2014-06-06 23:40:48 +00:00
|
|
|
/*
|
|
|
|
Copyright 2014 Google Inc. All rights reserved.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
2014-07-25 19:28:20 +00:00
|
|
|
"encoding/json"
|
2014-06-06 23:40:48 +00:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
2014-08-15 21:14:22 +00:00
|
|
|
"net/url"
|
2014-07-07 16:36:55 +00:00
|
|
|
"time"
|
2014-06-06 23:40:48 +00:00
|
|
|
|
|
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
2014-08-29 19:15:30 +00:00
|
|
|
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
|
2014-06-23 00:02:48 +00:00
|
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
2014-09-02 17:55:27 +00:00
|
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
2014-07-25 19:28:20 +00:00
|
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
|
2014-08-05 23:19:32 +00:00
|
|
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
2014-06-06 23:40:48 +00:00
|
|
|
)
|
|
|
|
|
2014-08-28 09:42:18 +00:00
|
|
|
// Interface holds the methods for clients of Kubernetes,
|
2014-07-10 23:51:34 +00:00
|
|
|
// an interface to allow mock testing.
|
2014-08-05 23:19:32 +00:00
|
|
|
// TODO: these should return/take pointers.
|
2014-07-10 23:51:34 +00:00
|
|
|
type Interface interface {
|
2014-08-21 21:14:06 +00:00
|
|
|
PodInterface
|
|
|
|
ReplicationControllerInterface
|
|
|
|
ServiceInterface
|
|
|
|
VersionInterface
|
2014-08-27 18:57:29 +00:00
|
|
|
MinionInterface
|
2014-08-21 21:14:06 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// PodInterface has methods to work with Pod resources.
|
2014-08-21 21:14:06 +00:00
|
|
|
type PodInterface interface {
|
2014-06-23 00:02:48 +00:00
|
|
|
ListPods(selector labels.Selector) (api.PodList, error)
|
2014-09-02 18:38:27 +00:00
|
|
|
GetPod(id string) (api.Pod, error)
|
|
|
|
DeletePod(id string) error
|
2014-06-09 05:38:45 +00:00
|
|
|
CreatePod(api.Pod) (api.Pod, error)
|
|
|
|
UpdatePod(api.Pod) (api.Pod, error)
|
2014-08-21 21:14:06 +00:00
|
|
|
}
|
2014-06-06 23:40:48 +00:00
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// ReplicationControllerInterface has methods to work with ReplicationController resources.
|
2014-08-21 21:14:06 +00:00
|
|
|
type ReplicationControllerInterface interface {
|
2014-07-31 14:59:54 +00:00
|
|
|
ListReplicationControllers(selector labels.Selector) (api.ReplicationControllerList, error)
|
2014-09-02 18:38:27 +00:00
|
|
|
GetReplicationController(id string) (api.ReplicationController, error)
|
2014-06-06 23:40:48 +00:00
|
|
|
CreateReplicationController(api.ReplicationController) (api.ReplicationController, error)
|
|
|
|
UpdateReplicationController(api.ReplicationController) (api.ReplicationController, error)
|
|
|
|
DeleteReplicationController(string) error
|
2014-08-05 23:19:32 +00:00
|
|
|
WatchReplicationControllers(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
2014-08-21 21:14:06 +00:00
|
|
|
}
|
2014-06-06 23:40:48 +00:00
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// ServiceInterface has methods to work with Service resources.
|
2014-08-21 21:14:06 +00:00
|
|
|
type ServiceInterface interface {
|
2014-08-29 02:31:41 +00:00
|
|
|
ListServices(selector labels.Selector) (api.ServiceList, error)
|
2014-09-02 18:38:27 +00:00
|
|
|
GetService(id string) (api.Service, error)
|
2014-06-06 23:40:48 +00:00
|
|
|
CreateService(api.Service) (api.Service, error)
|
|
|
|
UpdateService(api.Service) (api.Service, error)
|
|
|
|
DeleteService(string) error
|
2014-08-15 21:14:22 +00:00
|
|
|
WatchServices(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
2014-08-29 02:31:41 +00:00
|
|
|
}
|
2014-08-15 21:14:22 +00:00
|
|
|
|
2014-08-29 02:31:41 +00:00
|
|
|
// EndpointsInterface has methods to work with Endpoints resources
|
|
|
|
type EndpointsInterface interface {
|
|
|
|
ListEndpoints(selector labels.Selector) (api.EndpointsList, error)
|
2014-08-15 21:14:22 +00:00
|
|
|
WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error)
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// VersionInterface has a method to retrieve the server version.
|
2014-08-21 21:14:06 +00:00
|
|
|
type VersionInterface interface {
|
|
|
|
ServerVersion() (*version.Info, error)
|
|
|
|
}
|
|
|
|
|
2014-08-27 18:57:29 +00:00
|
|
|
type MinionInterface interface {
|
|
|
|
ListMinions() (api.MinionList, error)
|
|
|
|
}
|
|
|
|
|
2014-08-21 21:14:06 +00:00
|
|
|
// Client is the actual implementation of a Kubernetes client.
|
|
|
|
type Client struct {
|
|
|
|
*RESTClient
|
|
|
|
}
|
|
|
|
|
2014-08-28 13:56:38 +00:00
|
|
|
// New creates a Kubernetes client. This client works with pods, replication controllers
|
|
|
|
// and services. It allows operations such as list, get, update and delete on these objects.
|
|
|
|
// host must be a host string, a host:port combo, or an http or https URL. Passing a prefix
|
|
|
|
// to a URL will prepend the server path. Returns an error if host cannot be converted to a
|
|
|
|
// valid URL.
|
|
|
|
func New(host string, auth *AuthInfo) (*Client, error) {
|
|
|
|
restClient, err := NewRESTClient(host, auth, "/api/v1beta1/")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &Client{restClient}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewOrDie creates a Kubernetes client and panics if the provided host is invalid.
|
|
|
|
func NewOrDie(host string, auth *AuthInfo) *Client {
|
|
|
|
client, err := New(host, auth)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
2014-06-23 01:14:32 +00:00
|
|
|
// StatusErr might get returned from an api call if your request is still being processed
|
|
|
|
// and hence the expected return data is not available yet.
|
|
|
|
type StatusErr struct {
|
|
|
|
Status api.Status
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *StatusErr) Error() string {
|
2014-06-26 23:10:38 +00:00
|
|
|
return fmt.Sprintf("Status: %v (%#v)", s.Status.Status, s.Status)
|
2014-06-23 01:14:32 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// AuthInfo is used to store authorization information.
|
2014-06-06 23:40:48 +00:00
|
|
|
type AuthInfo struct {
|
|
|
|
User string
|
|
|
|
Password string
|
|
|
|
}
|
|
|
|
|
2014-08-21 21:14:06 +00:00
|
|
|
// RESTClient holds common code used to work with API resources that follow the
|
2014-09-02 10:00:28 +00:00
|
|
|
// Kubernetes API pattern.
|
2014-06-06 23:40:48 +00:00
|
|
|
// Host is the http://... base for the URL
|
2014-08-21 21:14:06 +00:00
|
|
|
type RESTClient struct {
|
2014-06-22 21:18:01 +00:00
|
|
|
host string
|
2014-08-28 13:56:38 +00:00
|
|
|
prefix string
|
|
|
|
secure bool
|
2014-06-22 21:18:01 +00:00
|
|
|
auth *AuthInfo
|
2014-06-06 23:40:48 +00:00
|
|
|
httpClient *http.Client
|
2014-07-07 16:36:55 +00:00
|
|
|
Sync bool
|
|
|
|
PollPeriod time.Duration
|
|
|
|
Timeout time.Duration
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-08-21 21:14:06 +00:00
|
|
|
// NewRESTClient creates a new RESTClient. This client performs generic REST functions
|
|
|
|
// such as Get, Put, Post, and Delete on specified paths.
|
2014-08-28 13:56:38 +00:00
|
|
|
func NewRESTClient(host string, auth *AuthInfo, path string) (*RESTClient, error) {
|
|
|
|
prefix, err := normalizePrefix(host, path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
base := *prefix
|
|
|
|
base.Path = ""
|
|
|
|
base.RawQuery = ""
|
|
|
|
base.Fragment = ""
|
2014-08-21 21:14:06 +00:00
|
|
|
return &RESTClient{
|
2014-08-28 13:56:38 +00:00
|
|
|
host: base.String(),
|
|
|
|
prefix: prefix.Path,
|
|
|
|
secure: prefix.Scheme == "https",
|
|
|
|
auth: auth,
|
2014-06-22 21:18:01 +00:00
|
|
|
httpClient: &http.Client{
|
|
|
|
Transport: &http.Transport{
|
|
|
|
TLSClientConfig: &tls.Config{
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2014-07-07 16:36:55 +00:00
|
|
|
Sync: false,
|
2014-08-18 17:40:35 +00:00
|
|
|
PollPeriod: time.Second * 2,
|
2014-07-07 16:36:55 +00:00
|
|
|
Timeout: time.Second * 20,
|
2014-08-28 13:56:38 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// normalizePrefix ensures the passed initial value is valid.
|
2014-08-28 13:56:38 +00:00
|
|
|
func normalizePrefix(host, prefix string) (*url.URL, error) {
|
|
|
|
if host == "" {
|
|
|
|
return nil, fmt.Errorf("host must be a URL or a host:port pair")
|
|
|
|
}
|
|
|
|
base := host
|
|
|
|
hostURL, err := url.Parse(base)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if hostURL.Scheme == "" {
|
|
|
|
hostURL, err = url.Parse("http://" + base)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if hostURL.Path != "" && hostURL.Path != "/" {
|
|
|
|
return nil, fmt.Errorf("host must be a URL or a host:port pair: %s", base)
|
|
|
|
}
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
2014-08-28 13:56:38 +00:00
|
|
|
hostURL.Path += prefix
|
2014-08-21 21:14:06 +00:00
|
|
|
|
2014-08-28 13:56:38 +00:00
|
|
|
return hostURL, nil
|
2014-08-21 21:14:06 +00:00
|
|
|
}
|
|
|
|
|
2014-08-28 13:56:38 +00:00
|
|
|
// Secure returns true if the client is configured for secure connections.
|
|
|
|
func (c *RESTClient) Secure() bool {
|
|
|
|
return c.secure
|
2014-06-22 21:18:01 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// doRequest executes a request, adds authentication (if auth != nil), and HTTPS
|
|
|
|
// cert ignoring.
|
2014-08-21 21:14:06 +00:00
|
|
|
func (c *RESTClient) doRequest(request *http.Request) ([]byte, error) {
|
2014-06-22 21:18:01 +00:00
|
|
|
if c.auth != nil {
|
|
|
|
request.SetBasicAuth(c.auth.User, c.auth.Password)
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
2014-06-22 21:18:01 +00:00
|
|
|
response, err := c.httpClient.Do(request)
|
2014-06-06 23:40:48 +00:00
|
|
|
if err != nil {
|
2014-06-24 04:55:11 +00:00
|
|
|
return nil, err
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
defer response.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(response.Body)
|
|
|
|
if err != nil {
|
|
|
|
return body, err
|
|
|
|
}
|
2014-06-26 23:10:38 +00:00
|
|
|
|
2014-07-02 20:51:27 +00:00
|
|
|
// Did the server give us a status response?
|
|
|
|
isStatusResponse := false
|
2014-06-26 23:10:38 +00:00
|
|
|
var status api.Status
|
2014-09-02 17:55:27 +00:00
|
|
|
if err := runtime.DecodeInto(body, &status); err == nil && status.Status != "" {
|
2014-07-02 20:51:27 +00:00
|
|
|
isStatusResponse = true
|
|
|
|
}
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case response.StatusCode == http.StatusConflict:
|
|
|
|
// Return error given by server, if there was one.
|
|
|
|
if isStatusResponse {
|
|
|
|
return nil, &StatusErr{status}
|
2014-06-23 01:14:32 +00:00
|
|
|
}
|
2014-07-02 20:51:27 +00:00
|
|
|
fallthrough
|
|
|
|
case response.StatusCode < http.StatusOK || response.StatusCode > http.StatusPartialContent:
|
|
|
|
return nil, fmt.Errorf("request [%#v] failed (%d) %s: %s", request, response.StatusCode, response.Status, string(body))
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the server gave us a status back, look at what it was.
|
|
|
|
if isStatusResponse && status.Status != api.StatusSuccess {
|
2014-06-26 23:10:38 +00:00
|
|
|
// "Working" requests need to be handled specially.
|
|
|
|
// "Failed" requests are clearly just an error and it makes sense to return them as such.
|
|
|
|
return nil, &StatusErr{status}
|
2014-06-23 01:14:32 +00:00
|
|
|
}
|
2014-06-22 21:18:01 +00:00
|
|
|
return body, err
|
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// ListPods takes a selector, and returns the list of pods that match that selector.
|
2014-07-08 07:15:41 +00:00
|
|
|
func (c *Client) ListPods(selector labels.Selector) (result api.PodList, err error) {
|
2014-08-05 22:23:33 +00:00
|
|
|
err = c.Get().Path("pods").SelectorParam("labels", selector).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 18:38:27 +00:00
|
|
|
// GetPod takes the id of the pod, and returns the corresponding Pod object, and an error if it occurs
|
|
|
|
func (c *Client) GetPod(id string) (result api.Pod, err error) {
|
|
|
|
err = c.Get().Path("pods").Path(id).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 18:38:27 +00:00
|
|
|
// DeletePod takes the id of the pod, and returns an error if one occurs
|
|
|
|
func (c *Client) DeletePod(id string) error {
|
|
|
|
return c.Delete().Path("pods").Path(id).Do().Error()
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// CreatePod takes the representation of a pod. Returns the server's representation of the pod, and an error, if it occurs.
|
2014-07-08 07:15:41 +00:00
|
|
|
func (c *Client) CreatePod(pod api.Pod) (result api.Pod, err error) {
|
|
|
|
err = c.Post().Path("pods").Body(pod).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// UpdatePod takes the representation of a pod to update. Returns the server's representation of the pod, and an error, if it occurs.
|
2014-07-08 07:15:41 +00:00
|
|
|
func (c *Client) UpdatePod(pod api.Pod) (result api.Pod, err error) {
|
2014-08-01 21:14:33 +00:00
|
|
|
if pod.ResourceVersion == 0 {
|
|
|
|
err = fmt.Errorf("invalid update object, missing resource version: %v", pod)
|
2014-08-01 00:35:54 +00:00
|
|
|
return
|
|
|
|
}
|
2014-07-08 07:15:41 +00:00
|
|
|
err = c.Put().Path("pods").Path(pod.ID).Body(pod).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// ListReplicationControllers takes a selector, and returns the list of replication controllers that match that selector.
|
2014-07-31 14:59:54 +00:00
|
|
|
func (c *Client) ListReplicationControllers(selector labels.Selector) (result api.ReplicationControllerList, err error) {
|
2014-08-05 22:23:33 +00:00
|
|
|
err = c.Get().Path("replicationControllers").SelectorParam("labels", selector).Do().Into(&result)
|
2014-07-31 14:59:54 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// GetReplicationController returns information about a particular replication controller.
|
2014-09-02 18:38:27 +00:00
|
|
|
func (c *Client) GetReplicationController(id string) (result api.ReplicationController, err error) {
|
|
|
|
err = c.Get().Path("replicationControllers").Path(id).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// CreateReplicationController creates a new replication controller.
|
2014-07-08 07:15:41 +00:00
|
|
|
func (c *Client) CreateReplicationController(controller api.ReplicationController) (result api.ReplicationController, err error) {
|
|
|
|
err = c.Post().Path("replicationControllers").Body(controller).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// UpdateReplicationController updates an existing replication controller.
|
2014-07-08 07:15:41 +00:00
|
|
|
func (c *Client) UpdateReplicationController(controller api.ReplicationController) (result api.ReplicationController, err error) {
|
2014-08-01 21:14:33 +00:00
|
|
|
if controller.ResourceVersion == 0 {
|
|
|
|
err = fmt.Errorf("invalid update object, missing resource version: %v", controller)
|
2014-08-01 00:35:54 +00:00
|
|
|
return
|
|
|
|
}
|
2014-07-08 07:15:41 +00:00
|
|
|
err = c.Put().Path("replicationControllers").Path(controller.ID).Body(controller).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-07-08 07:15:41 +00:00
|
|
|
// DeleteReplicationController deletes an existing replication controller.
|
2014-09-02 18:38:27 +00:00
|
|
|
func (c *Client) DeleteReplicationController(id string) error {
|
|
|
|
return c.Delete().Path("replicationControllers").Path(id).Do().Error()
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-08-05 23:19:32 +00:00
|
|
|
// WatchReplicationControllers returns a watch.Interface that watches the requested controllers.
|
|
|
|
func (c *Client) WatchReplicationControllers(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
|
|
|
|
return c.Get().
|
|
|
|
Path("watch").
|
|
|
|
Path("replicationControllers").
|
|
|
|
UintParam("resourceVersion", resourceVersion).
|
|
|
|
SelectorParam("labels", label).
|
|
|
|
SelectorParam("fields", field).
|
|
|
|
Watch()
|
|
|
|
}
|
|
|
|
|
2014-08-29 02:31:41 +00:00
|
|
|
// ListServices takes a selector, and returns the list of services that match that selector
|
|
|
|
func (c *Client) ListServices(selector labels.Selector) (result api.ServiceList, err error) {
|
|
|
|
err = c.Get().Path("services").SelectorParam("labels", selector).Do().Into(&result)
|
2014-08-28 04:32:52 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-07-08 07:15:41 +00:00
|
|
|
// GetService returns information about a particular service.
|
2014-09-02 18:38:27 +00:00
|
|
|
func (c *Client) GetService(id string) (result api.Service, err error) {
|
|
|
|
err = c.Get().Path("services").Path(id).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-07-08 07:15:41 +00:00
|
|
|
// CreateService creates a new service.
|
|
|
|
func (c *Client) CreateService(svc api.Service) (result api.Service, err error) {
|
|
|
|
err = c.Post().Path("services").Body(svc).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-07-08 07:15:41 +00:00
|
|
|
// UpdateService updates an existing service.
|
|
|
|
func (c *Client) UpdateService(svc api.Service) (result api.Service, err error) {
|
2014-08-01 21:14:33 +00:00
|
|
|
if svc.ResourceVersion == 0 {
|
|
|
|
err = fmt.Errorf("invalid update object, missing resource version: %v", svc)
|
2014-08-01 00:35:54 +00:00
|
|
|
return
|
|
|
|
}
|
2014-07-08 07:15:41 +00:00
|
|
|
err = c.Put().Path("services").Path(svc.ID).Body(svc).Do().Into(&result)
|
2014-06-23 00:02:48 +00:00
|
|
|
return
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
|
|
|
|
2014-07-08 07:15:41 +00:00
|
|
|
// DeleteService deletes an existing service.
|
2014-09-02 18:38:27 +00:00
|
|
|
func (c *Client) DeleteService(id string) error {
|
|
|
|
return c.Delete().Path("services").Path(id).Do().Error()
|
2014-06-06 23:40:48 +00:00
|
|
|
}
|
2014-07-25 19:28:20 +00:00
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// WatchServices returns a watch.Interface that watches the requested services.
|
2014-08-15 21:14:22 +00:00
|
|
|
func (c *Client) WatchServices(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
|
|
|
|
return c.Get().
|
|
|
|
Path("watch").
|
|
|
|
Path("services").
|
|
|
|
UintParam("resourceVersion", resourceVersion).
|
|
|
|
SelectorParam("labels", label).
|
|
|
|
SelectorParam("fields", field).
|
|
|
|
Watch()
|
|
|
|
}
|
|
|
|
|
2014-08-29 02:31:41 +00:00
|
|
|
// ListEndpoints takes a selector, and returns the list of endpoints that match that selector
|
|
|
|
func (c *Client) ListEndpoints(selector labels.Selector) (result api.EndpointsList, err error) {
|
|
|
|
err = c.Get().Path("endpoints").SelectorParam("labels", selector).Do().Into(&result)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-08-15 21:14:22 +00:00
|
|
|
// WatchEndpoints returns a watch.Interface that watches the requested endpoints for a service.
|
|
|
|
func (c *Client) WatchEndpoints(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
|
|
|
|
return c.Get().
|
|
|
|
Path("watch").
|
|
|
|
Path("endpoints").
|
|
|
|
UintParam("resourceVersion", resourceVersion).
|
|
|
|
SelectorParam("labels", label).
|
|
|
|
SelectorParam("fields", field).
|
|
|
|
Watch()
|
|
|
|
}
|
|
|
|
|
2014-07-25 19:28:20 +00:00
|
|
|
// ServerVersion retrieves and parses the server's version.
|
|
|
|
func (c *Client) ServerVersion() (*version.Info, error) {
|
|
|
|
body, err := c.Get().AbsPath("/version").Do().Raw()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
var info version.Info
|
|
|
|
err = json.Unmarshal(body, &info)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Got '%s': %v", string(body), err)
|
|
|
|
}
|
|
|
|
return &info, nil
|
|
|
|
}
|
2014-08-27 18:57:29 +00:00
|
|
|
|
2014-09-02 10:00:28 +00:00
|
|
|
// ListMinions lists all the minions in the cluster.
|
2014-08-27 18:57:29 +00:00
|
|
|
func (c *Client) ListMinions() (minionList api.MinionList, err error) {
|
|
|
|
err = c.Get().Path("minions").Do().Into(&minionList)
|
|
|
|
return
|
|
|
|
}
|