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, ®istry.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 }