npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

k8s-apply

v1.1.0

Published

A minimalistic kubernetes api interface - without any dependencies

Downloads

11

Readme

A minimalistic kubernetes api interface - without any dependencies

All methods return promises, so they can be bundled by using async/await. The library assumes to be used inside the cluster. Certificates and Tokens are read from /var/run/secrets/kubernetes.io/serviceaccount.

Function

All API calls are performed over the REST interface using node.js' internal https module. In order to allow a self signed certificate (as used by kubernetes), the certificate is monkey patched into tls.createSecureContext, see this article by David Barral.

Raw request

Use only if you want to do something exotic:

const k8sApi = new K8sApi();

const { statusCode, data } = await k8sApi.request( "/apis/my-extensions.example.com/v1/namespaces/my-namespace/extension-name?pretty=true" );
console.log( "List Example:", statusCode, JSON.stringify( data, null, 4 ) );

request by default performs a GET, so the above call is equal to k8sApi.get(...)

HTTP Wrappers

To provide more comfort around the raw call the following wrapper functions are provided:

  • async get( path, options ) - list objects or receive single object (add object name to the end of path)
  • async post( path, object, options ) - post (create) new object
  • async put( path, object, options ) - replace existing object
  • async del( path, options ) - delete existing object

All wrappers return the raw-request object consisting of:

  • statusCode of the HTTP request
  • data JSON response body (already parsed as object)

Apply object

If one wants to mimic the behaviour of kubectl apply, this function does that:

async applyObject( object )

It works as follows:

  1. Construct resource plural-path from object (assumes simple s for plural name).
  2. Attempts to create object
  3. If that works or fails hard the result is returned - goto 8.
  4. If a 409 (Conflict) is returned, the object already exists
  5. Read current object to receive the resourceVersion
  6. If read fails (i.e. get permission not present in ClusterRole), the result is returned - goto 8.
  7. Attempt to replace object using the existing name and the fetched resourceVersion
  8. return result

Example:

If you have your object stored in YAML, you can use the library js-yaml library.

const YAML = require("js-yaml");
const fs = require("fs");
const object = YAML.load( fs.readFileSync("service.yaml") );
try {
    const { statusCode, data } = await k8sApi.applyObject( object );
    console.log( "APPLY", statusCode+"\n", JSON.stringify( data, null, 4 ) );
} catch( err ) {
    console.log( "APPLY Failed,", err );
}

Delete object

Constructs the delete-path from the provided object

async delObject( object )

Example:

const YAML = require("js-yaml");
const fs = require("fs");
const object = YAML.load( fs.readFileSync("service.yaml") );
console.log( "YAML:", JSON.stringify(object, null, 4) );
try {
    const { statusCode, data } = await k8sApi.delObject( object );
    console.log( "DELETE:", statusCode+"\n", JSON.stringify( data, null, 4 ) );
} catch( err ) {
    console.log( "DELETE Failed,", err );
}

async/await Example

If you are new to async and await, here is how you can serialize apply and delete quite simple:

async function main() {
    /* use nested function to reuse names for `applyExample` and `delExample` */
    async function applyExample() {
        const YAML = require("js-yaml");
        const fs = require("fs");
        const object = YAML.load( fs.readFileSync("service.yaml") );
        console.log( "YAML:", JSON.stringify(object, null, 4) );
        try {
            const { statusCode, data } = await k8sApi.applyObject( object );
            console.log( "APPLY:", statusCode+"\n", JSON.stringify( data, null, 4 ) );
        } catch( err ) {
            console.log( "APPLY Failed,", err );
        }
    }
    await applyExample();

    /* list instances - use object destructure and renaming */
    let { statusCode: listStatusCode, data: listData } = await k8sApi.get("/api/v1/namespaces/my-namespace/services");
    console.log( "List Status:", listStatusCode+"" );
    listData.items.forEach( item => console.log( "Service:", JSON.stringify( item, null, 4 ) ) );

    async function delExample() {
        const YAML = require("js-yaml");
        const fs = require("fs");
        const object = YAML.load( fs.readFileSync("service.yaml") );
        console.log( "YAML:", JSON.stringify(object, null, 4) );
        try {
            const { statusCode, data } = await k8sApi.delObject( object );
            console.log( "DELETE:", statusCode+"\n", JSON.stringify( data, null, 4 ) );
        } catch( err ) {
            console.log( "DELETE Failed,", err );
        }
    }
    await delExample();
}
main();

Motivation

The popular kubernetes-client uses TypeScript and consists of a lot of hollow classes. This is fine if you like languages like Java, but can feel a bit alien if you are used to terser syntax. I do use kubernetes-client in some projects, but find it quite hard to look for the proper class to use, and do not see a benefit in looking up class names. To better understand my reasoning here, feel free to read this article by Lucas Chen

If you want to just apply an existing YAML, this library allows you to do just that in very few lines of code (see example above).