go-micro/api

Kubernetes Integration

agus7fauzi opened this issue · 6 comments

how to use this api gateway with kubernetes registry? thanks

asim commented

Look at how the CLI integrates plugins and do the same. Effectively fork/PR the importing of the plugin and potentially setting via flag or env var.

now I can integrate it, but for now the problem is the api gateway checks service.Endpoint.Metadata to determine whether the route exists or not. because all existing services have empty service.Endpoint.Metadata so the api gateway responds to no route. I don't know which one to adjust the api gateway code or the go micro service configuration to.
API Gateway code checking Metadata:

`// store local endpoint cache
func (r *registryRouter) store(services []*registry.Service) {
// endpoints
eps := map[string]*router.Route{}

// services
names := map[string]bool{}

// create a new endpoint mapping
for _, service := range services {
	// set names we need later
	names[service.Name] = true

	// map per endpoint
	for _, sep := range service.Endpoints {
		// create a key service:endpoint_name
		key := fmt.Sprintf("%s.%s", service.Name, sep.Name)

		// decode endpoint
		end := router.Decode(sep.Metadata)

		// if we got nothing skip
		if err := router.Validate(end); err != nil {
			if logger.V(logger.TraceLevel, logger.DefaultLogger) {
				logger.Tracef("endpoint validation failed: %v", err)
			}
			continue
		}

		// try get endpoint
		ep, ok := eps[key]
		if !ok {
			ep = &router.Route{Service: service.Name}
		}

		// overwrite the endpoint
		ep.Endpoint = end
		// append services
		ep.Versions = append(ep.Versions, service)
		// store it
		eps[key] = ep
	}
}

r.Lock()
defer r.Unlock()

// delete any existing eps for services we know
for key, route := range r.eps {
	// skip what we don't care about
	if !names[route.Service] {
		continue
	}

	// ok we know this thing
	// delete delete delete
	delete(r.eps, key)
}

// now set the eps we have
for name, ep := range eps {
	r.eps[name] = ep
	cep := &endpoint{}

	for _, h := range ep.Endpoint.Host {
		if h == "" || h == "*" {
			continue
		}
		hostreg, err := regexp.CompilePOSIX(h)
		if err != nil {
			if logger.V(logger.TraceLevel, logger.DefaultLogger) {
				logger.Tracef("endpoint have invalid host regexp: %v", err)
			}
			continue
		}
		cep.hostregs = append(cep.hostregs, hostreg)
	}

	for _, p := range ep.Endpoint.Path {
		var pcreok bool

		if p[0] == '^' && p[len(p)-1] == '$' {
			pcrereg, err := regexp.CompilePOSIX(p)
			if err == nil {
				cep.pcreregs = append(cep.pcreregs, pcrereg)
				pcreok = true
			}
		}

		rule, err := util.Parse(p)
		if err != nil && !pcreok {
			if logger.V(logger.TraceLevel, logger.DefaultLogger) {
				logger.Tracef("endpoint have invalid path pattern: %v", err)
			}
			continue
		} else if err != nil && pcreok {
			continue
		}

		tpl := rule.Compile()
		pathreg, err := util.NewPattern(tpl.Version, tpl.OpCodes, tpl.Pool, "")
		if err != nil {
			if logger.V(logger.TraceLevel, logger.DefaultLogger) {
				logger.Tracef("endpoint have invalid path pattern: %v", err)
			}
			continue
		}
		cep.pathregs = append(cep.pathregs, pathreg)
	}

	r.ceps[name] = cep
}

}`

asim commented

Just copy/replace the router with a new one called kubernetes and strip that info. It's going to be easier than trying to hack at it.

may I know the code in which repo and which file?

ok thanks, i will try again