oci ce cluster generate-token is missing in SDK
geisbruch opened this issue · 1 comments
geisbruch commented
There is no option to generate OKE token to connect to the cluster without locally run "oci ce cluster generate-token"
geisbruch commented
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();