Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oci ce cluster generate-token is missing in SDK #289

Open
geisbruch opened this issue Jun 13, 2024 · 1 comment
Open

oci ce cluster generate-token is missing in SDK #289

geisbruch opened this issue Jun 13, 2024 · 1 comment
Labels
Container Engine Issue pertains to the Container Engine for Kubernetes service

Comments

@geisbruch
Copy link

There is no option to generate OKE token to connect to the cluster without locally run "oci ce cluster generate-token"

@geisbruch
Copy link
Author

Here an snippet about how to do it outside the SDK allowing a full kube config that does not requires oci cli to be installed in the machine

This snippet simulate the logic of the command oci ce cluster generate-token

const clusterId = "<your cluster id>";

const cred = new oci.SimpleAuthenticationDetailsProvider(
    "ocid1.tenancy.oc1..<your tenancy>",
    "ocid1.user.oc1..<your user>",
    "<your fingerprint>",
    "<your private key>",
    null,
    oci.common.Region.fromRegionId("<region id>")
);

function buildSignedUrl() {
      const method = "GET"; // Change this to POST, PUT, etc. if needed
      const endpoint = `https://containerengine.${cred.getRegion().regionId}.oraclecloud.com/cluster_request/${clusterId}`;
      const headersToSign = ["date", "(request-target)", "host"];
      //const keyId = "ocid1.tenancy.oc1..your_tenancy_ocid/ocid1.user.oc1..your_user_ocid/your_key_fingerprint";
      const keyId = `${cred.getTenantId()}/${cred.getUser()}/${cred.getFingerprint()}`;
      const privateKey = cred.getPrivateKey();

      // Prepare date header
      const date = new Date().toUTCString();

      // Parse the URL
      const url = new URL(endpoint);
      const host = url.host;
      const path = url.pathname;

      // Create (request-target) header
      const requestTarget = `${method.toLowerCase()} ${path}`;

      // Headers to sign
      const headers = {
          "date": date,
          "(request-target)": requestTarget,
          "host": host
      };

      // Create signing string
      const signingString = headersToSign.map((header) => `${header}: ${headers[header]}`).join("\n");

      // Sign the string
      const sign = crypto.createSign("RSA-SHA256");
      sign.update(signingString);
      sign.end();
      const signature = sign.sign(privateKey, "base64");

      // Create authorization header
      const authorizationHeader = `Signature algorithm="rsa-sha256",headers="${headersToSign.join(" ")}",keyId="${keyId}",signature="${signature}",version="1"`;

      // Construct the signed URL
      const signedUrl = `${url.href}?authorization=${encodeURIComponent(authorizationHeader)}&date=${encodeURIComponent(date)}`;
      return signedUrl;
}
const sUrl = buildSignedUrl();
const token = Buffer.from(sUrl).toString('base64');

Now you can use that token in your kubeconfig

  const ceClient = new oci.containerengine.ContainerEngineClient(
      {
          authenticationDetailsProvider: cred,
      }
  );
 const kcConfig = await ceClient.createKubeconfig({
      clusterId,
      createClusterKubeconfigContentDetails: {
          tokenVersion: "2.0.0"
      }
  });
  let kubeConfigStr = "";
  for await(const chunk of kcConfig.value) {
      kubeConfigStr += Buffer.from(chunk).toString("utf8");
  }


  const kubeConfigObj = yaml.parse(kubeConfigStr);
  const kc = new k8s.KubeConfig();
  kc.addCluster({
      name: kubeConfigObj.clusters[0].name,
      caData: kubeConfigObj.clusters[0].cluster["certificate-authority-data"],
      skipTLSVerify: true,
      server: kubeConfigObj.clusters[0].cluster.server
  });
  kc.addUser({
      token,
      name: kubeConfigObj.users[0].name
  });
  kc.addContext({
      cluster: kubeConfigObj.clusters[0].name,
      user: kubeConfigObj.users[0].name,
      name: kubeConfigObj.contexts[0].name
  });
  kc.setCurrentContext(kubeConfigObj.contexts[0].name);
  const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
  const ns = await k8sApi.listNamespace();

@jyotisaini jyotisaini added the Container Engine Issue pertains to the Container Engine for Kubernetes service label Aug 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Container Engine Issue pertains to the Container Engine for Kubernetes service
Projects
None yet
Development

No branches or pull requests

2 participants