示例#1
0
// requestAddress
func requestAddress() func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		var (
			content []byte
			err     error
			areq    = api.RequestAddressRequest{}
			decoder = json.NewDecoder(r.Body)
		)

		logEvent("requestAddress")

		// Decode the JSON message
		err = decoder.Decode(&areq)
		if err != nil {
			httpError(w, "Could not read and parse requestAddress request", err)
			return
		}

		log.Infof("Received RequestAddressRequest: %+v", areq)

		// Build an alloc request to be sent to master
		allocReq := master.AddressAllocRequest{
			NetworkID:            areq.PoolID,
			PreferredIPv4Address: areq.Address,
		}

		subnetLen := strings.Split(areq.PoolID, "/")[1]

		var addr string
		if areq.Address != "" {
			addr = areq.Address + "/" + subnetLen
		} else {
			// Make a REST call to master
			var allocResp master.AddressAllocResponse
			err = cluster.MasterPostReq("/plugin/allocAddress", &allocReq, &allocResp)
			if err != nil {
				httpError(w, "master failed to allocate address", err)
				return
			}

			addr = allocResp.IPv4Address
		}

		// build response
		aresp := api.RequestAddressResponse{
			Address: addr,
		}

		log.Infof("Sending RequestAddressResponse: %+v", aresp)

		// build json
		content, err = json.Marshal(aresp)
		if err != nil {
			httpError(w, "Could not generate requestAddress response", err)
			return
		}

		w.Write(content)
	}
}
示例#2
0
// createEP creates the specified EP in contiv
func createEP(req *epSpec) (*epAttr, error) {

	// if the ep already exists, treat as error for now.
	netID := req.Network + "." + req.Tenant
	ep, err := netdGetEndpoint(netID + "-" + req.EndpointID)
	if err == nil {
		return nil, fmt.Errorf("EP %s already exists", req.EndpointID)
	}

	// Build endpoint request
	mreq := master.CreateEndpointRequest{
		TenantName:   req.Tenant,
		NetworkName:  req.Network,
		ServiceName:  req.Group,
		EndpointID:   req.EndpointID,
		EPCommonName: req.Name,
		ConfigEP: intent.ConfigEP{
			Container:   req.EndpointID,
			Host:        pluginHost,
			ServiceName: req.Group,
		},
	}

	var mresp master.CreateEndpointResponse
	err = cluster.MasterPostReq("/plugin/createEndpoint", &mreq, &mresp)
	if err != nil {
		epCleanUp(req)
		return nil, err
	}

	log.Infof("Got endpoint create resp from master: %+v", mresp)

	// Ask netplugin to create the endpoint
	err = netPlugin.CreateEndpoint(netID + "-" + req.EndpointID)
	if err != nil {
		log.Errorf("Endpoint creation failed. Error: %s", err)
		epCleanUp(req)
		return nil, err
	}

	ep, err = netdGetEndpoint(netID + "-" + req.EndpointID)
	if err != nil {
		epCleanUp(req)
		return nil, err
	}

	log.Debug(ep)
	// need to get the subnetlen from nw state.
	nw, err := netdGetNetwork(netID)
	if err != nil {
		return nil, err
	}

	epResponse := epAttr{}
	epResponse.PortName = ep.PortName
	epResponse.IPAddress = ep.IPAddress + "/" + strconv.Itoa(int(nw.SubnetLen))
	epResponse.Gateway = nw.Gateway

	return &epResponse, nil
}
示例#3
0
// deleteEndpoint deletes an endpoint using netplugin api
func (its *integTestSuite) deleteEndpoint(tenantName, netName, epgName string, epCfg *mastercfg.CfgEndpointState) error {
	// Build endpoint delete request
	delreq := master.DeleteEndpointRequest{
		TenantName:  tenantName,
		NetworkName: netName,
		ServiceName: epgName,
		EndpointID:  epCfg.EndpointID,
	}

	var delResp master.DeleteEndpointResponse
	err := cluster.MasterPostReq("/plugin/deleteEndpoint", &delreq, &delResp)
	if err != nil {
		log.Errorf("master failed to delete endpoint. Err: %v", err)
		return err
	}

	// delete the endpoint
	err = its.npcluster.PluginAgent.Plugin().DeleteEndpoint(epCfg.ID)
	if err != nil {
		log.Errorf("Error deleting endpoint %s. Err: %v", epCfg.ID, err)
		return err
	}

	return nil
}
示例#4
0
func (cniReq *cniServer) deleteMasterEndPoint() error {

	// delete from master
	delReq := master.DeleteEndpointRequest{
		TenantName:  cniReq.endPointLabels[cniapi.LabelTenantName],
		NetworkName: cniReq.endPointLabels[cniapi.LabelNetworkName],
		ServiceName: cniReq.endPointLabels[cniapi.LabelNetworkGroup],
		EndpointID:  cniReq.pluginArgs.CniContainerid,
	}

	delResp := master.DeleteEndpointResponse{}
	if err := cluster.MasterPostReq("/plugin/deleteEndpoint", &delReq, &delResp); err != nil {
		cniLog.Errorf("failed to delete endpoint %s from master %s ", cniReq.endpointID, err.Error())
		return err
	}
	return nil
}
示例#5
0
// Process Infra Nw Create
// Auto allocate an endpoint for this node
func processInfraNwCreate(netPlugin *plugin.NetPlugin, nwCfg *mastercfg.CfgNetworkState, opts cliOpts) (err error) {
	pluginHost := opts.hostLabel

	// Build endpoint request
	mreq := master.CreateEndpointRequest{
		TenantName:  nwCfg.Tenant,
		NetworkName: nwCfg.NetworkName,
		EndpointID:  pluginHost,
		ConfigEP: intent.ConfigEP{
			Container: pluginHost,
			Host:      pluginHost,
		},
	}

	var mresp master.CreateEndpointResponse
	err = cluster.MasterPostReq("/plugin/createEndpoint", &mreq, &mresp)
	if err != nil {
		log.Errorf("master failed to create endpoint %s", err)
		return err
	}

	log.Infof("Got endpoint create resp from master: %+v", mresp)

	// Take lock to ensure netPlugin processes only one cmd at a time
	netPlugin.Lock()
	defer func() { netPlugin.Unlock() }()

	// Ask netplugin to create the endpoint
	netID := nwCfg.NetworkName + "." + nwCfg.Tenant
	err = netPlugin.CreateEndpoint(netID + "-" + pluginHost)
	if err != nil {
		log.Errorf("Endpoint creation failed. Error: %s", err)
		return err
	}

	// Assign IP to interface
	ipCIDR := fmt.Sprintf("%s/%d", mresp.EndpointConfig.IPAddress, nwCfg.SubnetLen)
	err = netutils.SetInterfaceIP(nwCfg.NetworkName, ipCIDR)
	if err != nil {
		log.Errorf("Could not assign ip: %s", err)
		return err
	}

	return nil
}
示例#6
0
// allocAddress gets an address from the master
func (its *integTestSuite) allocAddress(addrPool, networkID, prefAddress string) (string, error) {
	// Build an alloc request to be sent to master
	allocReq := master.AddressAllocRequest{
		AddressPool:          addrPool,
		NetworkID:            networkID,
		PreferredIPv4Address: prefAddress,
	}

	// Make a REST call to master
	var allocResp master.AddressAllocResponse
	err := cluster.MasterPostReq("/plugin/allocAddress", &allocReq, &allocResp)
	if err != nil {
		log.Errorf("master failed to allocate address. Err: %v", err)
		return "", err
	}

	return strings.Split(allocResp.IPv4Address, "/")[0], nil
}
示例#7
0
// epCleanUp deletes the ep from netplugin and netmaster
func epCleanUp(req *epSpec) error {
	// first delete from netplugin
	// ignore any errors as this is best effort
	netID := req.Network + "." + req.Tenant
	err1 := netPlugin.DeleteEndpoint(netID + "-" + req.EndpointID)

	// now delete from master
	delReq := master.DeleteEndpointRequest{
		TenantName:  req.Tenant,
		NetworkName: req.Network,
		ServiceName: req.Group,
		EndpointID:  req.EndpointID,
	}

	var delResp master.DeleteEndpointResponse
	err2 := cluster.MasterPostReq("/plugin/deleteEndpoint", &delReq, &delResp)

	if err1 != nil {
		return err1
	}

	return err2
}
示例#8
0
// Process Infra Nw Delete
// Delete the auto allocated endpoint
func processInfraNwDelete(netPlugin *plugin.NetPlugin, nwCfg *mastercfg.CfgNetworkState, opts cliOpts) (err error) {
	pluginHost := opts.hostLabel

	// Build endpoint request
	mreq := master.DeleteEndpointRequest{
		TenantName:  nwCfg.Tenant,
		NetworkName: nwCfg.NetworkName,
		EndpointID:  pluginHost,
	}

	var mresp master.DeleteEndpointResponse
	err = cluster.MasterPostReq("/plugin/deleteEndpoint", &mreq, &mresp)
	if err != nil {
		log.Errorf("master failed to delete endpoint %s", err)
		return err
	}

	log.Infof("Got endpoint create resp from master: %+v", mresp)

	// Network delete will take care of infra nw EP delete in plugin

	return
}
示例#9
0
// createEndpoint creates an endpoint using netplugin api
func (its *integTestSuite) createEndpoint(tenantName, netName, epgName, v4Addr, v6Addr string) (*mastercfg.CfgEndpointState, error) {
	its.uniqEPID++
	epID := fmt.Sprintf("%s-%s-%s-%d", tenantName, netName, epgName, its.uniqEPID)
	// Build endpoint request
	mreq := master.CreateEndpointRequest{
		TenantName:  tenantName,
		NetworkName: netName,
		ServiceName: epgName,
		EndpointID:  epID,
		ConfigEP: intent.ConfigEP{
			Container:   epID,
			Host:        its.npcluster.HostLabel,
			IPAddress:   v4Addr,
			IPv6Address: v6Addr,
			ServiceName: epgName,
		},
	}

	var mresp master.CreateEndpointResponse
	err := cluster.MasterPostReq("/plugin/createEndpoint", &mreq, &mresp)
	if err != nil {
		log.Errorf("master failed to create endpoint. Err: %v", err)
		return nil, err
	}

	log.Infof("Got endpoint create resp from master: %+v", mresp)
	netID := netName + "." + tenantName

	// Ask netplugin to create the endpoint
	err = its.npcluster.PluginAgent.Plugin().CreateEndpoint(netID + "-" + epID)
	if err != nil {
		log.Errorf("Endpoint creation failed. Error: %s", err)
		return nil, err
	}

	return &mresp.EndpointConfig, nil
}
示例#10
0
/***
Copyright 2014 Cisco Systems Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package agent

import (
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/contiv/netplugin/mgmtfn/dockplugin"
	"github.com/contiv/netplugin/netmaster/master"
	"github.com/contiv/netplugin/netplugin/cluster"
	"github.com/docker/engine-api/client"
	"github.com/docker/engine-api/types"
	"github.com/samalba/dockerclient"
	"golang.org/x/net/context"
)

// Handles docker events monitored by dockerclient. Currently we only handle
// container start and die event*/
func handleDockerEvents(event *dockerclient.Event, ec chan error, args ...interface{}) {

	log.Debugf("Received Docker event: {%#v}\n", *event)
	endpointUpdReq := &master.UpdateEndpointRequest{}
	switch event.Status {
	case "start":
		defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
		cli, err := client.NewClient("unix:///var/run/docker.sock", "v1.21", nil, defaultHeaders)
		if err != nil {
			panic(err)
		}

		containerInfo, err := cli.ContainerInspect(context.Background(), event.ID)

		if err != nil {
			log.Errorf("Container Inspect failed :%s", err)
			return
		}

		if event.ID != "" {
			labelMap := getLabelsFromContainerInspect(&containerInfo)
			containerTenant := getTenantFromContainerInspect(&containerInfo)
			networkName, ipAddress, err := getEpNetworkInfoFromContainerInspect(&containerInfo)
			if err != nil {
				log.Errorf("Error getting container network info for %v.Err:%s", event.ID, err)
			}
			endpoint := getEndpointFromContainerInspect(&containerInfo)

			if ipAddress != "" {
				//Create provider info
				endpointUpdReq.IPAddress = ipAddress
				endpointUpdReq.ContainerID = event.ID
				endpointUpdReq.Tenant = containerTenant
				endpointUpdReq.Network = networkName
				endpointUpdReq.Event = "start"
				endpointUpdReq.EndpointID = endpoint
				endpointUpdReq.EPCommonName = containerInfo.Name
				endpointUpdReq.Labels = make(map[string]string)

				for k, v := range labelMap {
					endpointUpdReq.Labels[k] = v
				}
			}

			var epUpdResp master.UpdateEndpointResponse

			log.Infof("Sending Endpoint update request to master: {%+v}", endpointUpdReq)

			err = cluster.MasterPostReq("/plugin/updateEndpoint", endpointUpdReq, &epUpdResp)
			if err != nil {
				log.Errorf("Event: 'start' , Http error posting endpoint update, Error:%s", err)
			}
		} else {
			log.Errorf("Unable to fetch container labels for container %s ", event.ID)
		}
	case "die":
		endpointUpdReq.ContainerID = event.ID
		endpointUpdReq.Event = "die"
		var epUpdResp master.UpdateEndpointResponse
		log.Infof("Sending Endpoint update request to master: {%+v} on container delete", endpointUpdReq)
		err := cluster.MasterPostReq("/plugin/updateEndpoint", endpointUpdReq, &epUpdResp)
		if err != nil {
			log.Errorf("Event:'die' Http error posting endpoint update, Error:%s", err)
		}
	}
}
示例#11
0
// requestAddress
func requestAddress(w http.ResponseWriter, r *http.Request) {
	var (
		content []byte
		err     error
		areq    = api.RequestAddressRequest{}
		decoder = json.NewDecoder(r.Body)
	)

	logEvent("requestAddress")

	// Decode the JSON message
	err = decoder.Decode(&areq)
	if err != nil {
		httpError(w, "Could not read and parse requestAddress request", err)
		return
	}

	log.Infof("Received RequestAddressRequest: %+v", areq)

	networkID := ""
	addrPool := areq.PoolID
	subnetLen := strings.Split(areq.PoolID, "/")[1]

	// check if pool id contains address pool or network id
	// HACK alert: This is very fragile. Simplify this when we stop supporting docker 1.9
	if strings.Contains(areq.PoolID, "|") {
		addrPool = strings.Split(areq.PoolID, "|")[1]
		networkID = strings.Split(areq.PoolID, "|")[0]
	}

	// Build an alloc request to be sent to master
	allocReq := master.AddressAllocRequest{
		AddressPool:          addrPool,
		NetworkID:            networkID,
		PreferredIPv4Address: areq.Address,
	}

	var addr string

	// check if this request is for gateway
	reqType, ok := areq.Options["RequestAddressType"]
	if ok && reqType == netlabel.Gateway {
		if areq.Address != "" {
			addr = areq.Address + "/" + subnetLen
		} else {
			// simply return a dummy address
			addr = addrPool
		}
	} else if areq.Address != "" {
		// This is a special case for docker 1.9 gateway request which does not
		// come with 'RequestAddressType' label
		// FIXME: Remove this hack when we stop supporting docker 1.9
		addr = areq.Address + "/" + subnetLen
	} else {
		// Make a REST call to master
		var allocResp master.AddressAllocResponse
		err = cluster.MasterPostReq("/plugin/allocAddress", &allocReq, &allocResp)
		if err != nil {
			httpError(w, "master failed to allocate address", err)
			return
		}

		addr = allocResp.IPv4Address
	}

	// build response
	aresp := api.RequestAddressResponse{
		Address: addr,
	}

	log.Infof("Sending RequestAddressResponse: %+v", aresp)

	// build json
	content, err = json.Marshal(aresp)
	if err != nil {
		httpError(w, "Could not generate requestAddress response", err)
		return
	}

	w.Write(content)
}
示例#12
0
func createEndpoint(hostname string) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		logEvent("create endpoint")

		content, err := ioutil.ReadAll(r.Body)
		if err != nil {
			httpError(w, "Could not read endpoint create request", err)
			return
		}

		cereq := api.CreateEndpointRequest{}
		if err := json.Unmarshal(content, &cereq); err != nil {
			httpError(w, "Could not read endpoint create request", err)
			return
		}

		log.Infof("CreateEndpointRequest: %+v. Interface: %+v", cereq, cereq.Interface)

		tenantName, netName, serviceName, err := GetDockerNetworkName(cereq.NetworkID)
		if err != nil {
			log.Errorf("Error getting network name for UUID: %s. Err: %v", cereq.NetworkID, err)
			httpError(w, "Could not get network name", err)
			return
		}

		// Build endpoint request
		mreq := master.CreateEndpointRequest{
			TenantName:  tenantName,
			NetworkName: netName,
			ServiceName: serviceName,
			EndpointID:  cereq.EndpointID,
			ConfigEP: intent.ConfigEP{
				Container:   cereq.EndpointID,
				Host:        hostname,
				IPAddress:   strings.Split(cereq.Interface.Address, "/")[0],
				ServiceName: serviceName,
			},
		}

		var mresp master.CreateEndpointResponse
		err = cluster.MasterPostReq("/plugin/createEndpoint", &mreq, &mresp)
		if err != nil {
			httpError(w, "master failed to create endpoint", err)
			return
		}

		log.Infof("Got endpoint create resp from master: %+v", mresp)
		netID := netName + "." + tenantName

		// Ask netplugin to create the endpoint
		err = netPlugin.CreateEndpoint(netID + "-" + cereq.EndpointID)
		if err != nil {
			log.Errorf("Endpoint creation failed. Error: %s", err)
			httpError(w, "Could not create endpoint", err)
			return
		}

		ep, err := netdGetEndpoint(netID + "-" + cereq.EndpointID)
		if err != nil {
			httpError(w, "Could not find created endpoint", err)
			return
		}

		log.Debug(ep)

		epResponse := api.CreateEndpointResponse{
			Interface: &api.EndpointInterface{},
		}

		// Add the service information using Service plugin
		if serviceName != "" {
			log.Infof("Calling AddService with: ID: %s, Name: %s, Network: %s, Tenant: %s, IP: %s", cereq.EndpointID[len(cereq.EndpointID)-12:], serviceName, netName, tenantName, ep.IPAddress)
			dnsBridge.AddService(cereq.EndpointID[len(cereq.EndpointID)-12:], serviceName, netName, tenantName, ep.IPAddress)
		}

		log.Infof("Sending CreateEndpointResponse: {%+v}, IP Addr: %v", epResponse, ep.IPAddress)

		content, err = json.Marshal(epResponse)
		if err != nil {
			httpError(w, "Could not generate create endpoint response", err)
			return
		}

		w.Write(content)
	}
}
示例#13
0
func deleteEndpoint(hostname string) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		logEvent("delete endpoint")

		content, err := ioutil.ReadAll(r.Body)
		if err != nil {
			httpError(w, "Could not read delete endpoint request", err)
			return
		}

		der := api.DeleteEndpointRequest{}
		if err := json.Unmarshal(content, &der); err != nil {
			httpError(w, "Could not read delete endpoint request", err)
			return
		}

		log.Infof("Received DeleteEndpointRequest: %+v", der)

		tenantName, netName, serviceName, err := GetDockerNetworkName(der.NetworkID)
		if err != nil {
			log.Errorf("Error getting network name for UUID: %s. Err: %v", der.NetworkID, err)
			httpError(w, "Could not get network name", err)
			return
		}

		// Build endpoint delete request
		delreq := master.DeleteEndpointRequest{
			TenantName:  tenantName,
			NetworkName: netName,
			ServiceName: serviceName,
			EndpointID:  der.EndpointID,
		}

		var delResp master.DeleteEndpointResponse
		err = cluster.MasterPostReq("/plugin/deleteEndpoint", &delreq, &delResp)
		if err != nil {
			httpError(w, "master failed to delete endpoint", err)
			return
		}

		// delete the endpoint
		netID := netName + "." + tenantName
		err = netPlugin.DeleteEndpoint(netID + "-" + delreq.EndpointID)
		if err != nil {
			log.Errorf("Error deleting endpoint %s. Err: %v", delreq.EndpointID, err)
			httpError(w, "failed to delete endpoint", err)
			return
		}

		ep, err := netdGetEndpoint(netID + "-" + delreq.EndpointID)
		if err != nil {
			httpError(w, "Could not find endpoint", err)
			return
		}

		// Remove the DNS entry for the service
		if serviceName != "" {
			log.Infof("Calling RemoveService with: ID: %s, Name: %s, Network: %s, Tenant: %s, IP: %s", delreq.EndpointID[len(delreq.EndpointID)-12:], serviceName, netName, tenantName, ep.IPAddress)
			dnsBridge.RemoveService(delreq.EndpointID[len(delreq.EndpointID)-12:], serviceName, netName, tenantName, ep.IPAddress)
		}

		// build response
		content, err = json.Marshal(api.DeleteEndpointResponse{})
		if err != nil {
			httpError(w, "Could not generate delete endpoint response", err)
			return
		}

		w.Write(content)
	}
}
示例#14
0
/*Handles docker events monitored by dockerclient. Currently we only handle
  container start and die event*/
func handleDockerEvents(event *dockerclient.Event, ec chan error, args ...interface{}) {

	log.Printf("Received Docker event: {%#v}\n", *event)
	providerUpdReq := &master.SvcProvUpdateRequest{}
	switch event.Status {
	case "start":
		defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
		cli, err := client.NewClient("unix:///var/run/docker.sock", "v1.21", nil, defaultHeaders)
		if err != nil {
			panic(err)
		}
		containerInfo, err := cli.ContainerInspect(context.Background(), event.ID)
		if err != nil {
			log.Errorf("Container Inspect failed :%s", err)
			return
		}
		if event.ID != "" {
			labelMap := getLabelsFromContainerInspect(&containerInfo)

			containerTenant := getTenantFromContainerInspect(&containerInfo)
			network, ipAddress := getEpNetworkInfoFromContainerInspect(&containerInfo)
			container := getContainerFromContainerInspect(&containerInfo)
			if ipAddress != "" {
				//Create provider info
				networkname := strings.Split(network, "/")[0]
				providerUpdReq.IPAddress = ipAddress
				providerUpdReq.ContainerID = event.ID
				providerUpdReq.Tenant = containerTenant
				providerUpdReq.Network = networkname
				providerUpdReq.Event = "start"
				providerUpdReq.Container = container
				providerUpdReq.Labels = make(map[string]string)

				for k, v := range labelMap {
					providerUpdReq.Labels[k] = v
				}
			}
			if len(labelMap) == 0 {
				//Ignore container without labels
				return
			}
			var svcProvResp master.SvcProvUpdateResponse

			log.Infof("Sending Provider create request to master: {%+v}", providerUpdReq)

			err := cluster.MasterPostReq("/plugin/svcProviderUpdate", providerUpdReq, &svcProvResp)
			if err != nil {
				log.Errorf("Event: 'start' , Http error posting service provider update, Error:%s", err)
			}
		} else {
			log.Errorf("Unable to fetch container labels for container %s ", event.ID)
		}
	case "die":
		providerUpdReq.ContainerID = event.ID
		providerUpdReq.Event = "die"
		var svcProvResp master.SvcProvUpdateResponse
		log.Infof("Sending Provider delete request to master: {%+v}", providerUpdReq)
		err := cluster.MasterPostReq("/plugin/svcProviderUpdate", providerUpdReq, &svcProvResp)
		if err != nil {
			log.Errorf("Event:'die' Http error posting service provider update, Error:%s", err)
		}
	}
}
示例#15
0
func (cniReq *cniServer) createCniEndPoint() error {
	var err error
	ovsEpDriver := &drivers.OvsOperEndpointState{}
	ovsEpDriver.StateDriver = stateDriver

	nwState := &mastercfg.CfgNetworkState{}
	nwState.StateDriver = stateDriver

	// build endpoint request
	epReq := master.CreateEndpointRequest{
		TenantName:  cniReq.endPointLabels[cniapi.LabelTenantName],
		NetworkName: cniReq.endPointLabels[cniapi.LabelNetworkName],
		ServiceName: cniReq.endPointLabels[cniapi.LabelNetworkGroup],
		EndpointID:  cniReq.pluginArgs.CniContainerid,
		ConfigEP: intent.ConfigEP{
			Container:   cniReq.pluginArgs.CniContainerid,
			Host:        hostName,
			ServiceName: cniReq.endPointLabels[cniapi.LabelNetworkGroup],
		},
	}

	cniLog.Infof("endpoint-req: epid:%s cont-id:%s ", epReq.EndpointID, epReq.ConfigEP.Container)

	epResp := master.CreateEndpointResponse{}
	if err = cluster.MasterPostReq("/plugin/createEndpoint", &epReq, &epResp); err != nil {
		cniLog.Errorf("failed to create endpoint in master: %s", err.Error())
		return err
	}

	cniLog.Infof("endpoint created  %+v", epResp)

	// create endpoint in netplugin
	if err = netPlugin.CreateEndpoint(cniReq.endpointID); err != nil {
		cniLog.Errorf("failed to create endpoint in netplugin: %s", err.Error())
		goto cleanupMaster
	}

	// read end point
	if err = ovsEpDriver.Read(cniReq.endpointID); err != nil {
		cniLog.Errorf("failed to read endpoint: %s", err.Error())
		goto cleanupNetplugin
	}

	if err = nwState.Read(cniReq.networkID); err != nil {
		cniLog.Errorf("failed to read network config : %s", err.Error())
		goto cleanupNetplugin
	}

	cniLog.Debugf("read new network config +%v", nwState)

	if err = cniReq.configureNetNs(ovsEpDriver, &epResp, nwState); err != nil {
		goto cleanupNetplugin
	}

	// host access
	if strings.HasSuffix(cniReq.pluginArgs.CniIfname, "0") {
		if err = cniReq.createHostBrIntf(ovsEpDriver); err != nil {
			cniLog.Errorf("failed to configure host-br %s", err.Error())
			goto cleanupNetns
		}
	}

	return nil

	// unwind the setup, ignore errors
cleanupNetns:
	cniReq.unlinkNetNs()
cleanupNetplugin:
	cniReq.deleteNetpluginEndPoint()
cleanupMaster:
	cniReq.deleteMasterEndPoint()

	return err
}