Svc metadata (#972)
* Added service metadata * Added metadata to runtime service * Add Annotations metadata to service metadata * Add micro/micro as default service owners * Update runtime/kubernetes/client/kubernetes.go Change comment Co-Authored-By: Jake Sanders <i@am.so-aweso.me>
This commit is contained in:
@@ -152,10 +152,5 @@ func (c *client) List(r *Resource) error {
|
||||
"micro": "service",
|
||||
}
|
||||
|
||||
return api.NewRequest(c.opts).
|
||||
Get().
|
||||
Resource(r.Kind).
|
||||
Params(&api.Params{LabelSelector: labels}).
|
||||
Do().
|
||||
Into(r.Value)
|
||||
return c.Get(r, labels)
|
||||
}
|
||||
|
@@ -50,7 +50,6 @@ func DefaultService(name, version string) *Service {
|
||||
if len(version) > 0 {
|
||||
// API service object name joins name and version over "-"
|
||||
svcName = strings.Join([]string{name, version}, "-")
|
||||
|
||||
}
|
||||
|
||||
Metadata := &Metadata{
|
||||
@@ -84,26 +83,32 @@ func DefaultDeployment(name, version, source string) *Deployment {
|
||||
"micro": "service",
|
||||
}
|
||||
|
||||
// API deployment object name joins name and version over "="
|
||||
depName := strings.Join([]string{name, version}, "-")
|
||||
depName := name
|
||||
if len(version) > 0 {
|
||||
// API deployment object name joins name and version over "-"
|
||||
depName = strings.Join([]string{name, version}, "-")
|
||||
}
|
||||
|
||||
Metadata := &Metadata{
|
||||
Name: depName,
|
||||
Namespace: "default",
|
||||
Version: version,
|
||||
Labels: Labels,
|
||||
Annotations: map[string]string{
|
||||
"source": source,
|
||||
"owner": "micro",
|
||||
"group": "micro",
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: we need to figure out this version stuff
|
||||
// might be worth adding Build to runtime.Service
|
||||
// might have to add Build to runtime.Service
|
||||
buildTime, err := strconv.ParseInt(version, 10, 64)
|
||||
if err == nil {
|
||||
buildUnixTimeUTC := time.Unix(buildTime, 0)
|
||||
Metadata.Annotations = map[string]string{
|
||||
"build": buildUnixTimeUTC.Format(time.RFC3339),
|
||||
}
|
||||
Metadata.Annotations["build"] = buildUnixTimeUTC.Format(time.RFC3339)
|
||||
} else {
|
||||
log.Debugf("Runtime could not parse build: %v", err)
|
||||
log.Debugf("could not parse build: %v", err)
|
||||
}
|
||||
|
||||
// enable go modules by default
|
||||
|
@@ -17,6 +17,12 @@ metadata:
|
||||
{{ $key }}: "{{ $value }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- with .Metadata.Annotations }}
|
||||
{{- range $key, $value := . }}
|
||||
{{ $key }}: "{{ $value }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Spec.Replicas }}
|
||||
selector:
|
||||
|
@@ -103,13 +103,21 @@ type DeploymentSpec struct {
|
||||
Template *Template `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentCondition describes the state of deployment
|
||||
type DeploymentCondition struct {
|
||||
Type string `json:"type"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentStatus is returned when querying deployment
|
||||
type DeploymentStatus struct {
|
||||
Replicas int `json:"replicas,omitempty"`
|
||||
UpdatedReplicas int `json:"updatedReplicas,omitempty"`
|
||||
ReadyReplicas int `json:"readyReplicas,omitempty"`
|
||||
AvailableReplicas int `json:"availableReplicas,omitempty"`
|
||||
UnavailableReplicas int `json:"unavailableReplicas,omitempty"`
|
||||
Replicas int `json:"replicas,omitempty"`
|
||||
UpdatedReplicas int `json:"updatedReplicas,omitempty"`
|
||||
ReadyReplicas int `json:"readyReplicas,omitempty"`
|
||||
AvailableReplicas int `json:"availableReplicas,omitempty"`
|
||||
UnavailableReplicas int `json:"unavailableReplicas,omitempty"`
|
||||
Conditions []DeploymentCondition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// Deployment is Kubernetes deployment
|
||||
|
@@ -109,6 +109,90 @@ func (k *kubernetes) Create(s *runtime.Service, opts ...runtime.CreateOption) er
|
||||
return nil
|
||||
}
|
||||
|
||||
// getMicroService queries kubernetes for micro service
|
||||
// NOTE: this function is not thread-safe
|
||||
func (k *kubernetes) getMicroService(labels map[string]string) ([]*runtime.Service, error) {
|
||||
// get the service status
|
||||
serviceList := new(client.ServiceList)
|
||||
r := &client.Resource{
|
||||
Kind: "service",
|
||||
Value: serviceList,
|
||||
}
|
||||
if err := k.client.Get(r, labels); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// get the deployment status
|
||||
depList := new(client.DeploymentList)
|
||||
d := &client.Resource{
|
||||
Kind: "deployment",
|
||||
Value: depList,
|
||||
}
|
||||
if err := k.client.Get(d, labels); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// service map
|
||||
svcMap := make(map[string]*runtime.Service)
|
||||
|
||||
// collect info from kubernetes service
|
||||
for _, kservice := range serviceList.Items {
|
||||
name := kservice.Metadata.Labels["name"]
|
||||
version := kservice.Metadata.Labels["version"]
|
||||
svcMap[name] = &runtime.Service{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Metadata: make(map[string]string),
|
||||
}
|
||||
// copy annotations metadata into service metadata
|
||||
for k, v := range kservice.Metadata.Annotations {
|
||||
svcMap[name].Metadata[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// collect additional info from kubernetes deployment
|
||||
for _, kdep := range depList.Items {
|
||||
name := kdep.Metadata.Labels["name"]
|
||||
if svc, ok := svcMap[name]; ok {
|
||||
// set the service source
|
||||
svc.Source = kdep.Metadata.Annotations["source"]
|
||||
// copy all annotations metadata into service metadata
|
||||
for k, v := range kdep.Metadata.Annotations {
|
||||
svc.Metadata[k] = v
|
||||
}
|
||||
|
||||
// parse out deployment status
|
||||
if len(kdep.Status.Conditions) > 0 {
|
||||
status := kdep.Status.Conditions[0].Type
|
||||
// pick the last known condition type and mark the service status with it
|
||||
log.Debugf("Runtime setting %s service deployment status: %v", name, status)
|
||||
svc.Metadata["status"] = status
|
||||
}
|
||||
|
||||
// parse out deployment build
|
||||
if build, ok := kdep.Metadata.Annotations["build"]; ok {
|
||||
buildTime, err := time.Parse(time.RFC3339, build)
|
||||
if err != nil {
|
||||
log.Debugf("Runtime failed parsing build time for %s: %v", name, err)
|
||||
continue
|
||||
}
|
||||
svc.Metadata["build"] = fmt.Sprintf("%d", buildTime.Unix())
|
||||
continue
|
||||
}
|
||||
// if no build annotation is found, set it to current time
|
||||
svc.Metadata["build"] = fmt.Sprintf("%d", time.Now().Unix())
|
||||
}
|
||||
}
|
||||
|
||||
// collect all the services and return
|
||||
services := make([]*runtime.Service, 0, len(serviceList.Items))
|
||||
for _, service := range svcMap {
|
||||
services = append(services, service)
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
// Get returns all instances of given service
|
||||
func (k *kubernetes) Get(name string, opts ...runtime.GetOption) ([]*runtime.Service, error) {
|
||||
k.Lock()
|
||||
@@ -119,11 +203,12 @@ func (k *kubernetes) Get(name string, opts ...runtime.GetOption) ([]*runtime.Ser
|
||||
return nil, errors.New("missing service name")
|
||||
}
|
||||
|
||||
// set the default label
|
||||
// set the default labels
|
||||
labels := map[string]string{
|
||||
"micro": "service",
|
||||
"name": name,
|
||||
}
|
||||
|
||||
var options runtime.GetOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
@@ -136,25 +221,21 @@ func (k *kubernetes) Get(name string, opts ...runtime.GetOption) ([]*runtime.Ser
|
||||
|
||||
log.Debugf("Runtime querying service %s", name)
|
||||
|
||||
serviceList := new(client.ServiceList)
|
||||
r := &client.Resource{
|
||||
Kind: "service",
|
||||
Value: serviceList,
|
||||
}
|
||||
if err := k.client.Get(r, labels); err != nil {
|
||||
return nil, err
|
||||
return k.getMicroService(labels)
|
||||
}
|
||||
|
||||
// List the managed services
|
||||
func (k *kubernetes) List() ([]*runtime.Service, error) {
|
||||
k.Lock()
|
||||
defer k.Unlock()
|
||||
|
||||
labels := map[string]string{
|
||||
"micro": "service",
|
||||
}
|
||||
|
||||
services := make([]*runtime.Service, 0, len(serviceList.Items))
|
||||
for _, kservice := range serviceList.Items {
|
||||
service := &runtime.Service{
|
||||
Name: kservice.Metadata.Name,
|
||||
Version: kservice.Metadata.Version,
|
||||
}
|
||||
services = append(services, service)
|
||||
}
|
||||
log.Debugf("Runtime listing all micro services")
|
||||
|
||||
return services, nil
|
||||
return k.getMicroService(labels)
|
||||
}
|
||||
|
||||
// Update the service in place
|
||||
@@ -202,39 +283,6 @@ func (k *kubernetes) Delete(s *runtime.Service) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// List the managed services
|
||||
func (k *kubernetes) List() ([]*runtime.Service, error) {
|
||||
serviceList := new(client.ServiceList)
|
||||
r := &client.Resource{
|
||||
Kind: "service",
|
||||
Value: serviceList,
|
||||
}
|
||||
|
||||
if err := k.client.List(r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("Runtime found %d micro services", len(serviceList.Items))
|
||||
|
||||
services := make([]*runtime.Service, 0, len(serviceList.Items))
|
||||
|
||||
for _, service := range serviceList.Items {
|
||||
buildTime, err := time.Parse(time.RFC3339, service.Metadata.Annotations["build"])
|
||||
if err != nil {
|
||||
log.Debugf("Runtime error parsing build time for %s: %v", service.Metadata.Name, err)
|
||||
continue
|
||||
}
|
||||
// add the service to the list of services
|
||||
svc := &runtime.Service{
|
||||
Name: service.Metadata.Name,
|
||||
Version: fmt.Sprintf("%d", buildTime.Unix()),
|
||||
}
|
||||
services = append(services, svc)
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
// run runs the runtime management loop
|
||||
func (k *kubernetes) run(events <-chan runtime.Event) {
|
||||
t := time.NewTicker(time.Second * 10)
|
||||
|
Reference in New Issue
Block a user