mirror of
https://github.com/go-micro/go-micro.git
synced 2025-06-18 22:17:44 +02:00
[WIP] Micro Runtime (#947)
* Add Get() and GetOptions. * Removed watcher. Outline of client. YAML templates * Added default service and deployment templates and types * Added API tests and cleaned up errors. * Small refactoring. Template package is no more. * Ripped out existing code in preparation to small rework * Reshuffled the source code to make it organized better * Create service and deployment in kubernetes runtime * Major cleanup and refactoring of Kubernetes runtime * Service now handles low level K8s API calls across both K8s deployment an service API objects * Runtime has a task queue that serves for queueing runtime action requests * General refactoring * No need for Lock in k8s service * Added kubernetes runtime env var to default deployment * Enable running different versions of the same service * Can't delete services through labels * Proto cruft. Added runtime.CreateOptions implementation in proto * Removed proxy service from default env variables * Make service name mandatory param to Get method * Get Delete changes from https://github.com/micro/go-micro/pull/945 * Replaced template files with global variables * Validate service names before sending K8s API request * Refactored Kubernetes API client. Fixed typos. * Added client.Resource to make API resources more explicit in code
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
@ -13,6 +14,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// path to kubernetes service account token
|
||||
serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount"
|
||||
// ErrReadNamespace is returned when the names could not be read from service account
|
||||
ErrReadNamespace = errors.New("Could not read namespace from service account secret")
|
||||
@ -23,9 +25,7 @@ type client struct {
|
||||
opts *api.Options
|
||||
}
|
||||
|
||||
// NewClientInCluster should work similarily to the official api
|
||||
// NewInClient by setting up a client configuration for use within
|
||||
// a k8s pod.
|
||||
// NewClientInCluster creates a Kubernetes client for use from within a k8s pod.
|
||||
func NewClientInCluster() *client {
|
||||
host := "https://" + os.Getenv("KUBERNETES_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_SERVICE_PORT")
|
||||
|
||||
@ -34,7 +34,7 @@ func NewClientInCluster() *client {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if s == nil || !s.IsDir() {
|
||||
log.Fatal(errors.New("no k8s service account found"))
|
||||
log.Fatal(errors.New("service account not found"))
|
||||
}
|
||||
|
||||
token, err := ioutil.ReadFile(path.Join(serviceAccountPath, "token"))
|
||||
@ -90,26 +90,72 @@ func detectNamespace() (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateDeployment patches kubernetes deployment with metadata provided in body
|
||||
func (c *client) UpdateDeployment(name string, body interface{}) error {
|
||||
// Create creates new API object
|
||||
func (c *client) Create(r *Resource) error {
|
||||
b := new(bytes.Buffer)
|
||||
if err := renderTemplate(r.Kind, b, r.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return api.NewRequest(c.opts).
|
||||
Patch().
|
||||
Resource("deployments").
|
||||
Name(name).
|
||||
Body(body).
|
||||
Post().
|
||||
SetHeader("Content-Type", "application/yaml").
|
||||
Resource(r.Kind).
|
||||
Body(b).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// ListDeployments lists all kubernetes deployments with given labels
|
||||
func (c *client) ListDeployments(labels map[string]string) (*DeploymentList, error) {
|
||||
var deployments DeploymentList
|
||||
err := api.NewRequest(c.opts).
|
||||
// Get queries API objects and stores the result in r
|
||||
func (c *client) Get(r *Resource, labels map[string]string) error {
|
||||
return api.NewRequest(c.opts).
|
||||
Get().
|
||||
Resource("deployments").
|
||||
Resource(r.Kind).
|
||||
Params(&api.Params{LabelSelector: labels}).
|
||||
Do().
|
||||
Into(&deployments)
|
||||
|
||||
return &deployments, err
|
||||
Into(r.Value)
|
||||
}
|
||||
|
||||
// Update updates API object
|
||||
func (c *client) Update(r *Resource) error {
|
||||
req := api.NewRequest(c.opts).
|
||||
Patch().
|
||||
SetHeader("Content-Type", "application/strategic-merge-patch+json").
|
||||
Resource(r.Kind).
|
||||
Name(r.Name)
|
||||
|
||||
switch r.Kind {
|
||||
case "service":
|
||||
req.Body(r.Value.(*Service).Spec)
|
||||
case "deployment":
|
||||
req.Body(r.Value.(*Deployment).Spec)
|
||||
default:
|
||||
return errors.New("unsupported resource")
|
||||
}
|
||||
|
||||
return req.Do().Error()
|
||||
}
|
||||
|
||||
// Delete removes API object
|
||||
func (c *client) Delete(r *Resource) error {
|
||||
return api.NewRequest(c.opts).
|
||||
Delete().
|
||||
Resource(r.Kind).
|
||||
Name(r.Name).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// List lists API objects and stores the result in r
|
||||
func (c *client) List(r *Resource) error {
|
||||
labels := map[string]string{
|
||||
"micro": "service",
|
||||
}
|
||||
|
||||
return api.NewRequest(c.opts).
|
||||
Get().
|
||||
Resource(r.Kind).
|
||||
Params(&api.Params{LabelSelector: labels}).
|
||||
Do().
|
||||
Into(r.Value)
|
||||
}
|
||||
|
Reference in New Issue
Block a user