godaddy/kubernetes-client

Use within Google Cloud Functions

Open

#262 aperta il 7 mag 2018

Vedi su GitHub
 (12 commenti) (18 reazioni) (0 assegnatari)JavaScript (206 fork)batch import
help wanted

Metriche repository

Star
 (954 star)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

I wanted to kick off a job in my GKE cluster from a Google Cloud Function reacting to changes in Cloud Storage. Since there's no .kube/config it wasn't clear to me how to do that with the new fromKubeConfig initialization. I got it working by piecing together a config object from data retrieved by google-auth-library and @google-cloud/container clients. I'll leave it here to both ask if this way makes sense and to serve as an example for others trying to do something similar.

const {auth} = require('google-auth-library');
const container = require('@google-cloud/container');
const job = require('./job.json');
const kube = require('kubernetes-client');

const clusterClient = new container.v1.ClusterManagerClient();
const request = {
  projectId: process.env.GCLOUD_PROJECT,
  zone: 'us-east4-b',
  clusterId: 'cluster-2',
};

function getCluster() {
  return clusterClient.getCluster(request)
    .then(results => {
      return results[0];
    });
}

function getToken() {
  return auth.getClient()
    .then(client => {
      return client.getAccessToken();
    })
    .then(tokenResponse => {
      return tokenResponse.token;
    });
}

// kubeClient is a lazy global used for caching.
// https://cloud.google.com/functions/docs/bestpractices/tips#use_global_variables_to_reuse_objects_in_future_invocations
let kubeClient;

function getKubeClient(cluster, token) {
  kubeClient = new kube.Client({config: kube.config.fromKubeconfig({
    apiVersion: 'v1',
    kind: 'Config',
    preferences: {},
    'current-context': 'a',
    contexts: [
      {
        name: 'a',
        context: {
          cluster: 'a',
          user: 'a'
        }
      }
    ],
    clusters: [
      {
        name: 'a',
        cluster: {
          'certificate-authority-data': cluster.masterAuth.clusterCaCertificate,
          server: `https://${cluster.endpoint}`
        }
      }
    ],
    users: [
      {
        name: 'a',
        user: {
          'auth-provider': {
            config: {
              'access-token': token,
              'cmd-args': 'config config-helper --format=json',
              'cmd-path': '/google/google-cloud-sdk/bin/gcloud',
              'token-key': '{.credential.access_token}'
            },
            name: 'gcp'
          }
        }
      }
    ]
  })});
  return kubeClient.loadSpec();
}

exports.updateJob = (event) => {
  return (kubeClient && Promise.resolve(kubeClient) ||
    Promise.all([getCluster(), getToken()]).then(([cluster, token]) => {
      return getKubeClient(cluster, token);
    }))
    .then(kubeClient => {
      // Strip extension from filename to get job name
      const name = event.data.name.replace(/\.[^/.]+$/, "");
      job.metadata.generateName = `${name}-update-`;
      job.spec.template.spec.volumes[0].configMap.name = name;
      return kubeClient.apis.batch.v1.namespaces('default').jobs.post({body: job});
    })
    .then(res => {
      console.log('Job created:', res.body.metadata.name);
    });
};

Guida contributor