func localID(namespace, service string) string {
	return fmt.Sprintf("%s.%s", service, namespace)
}
unique id within a context
package main
import (
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"github.com/sirupsen/logrus"
	"gopkg.in/yaml.v2"
)
const (
	defaultCIDR = "127.0.11.0/24"
)
type config struct {
	CIDR string `yaml:"cidr"`
	Contexts []struct {
		Name       string `yaml:"name"`  
		Namespaces []struct {
			Name     string `yaml:"name"`
			Services []struct {
				Name    string   `yaml:"name"`
				Aliases []string `yaml:"aliases"`
			} `yaml:"services"`
		} `yaml:"namespaces"`
	} `yaml:"contexts"`
}
func readConfig(log *logrus.Logger, configPath string) (string, []*target, error) {
	expanded := os.ExpandEnv(configPath)
	log.Infof("using config at: %s", expanded)
	raw, err := ioutil.ReadFile(expanded)
	if err != nil {
		return "", nil, err
	}
	var cfg config
	if err := yaml.Unmarshal(raw, &cfg); err != nil {
		return "", nil, err
	}
	if cfg.CIDR == "" {
		cfg.CIDR = defaultCIDR
	}
	var targets []*target
	for _, c := range cfg.Contexts {
		for _, ns := range c.Namespaces {
			for _, svc := range ns.Services {
				targets = append(targets, &target{
					context:   c.Name,
					namespace: ns.Name,
					service:   svc.Name,
					aliases:   svc.Aliases,
					ports:     map[string]string{},
				})
			}
		}
	}
	return cfg.CIDR, targets, nil
}
func generateIPs(cidr string, n int) ([]string, error) {
	cur, ipNet, err := net.ParseCIDR(cidr)
	if err != nil {
		return nil, err
	}
	var ips []string
	for i := 0; i < n; i++ {
		for i := len(cur) - 1; i >= 0; i-- {
			cur[i]++
			if cur[i] != 0 {
				break
			}
		}
		if !ipNet.Contains(cur) {
			return nil, fmt.Errorf("CIDR overflow (%v allocated)", i)
		}
		ips = append(ips, cur.String())
	}
	return ips, nil
}
type target struct {
	context   string    
	namespace string    
	service   string    
	aliases   []string  
	addr     string             
	ports    map[string]string  
	conflict bool               
}
func (t target) local() string {
	return localID(t.namespace, t.service)
}
func (t target) global() string {
	return globalID(t.context, t.namespace, t.service)
}