Giter Club home page Giter Club logo

kubernetes-client's Introduction

kubernetes-client

Build Status Greenkeeper badge

Simplified Kubernetes API client for Node.js.

Installation

Install via npm:

npm i kubernetes-client --save

Initializing

kubernetes-client generates a Kubernetes API client at runtime based on a Swagger / OpenAPI specification. You can generate a client using the cluster's kubeconfig file and that cluster's API specification.

To create the config required to make a client, you can either:

let kubernetes-client configure automatically by trying the KUBECONFIG environment variable first, then ~/.kube/config, then an in-cluster service account, and lastly settling on a default proxy configuration:

const client = new Client({ version: '1.13' })

provide your own path to a file:

const { KubeConfig } = require('kubernetes-client')
const kubeconfig = new KubeConfig()
kubeconfig.loadFromFile('~/some/path')
const Request = require('kubernetes-client/backends/request')

const backend = new Request({ kubeconfig })
const client = new Client({ backend, version: '1.13' })

provide a configuration object from memory:

// Should match the kubeconfig file format exactly
const config = {
  apiVersion: 'v1',
  clusters: [],
  contexts: [],
  'current-context': '',
  kind: 'Config',
  users: []
}
const { KubeConfig } = require('kubernetes-client')
const kubeconfig = new KubeConfig()
kubeconfig.loadFromString(JSON.stringify(config))

const Request = require('kubernetes-client/backends/request')
const backend = new Request({ kubeconfig })
const client = new Client({ backend, version: '1.13' })

and you can also specify the context by setting it in the kubeconfig object:

kubeconfig.setCurrentContext('dev')

You can also elide the .version and pass an OpenAPI specification:

const spec = require('./swagger.json')
const client = new Client({ spec })

or load a specification dynamically from the kube-apiserver:

const client = new Client()
await client.loadSpec()

See Examples for more configuration examples.

Basic usage

kubernetes-client translates Path Item Objects [1] (e.g., /api/v1/namespaces) to object chains ending in HTTP methods (e.g., api.v1.namespaces.get).

So, to fetch all Namespaces:

const namespaces = await client.api.v1.namespaces.get()

kubernetes-client translates Path Templating [2] (e.g., /apis/apps/v1/namespaces/{namespace}/deployments) to function calls (e.g., apis.apps.v1.namespaces('default').deployments).

So, to create a new Deployment in the default Namespace:

const deploymentManifest = require('./nginx-deployment.json')
const create = await client.apis.apps.v1.namespaces('default').deployments.post({ body: deploymentManifest })

and then fetch your newly created Deployment:

const deployment = await client.apis.apps.v1.namespaces('default').deployments(deploymentManifest.metadata.name).get()

and finally, remove the Deployment:

await client.apis.apps.v1.namespaces('default').deployments(deploymentManifest.metadata.name).delete()

kubernetes-client supports .delete, .get, .patch, .post, and .put.

Documentation

kubernetes-client generates documentation for the included specifications:

TypeScript

kubernetes-client includes a typings declartion file for Kubernetes API 1.13 and a complimentry Client1_13 class:

import * as ApiClient from 'kubernetes-client';

const Client = ApiClient.Client1_13;
const client = new Client({ version: '1.13' });

When using TypeScript, kubernetes-client does not support dynamically generating a client via .loadSpec().

Examples

examples/ has snippets for using kubernetes-client:

Contributing

See the kubernetes-client Issues if you're interested in helping out; and look over the CONTRIBUTING.md before submitting new Issues and Pull Requests.

Testing

Run the unit tests:

npm test

The integration tests use the current-context in your kubeconfig file. Run the integration tests:

npm run test-integration

Run integration tests with the @kubernetes/client-node backend:

KUBERNETES_CLIENT_BACKEND=client-node npm run test-integration

References

License

MIT

kubernetes-client's People

Contributors

agerard-godaddy avatar ajpauwels avatar ankon avatar anton-kotenko avatar cfellin1 avatar gempesaw avatar gergelyke avatar gisenberg avatar greenkeeper[bot] avatar hekike avatar idirouhab avatar iffyio avatar jacopodaeli avatar jcrugzz avatar jh2oman avatar lholmquist avatar markherhold avatar maxpain avatar nagapavan avatar naseemkullah avatar nick avatar nochance777 avatar renovate[bot] avatar russell avatar silasbw avatar theothermike avatar tkporter avatar twood-godaddy avatar twood67 avatar vaibhavpage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kubernetes-client's Issues

`kubectl apply -f` functionality

From @therynamo:

"Another nicety would be being able to do something like kubectl apply -f, programatically. So instead of seeing, Error: deployment "insert_deployment_name_here" already exists, it would just overwrite with the new config. However, I may have yet again misread the docs."

Refactor usage of resource name strings

The current code copy pastas resource names in several places (e.g., common.js and namespace.js). Keeping them in a single place (e.g., defining an enum in common.js) will make them less painful to update.

Jobs API endpoint

This may be an inquiry more than a request, but I'm trying to use this library to list/create a job in my cluster.

According to these docs, the correct api endpoint is:
GET /apis/batch/v1/namespaces/{namespace}/jobs/{name}.

When I use this library like so (assuming the namespace configured in the k8 constructor is my-namespace:
k8.namespace.jobs('my-job').get(a => console.log(a));

It makes a request to:

/api/v1/namespaces/my-namespace/jobs/my-job

How do I get the first part of that url be /apis/batch/v1/namespaces? Is there a setting I'm missing somewhere?

Thanks, and I appreciate all the work you've done on the library so far!

URL for watching jobs

Is there a clean way to watch jobs?

The K8s URL is /apis/batch/v1/watch/namespaces/{namespace}/jobs/{name} (https://kubernetes.io/docs/api-reference/v1.6/#watch-47)

To get it to actually use that URL, I fiddled the version:

const batchWatch = new K8s.Batch({
  version: 'v1/watch',
  ...
});

const stream = batchWatch.ns.jobs('foo').get();

Is there supposed to be a better way of doing this?

Cluster level queries

Are there plans to support queries to cluster level resources queries

eg.
/api/v1/resourcequotas
/api/v1/replicationcontrollers

Support for --all-namespaces

Is there a way to get resources over all namespaces? I couldn't see an obvious way, unless I'm missing something.

Fix: namespaces define every resources (regardless of API)

The Namespaces object supports a default resources argument, but no APIs leverage it. Change our existing APIs to pass the set of resources they support (e.g., Core). This will require adding some plumbing to ApiGroup to pass the array of resources to the Namespaces constructor.

code: 404 error

I'm getting following error

{
  "code": 404
}

this is my server.js file ( i have exported export NODE_TLS_REJECT_UNAUTHORIZED=0 )

const K8Api = require('kubernetes-client');
const k8 = new K8Api({
  url: 'https://10.2.2.2:8443',
  //version: 'v1beta1', 
  auth: {
    bearer: 'sulLF-Y-vn-wgfNcjXR5bb0JU7-E0G8LDKtKYyDGpQ0'
  }
});

function print(err, result) {
  console.log(JSON.stringify(err || result, null, 2));
  console.log(result);
}

k8.namespaces.replicationcontrollers.get('mongodb', print);
k8.namespaces.replicationcontrollers.get('mongodb-1', print);

But when i do

jjonagam-osx:k8s-api cjonagam$ kubectl get rc
NAME DESIRED CURRENT AGE
mongodb-1 3 3 4d

How to list pods from specific deployment?

I am trying to list pods form specific deployment. On the docs it says it is supported on the rc(NOT deployment) but that does not work for me. I can list pods via kube.core.namespace.pods.get() only.

Deprecated Types Warning

There should be a warning when users use a deprecated type. However there needs to be a 'type x version' matrix before this can be implemented.

From @jcrugzz on implementing this:
"Not a bad idea. The only tricky part is that deprecation depends on what k8s version the user is using. We should be showing a support matrix for types and k8s version after this merges"

Initial suggestion in #78

Deployments can be created but nothing else

Hi, for some reason I can create a deployment but I cannot load/list/update it since I will always get Error: the server could not find the requested resource. Other resources are just fine.

Any idea what might be wrong?

Watcher using web sockets or polling?

Sorry for opening a bug for a question - but was wondering how the watch support is implemented. Is is just polling or establishing a web socket connection?

Deployment Delete

After looking at the k8s docs on deployment delete, it seems like passing orphanDependents: false should delete "everything" associated with the deployment.

Currently, I am trying to use the kubernetes-client api to accomplish full deletes of items associated with a deployment. For example, when using the following api:

const deployment = {
  {
  "apiVersion": "extensions/v1beta1",
  "kind": "Deployment",
  "metadata": {
    "name": "<insert_deployment_name_here>"
  },
  "spec": {
    "replicas": 2,
  ... // etc.
}

// Assume k8s is an instance of `kubernetes-api` v3.1
k8s.group(deployment).ns.deployments.delete({ body: deployment, orphanDependents: false }
// or instead using: 
k8s.group(deployment).ns.deployments.delete({ body: deployment, preservePods: false }

I would expect the above to delete an already existing deployment with the given deployment name, and all pods, and replicasets. However, the observed behavior is that the deployment does get deleted, though the pods and replicasets are orphaned (i.e. not deleted). If you run a kubectl delete deployment <deployment_name>, by default, all resources associated with the deployment will be deleted.

Perhaps you could let me know if I'm using the api wrong, or if kubernetes-client does not support this.

What I'm trying to avoid is having to have 3 callbacks, each deleting one of the above resources, in order to create a deployment with the same name.

Another nicety would be being able to do something like kubectl apply -f, programatically. So instead of seeing, Error: deployment "insert_deployment_name_here" already exists, it would just overwrite with the new config. However, I may have yet again misread the docs.

Any help is appreciated! Thanks for maintaining this project, its helped a lot and has allowed me to not have to write my own library to do exactly this. ๐Ÿ‘ x ๐Ÿ’ฏ

How to get status of pods?

When I do a k8.namespaces.replicationcontrollers.pod.get(print); Its a very long o/p..I am interested in knowing if the pod is in "Running" status or not..How can I fetch this information?
Please help!

Differences between Extensions and APIs when sending yaml/json configuration

I am struggling with the difference between post and patch on different modules, so far...

I can post using the API (but not patch)...

const api = new k8s.Api({config})
api.group(manifest0).ns.kind(manifest0).patch({ body: manifest0 }

Error: 'the server does not allow this method on the requested resource'


I can patch (deployments only) but not post. Services as an example returns the same error on both post and patch...

const ext = new k8s.Extensions({config})
ext.namespaces.deployments(project_name) .patch({ body: body}, () => {response})

Error: 'the server does not allow this method on the requested resource'

Support more Deployment operations

E.g., POST /apis/extensions/v1beta1/namespaces/{namespace}/deployments/{name}/rollback

This is a special case of a more general problem we need to handle with other objects (e.g., proxy for Pods and Services).

Promises based API

It would be nice if this library also supported promises. Unfortunately, wrapping the request library for promises is fairly non-trivial. This makes it a bit unwieldy to promisify at runtime.

The request-promise library also supports a nodeify method for callbacks, allowing simulataneous support for callbacks and promises. However, this may make streaming more cumbersome.

Perhaps a provide your own request library approach?

POST YAML rather than JSON?

I'm struggling to get POST'ing YAML to the deployments API working.

extensions.ns('test').deployments.post({
    headers: { 'content-type': 'application/yaml' },
    body: `
    apiVersion: extensions/v1beta1
    kind: Deployment ... `
});

I see if I alter the library to log out what options are generated:

{ headers: { 'content-type': 'application/json' },
  path: [ '/apis/extensions/v1beta1/namespaces/test/deployments' ],
  body: 'apiVersion: extensions/v1beta1\nkind: Deployment\n ...' }

How can I get this library to send the application/yaml header? I see the API documention for k8s says it' accepts YAML as their CURL example is YAML based.

https://kubernetes.io/docs/api-reference/v1.7/#-strong-write-operations-strong--20

And click curl for the example

Authorization

How does this module handle Authorization? Is it expected that the end-user will pass them in as headers?

Can't schedule jobs, server could not find the requested resource

I am having trouble running the example job from the k8s documentation using the client.

const Api = require('kubernetes-client');
var config = Api.config.fromKubeconfig();
config.apiVersion = 'batch/v1';
const ext = new Api.Extensions(config);

ext.namespaces.jobs.post({
    body: {
      apiVersion: 'batch/v1',
      kind: 'Job',
      metadata: {
        name: 'pi'
      },
      spec: {
        template: {
          spec: {
            restartPolicy: 'Never',
            containers: [{
              image: 'perl',
              command: ['perl', '-Mbignum=bpi', '-wle', 'print bpi(2000)'],
              name: 'pi'
            }]
          },
          metadata: {
            name: 'pi'
          }
        }
      }
    }
  },
  function(err, job) {
    if (err) return console.log('Failed to creata job: ' + err);
    console.log(job);
  });

When I run the script I get the following error:

Failed to creata job: Error: the server could not find the requested resource

But I can schedule the job without problem using kubectl

$ curl -O https://raw.githubusercontent.com/kubernetes/kubernetes.github.io/master/docs/concepts/workloads/controllers/job.yaml
$ kubectl create -f job.yaml
job "pi" created

Am I missing something or I a not configuring the extension correctly?

k8.ns.pvc.matchLabels gives 404

I used to be able to call the following:

k8.ns.pvc.matchLabels({ app: 'test' }).get((err, sRes) => {

but that now gives a 'resource not found' error. I now have to call the following instead:

k8.ns.pvc.get({ qs: { labelSelector: 'app=test' } }, (err, sRes) => {

Pod get with watch looses events

I use watch in the following format:

kubernetes.api.ns.po.get({
      qs: {
        watch: true,
        labelSelector: PodManager.serviceNameLabel
      }
    }
})

After a while it stops listening to events.
Do you have an idea?

Thanks!

Update ConfigMap

How to update and delete ConfigMap?

const api = new Api.Api({ url: process.env.K8S_HOST, namespace: kubeParam.namespace, ca: fs.readFileSync(KUBERNETES_CA_PATH,{'encoding':'utf-8'}), insecureSkipTlsVerify: true, auth: { bearer: fs.readFileSync(KUBERNETES_TOKEN_PATH,{'encoding':'utf-8'}), } }); api.core.configmap.delete({name: 'configmap-test'},print)

result
{ Error: the server could not find the requested resource }

Cert error

Getting this error while connecting. how can i fix this?

{
  "code": "SELF_SIGNED_CERT_IN_CHAIN"
}

In-cluster config support

Hi,

would you be open for adding a built-in in-cluster config?

Based on:
https://github.com/kubernetes/client-go/blob/124670e99da15091e13916f0ad4b2b2df2a39cd5/rest/config.go#L274
and
http://kubernetes.io/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod

Something like:

const fs = require('fs')

const certPath = '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt'
const tokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token'
const namespacePath = '/var/run/secrets/kubernetes.io/serviceaccount/namespace'

function getInClusterConfig () {
  const host = process.env.KUBERNETES_SERVICE_HOST
  const port = process.env.KUBERNETES_SERVICE_PORT
  let cert
  let namespace
  let bearer

  if (!host || !port) {
    throw TypeError('Unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined')
  }

  try {
    cert = fs.readFileSync(certPath, 'utf8')
  } catch (err) {
    throw TypeError('Expected to load root CA config from ${certPath}, but got err', err)
  }

  try {
    bearer = fs.readFileSync(tokenPath, 'utf8')
  } catch (err) {
    throw TypeError('Expected to load token config from ${tokenPath}, but got err', err)
  }

  try {
    namespace = fs.readFileSync(namespacePath, 'utf8')
  } catch (err) {
    throw TypeError('Expected to load namespace config from ${namespacePath}, but got err', err)
  }

  return {
    url: `https://${host}:${port}`,
    cert,
    auth: { bearer },
    namespace
  }
}

The interface could be:

const K8Api = require('kubernetes-client');
const k8 = new K8Api.Core(K8Api.getInClusterConfig())

I'm happy to send a PR if you like the idea.
What do you think?

Call to remove label from the pod

Is there a support to patch pod, I am looking to remove certain labels from a given pod.

I am trying to pass something like this in patch :
body: {op:"remove", path: "/metadata/labels/op"}

but it doesn't seem to be working.

Any advice??

Support RBAC integration tests

Setting up RBAC is more involved (e.g., it's not just minikube --extra-config=apiserver.GenericServerRunOptions.AuthorizationMode=RBAC, you need a client cert with /O=system:masters and some setup to avoid breaking the other integration tests.

  • Investigate the other setup required
  • Make it easy to run that setup
  • Ensure the other integration tests still work (another possibility is running two kube clusters, one for RBAC and one for every other integration test)

Cannot watch events endpoint

Hello! I'm trying to watch the events endpoint but the request it's not sending the watch=true. query string,

Here's how I'm doing it:

const JSONStream = require('json-stream');
jsonStream = new JSONStream();

const stream = k8.ns('myns').events.get({ qs: { watch: true } });
jsonStream.on('data', res => {
  // handling response
});

screen shot 2017-02-02 at 19 35 30

Typings

A set of typings for us Typescript users would be really cool.

Update ConfigMap values

How to update ConfigMap?

api.group(json).ns.kind(json).put({ body:JSON.parse(JSON.stringify(json)) }, print);

the result like so:
{ Error: the server does not allow this method on the requested resource}

Unable to stream

When using the streaming example as documented in the readme I just get an error indicating that getStream is not a function.

k8s-client_js_ _platform-ui

TLSWrap.onread error while using Api.config.fromKubeconfig()

I'm trying to get a services from kubernetes by passing kubeconfig to Api.config.fromKubeconfig() but I receive the following error:

Error
{ Error: read ECONNRESET
at exports._errnoException (util.js:1007:11)
at TLSWrap.onread (net.js:563:26) code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }

Sample Code multible services

const Api = require('kubernetes-client');
const kubeconfig = Api.config.loadKubeconfig(
  expandHomeDir('~/.kube/kubeconfig')
);
const core = new Api.Core(Api.config.fromKubeconfig(kubeconfig));

function getKubeCoreService(){
  core.services.get(getServices);
}

function getServices(err, result){
  console.log(err);
}

How ever if I only request one service it executes without errors

Sample Code single service

const Api = require('kubernetes-client');
const kubeconfig = Api.config.loadKubeconfig(
  expandHomeDir('~/.kube/kubeconfig')
);
const core = new Api.Core(Api.config.fromKubeconfig(kubeconfig));

function getKubeCoreService(){
  core.services('servicename').get(getServices);
}

function getServices(err, result){
  console.log(err);
}

Label added to deployment added to rc instead

I have an existing deployment and I tried to add new label and update the deployment via:

GKE.prototype.update = function(json, successCallback, failureCallback) {
  var success = successCallback || console.log;
  var error = failureCallback || console.error;

  var type = this.getType(json);
  var exec = type === 'deployments' ? this.kube.extensions : this.kube.core;

  exec.namespaces[type](this.getName(json)).patch({ body: json }, function(err, result) {
    if (err) {
      error(err);
    } else {
      success(result);
    }
  });
};

after successful submission I have noticed that the deployment is the same, but a new replication controller was created with the new label.

This is unexpected behavior. How can I update the deployment properly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.