github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edgemesh/pkg/plugin/registry/registry.go (about)

     1  package registry
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/go-chassis/go-chassis/core/registry"
     9  	"github.com/go-chassis/go-chassis/pkg/util/tags"
    10  	v1 "k8s.io/api/core/v1"
    11  	"k8s.io/klog"
    12  
    13  	"github.com/kubeedge/kubeedge/edge/pkg/metamanager/client"
    14  	"github.com/kubeedge/kubeedge/edgemesh/pkg/cache"
    15  	"github.com/kubeedge/kubeedge/edgemesh/pkg/common"
    16  )
    17  
    18  const (
    19  	// EdgeRegistry constant string
    20  	EdgeRegistry = "edge"
    21  )
    22  
    23  // TODO Remove the init method, because it will cause invalid logs to be printed when the program is running @kadisi
    24  // init initialize the plugin of edge meta registry
    25  func init() { registry.InstallServiceDiscovery(EdgeRegistry, NewEdgeServiceDiscovery) }
    26  
    27  // EdgeServiceDiscovery to represent the object of service center to call the APIs of service center
    28  type EdgeServiceDiscovery struct {
    29  	metaClient client.CoreInterface
    30  	Name       string
    31  }
    32  
    33  func NewEdgeServiceDiscovery(options registry.Options) registry.ServiceDiscovery {
    34  	return &EdgeServiceDiscovery{
    35  		metaClient: client.New(),
    36  		Name:       EdgeRegistry,
    37  	}
    38  }
    39  
    40  // GetAllMicroServices Get all MicroService information.
    41  func (esd *EdgeServiceDiscovery) GetAllMicroServices() ([]*registry.MicroService, error) {
    42  	return nil, nil
    43  }
    44  
    45  // FindMicroServiceInstances find micro-service instances (subnets)
    46  func (esd *EdgeServiceDiscovery) FindMicroServiceInstances(consumerID, microServiceName string, tags utiltags.Tags) ([]*registry.MicroServiceInstance, error) {
    47  	// parse microServiceName
    48  	name, namespace, port, err := parseServiceUrl(microServiceName)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	// get service
    53  	service, err := esd.getService(name, namespace)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	// get pods
    58  	pods, err := esd.getPods(name, namespace)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	// get targetPort
    63  	var targetPort int
    64  	for _, p := range service.Spec.Ports {
    65  		if p.Protocol == "TCP" && int(p.Port) == port {
    66  			targetPort = p.TargetPort.IntValue()
    67  			break
    68  		}
    69  	}
    70  	// port not found
    71  	if targetPort == 0 {
    72  		klog.Errorf("[EdgeMesh] port %d not found in svc: %s.%s", port, namespace, name)
    73  		return nil, fmt.Errorf("port %d not found in svc: %s.%s", port, namespace, name)
    74  	}
    75  
    76  	// gen
    77  	var microServiceInstances []*registry.MicroServiceInstance
    78  	var hostPort int32
    79  	// all pods share the same hostport, get from pods[0]
    80  	if pods[0].Spec.HostNetwork {
    81  		// host network
    82  		hostPort = int32(targetPort)
    83  	} else {
    84  		// container network
    85  		for _, container := range pods[0].Spec.Containers {
    86  			for _, port := range container.Ports {
    87  				if port.ContainerPort == int32(targetPort) {
    88  					hostPort = port.HostPort
    89  				}
    90  			}
    91  		}
    92  	}
    93  	for _, p := range pods {
    94  		if p.Status.Phase == v1.PodRunning {
    95  			microServiceInstances = append(microServiceInstances, &registry.MicroServiceInstance{
    96  				InstanceID:   "",
    97  				ServiceID:    name + "." + namespace,
    98  				HostName:     "",
    99  				EndpointsMap: map[string]string{"rest": fmt.Sprintf("%s:%d", p.Status.HostIP, hostPort)},
   100  			})
   101  		}
   102  	}
   103  
   104  	return microServiceInstances, nil
   105  }
   106  
   107  // GetMicroServiceID get microServiceID
   108  func (esd *EdgeServiceDiscovery) GetMicroServiceID(appID, microServiceName, version, env string) (string, error) {
   109  	return "", nil
   110  }
   111  
   112  // GetMicroServiceInstances return instances
   113  func (esd *EdgeServiceDiscovery) GetMicroServiceInstances(consumerID, providerID string) ([]*registry.MicroServiceInstance, error) {
   114  	return nil, nil
   115  }
   116  
   117  // GetMicroService return service
   118  func (esd *EdgeServiceDiscovery) GetMicroService(microServiceID string) (*registry.MicroService, error) {
   119  	return nil, nil
   120  }
   121  
   122  // AutoSync updating the cache manager
   123  func (esd *EdgeServiceDiscovery) AutoSync() {}
   124  
   125  // Close close all websocket connection
   126  func (esd *EdgeServiceDiscovery) Close() error { return nil }
   127  
   128  // parseServiceUrl parses serviceUrl to ${service_name}.${namespace}.svc.${cluster}:${port}, keeps with k8s service
   129  func parseServiceUrl(serviceUrl string) (name, namespace string, port int, err error) {
   130  	name, namespace = common.SplitServiceKey(serviceUrl)
   131  	serviceUrlSplit := strings.Split(serviceUrl, ":")
   132  	if len(serviceUrlSplit) == 1 {
   133  		// default
   134  		port = 80
   135  	} else if len(serviceUrlSplit) == 2 {
   136  		port, err = strconv.Atoi(serviceUrlSplit[1])
   137  		if err != nil {
   138  			klog.Errorf("[EdgeMesh] service url %s invalid", serviceUrl)
   139  			return
   140  		}
   141  	} else {
   142  		klog.Errorf("[EdgeMesh] service url %s invalid", serviceUrl)
   143  		err = fmt.Errorf("service url %s invalid", serviceUrl)
   144  	}
   145  	return
   146  }
   147  
   148  // getService get k8s service from either lruCache or metaManager
   149  func (esd *EdgeServiceDiscovery) getService(name, namespace string) (*v1.Service, error) {
   150  	var svc *v1.Service
   151  	key := fmt.Sprintf("service.%s.%s", namespace, name)
   152  	// try to get from cache
   153  	v, ok := cache.GetMeshCache().Get(key)
   154  	if ok {
   155  		svc, ok = v.(*v1.Service)
   156  		if !ok {
   157  			klog.Errorf("[EdgeMesh] service %s from cache with invalid type", key)
   158  			return nil, fmt.Errorf("service %s from cache with invalid type", key)
   159  		}
   160  		klog.Infof("[EdgeMesh] get service %s from cache", key)
   161  	} else {
   162  		// get from metaClient
   163  		var err error
   164  		svc, err = esd.metaClient.Services(namespace).Get(name)
   165  		if err != nil {
   166  			klog.Errorf("[EdgeMesh] get service from metaClient failed, error: %v", err)
   167  			return nil, err
   168  		}
   169  		cache.GetMeshCache().Add(key, svc)
   170  		klog.Infof("[EdgeMesh] get service %s from metaClient", key)
   171  	}
   172  	return svc, nil
   173  }
   174  
   175  // getPods get service pods from either lruCache or metaManager
   176  func (esd *EdgeServiceDiscovery) getPods(name, namespace string) ([]v1.Pod, error) {
   177  	var pods []v1.Pod
   178  	key := fmt.Sprintf("pods.%s.%s", namespace, name)
   179  	// try to get from cache
   180  	v, ok := cache.GetMeshCache().Get(key)
   181  	if ok {
   182  		pods, ok = v.([]v1.Pod)
   183  		if !ok {
   184  			klog.Errorf("[EdgeMesh] pods %s from cache with invalid type", key)
   185  			return nil, fmt.Errorf("pods %s from cache with invalid type", key)
   186  		}
   187  		klog.Infof("[EdgeMesh] get pods %s from cache", key)
   188  	} else {
   189  		// get from metaClient
   190  		var err error
   191  		pods, err = esd.metaClient.Services(namespace).GetPods(name)
   192  		if err != nil {
   193  			klog.Errorf("[EdgeMesh] get pods from metaClient failed, error: %v", err)
   194  			return nil, err
   195  		}
   196  		if len(pods) == 0 {
   197  			klog.Errorf("[EdgeMesh] pod list %s is empty", key)
   198  			return nil, fmt.Errorf("pod list %s is empty", key)
   199  		}
   200  		cache.GetMeshCache().Add(key, pods)
   201  		klog.Infof("[EdgeMesh] get pods %s from metaClient", key)
   202  	}
   203  	return pods, nil
   204  }