@dmgnr/kuber 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -953,6 +953,6 @@ Headers: `+JSON.stringify(Q));this.code=$,this.body=K,this.headers=Q}}class Z${c
953
953
  `)}var Ba=F$({meta:{name:"ls",description:"List operations"},args:{workspace:{type:"string",alias:"w",description:"Filter by workspace"}},async run({args:$}){console.log(await wa($.workspace??$._[0]))}}),Ia=F$({meta:{name:"get",description:"Get an operation"},async run({args:$}){let X=String($._[0]??"").trim();if(!X)throw Error("Operation ID is required");console.log(await Oa(X))}}),kM=F$({meta:{name:"operations",description:"Inspect server operations"},subCommands:{get:Ia,ls:Ba}});var U4={reset:"\x1B[0m",fgBlack:"\x1B[30m",fgBlue:"\x1B[34m",fgPurple:"\x1B[35m",fgYellow:"\x1B[33m",fgGreen:"\x1B[32m",bgGreen:"\x1B[42m",bgYellow:"\x1B[43m",bgRed:"\x1B[41m"};function Ea($){return`${$.level==="good"?U4.bgGreen:$.level==="bad"?U4.bgRed:U4.bgYellow}${U4.fgBlack} ${$.label} ${U4.reset}`}function La($){let X=$.split("/",1)[0],K=X==="Deployment"?U4.fgBlue:X==="Service"?U4.fgPurple:X==="Ingress"?U4.fgYellow:X==="Pod"?U4.fgGreen:void 0;return K?`${K}${$}${U4.reset}`:$}function TM($){let X=[],K=(Q,G,Y)=>{X.push(`${G}${Y?"\u2514\u2500 ":"\u251C\u2500 "}${La(Q.id)} ${Ea(Q.status)}`);let Z=G+(Y?" ":"\u2502 ");Q.children.forEach((J,U)=>{K(J,Z,U===Q.children.length-1)})};for(let Q of $)X.push(Q.namespace),Q.roots.forEach((G,Y)=>{K(G,"",Y===Q.roots.length-1)}),X.push("");return X.join(`
954
954
  `)}async function ja($,X=!1,K=W$){let Q=X?"?includeIdle=true":"",G=await K(`/workspaces/${encodeURIComponent($)}/status${Q}`);return TM(G)}var RM=F$({meta:{name:"ps",description:"List deployments"},args:{all:{type:"boolean",alias:"a",description:"Show all stopped deployments (including those created by the run command)"}},async run({args:{all:$}}){console.log(await ja(A$().project,$))}});function Pa($,X,K=W$){return K(`/workspaces/${encodeURIComponent($)}/lifecycle`,{method:"POST",json:{action:"restart",...X&&{services:[X]}}})}var AM=F$({meta:{name:"restart",description:"Roll out a restart for managed deployments"},args:{deployment:{type:"positional",description:"Deployment name to restart (defaults to all managed)",required:!1}},async run({args:$}){await new V6([{title:"Restart deployments",task:async(X,K)=>{let{deployments:Q}=await Pa(A$().project,$.deployment);K.output=`${Q.length} deployments queued`}}]).run()}});function ka($,X,K,Q=W$){return Q(`/workspaces/${encodeURIComponent($)}/rollback`,{method:"POST",json:{...X&&{services:[X]},timeoutMs:K}})}var gM=F$({meta:{name:"rollback",description:"Roll deployments back to the previous release",alias:"fuck"},args:{deployment:{type:"positional",description:"Deployment name to roll back (defaults to all managed)",required:!1}},async run({args:$}){let{project:X,config:K}=A$(),Q=[];if(await new V6([{title:"Roll back deployments",task:async(G,Y)=>{({deployments:Q}=await ka(X,$.deployment,K.rolloutTimeoutMs)),Y.output=`${Q.length} deployment${Q.length===1?"":"s"} queued`}}]).run(),Q.length===0)if($.deployment)console.log(`${$.deployment} has no previous release to roll back to`);else console.log("No deployments have a previous release to roll back to")}});var Ta="http://garage-ui.garage-system.svc.cluster.local";function Ra($,X,K=W$){return K(`/workspaces/${encodeURIComponent($)}/storage/credentials`,{method:"POST",json:{claim:X}})}function Aa($){return`${Ta}/buckets/${encodeURIComponent($)}/objects`}async function _M($){let X=hF(await A$().compose()).find((K)=>K.service===$);if(!X)throw Error(`Service ${$} does not declare a managed S3 volume.`);return X}var ga=F$({meta:{name:"ls",description:"List managed S3 claims"},async run(){let $=hF(await A$().compose());if($.length===0){console.log("No managed S3 volumes declared");return}console.log(M6($.map((X)=>({service:X.service,key:X.key,bucket:X.bucket}))))}}),_a=F$({meta:{name:"creds",description:"Print S3 environment variables for a service"},async run({args:$}){let X=$._[0];if(!X)throw Error("Service name is required");let K=await Ra(A$().project,await _M(X));for(let[Q,G]of Object.entries(K))console.log(`${Q}=${G}`)}}),Sa=F$({meta:{name:"ui",description:"Print the Garage UI URL for a service bucket"},async run({args:$}){let X=$._[0];if(!X)throw Error("Service name is required");console.log(Aa((await _M(X)).bucket))}}),SM=F$({meta:{name:"s3",description:"Inspect managed S3 storage"},subCommands:{creds:_a,ls:ga,ui:Sa}});var qM=F$({meta:{name:"start",description:"Start deployments without rebuilding images"},async run(){await wN(!1)}});function qa($,X=W$){return X(`/workspaces/${encodeURIComponent($)}/lifecycle`,{method:"POST",json:{action:"stop"}})}var bM=F$({meta:{name:"stop",description:"Scale managed deployments to zero"},async run(){await new V6([{title:"Scale deployments",task:async($,X)=>{let{deployments:K}=await qa(A$().project);X.output=`${K.length} deployments queued`}}]).run()}});import{stdin as N4,stdout as RP}from"process";import{createInterface as ba}from"readline/promises";function g4($){let X=String($??"").trim();if(!X)throw Error("Username is required");return X}function xM($){let X=String($??"").split(",").map((Q)=>Q.trim()).filter(Boolean);if(X.length===0)throw Error("At least one role is required (for example: --roles admin)");let K=X.find((Q)=>!["viewer","operator","admin"].includes(Q));if(K)throw Error(`Unknown role: ${K}`);return[...new Set(X)]}function Ma($){let X=String($??"").split(",").map((Q)=>Q.trim()).filter(Boolean),K=new Set(["kubernetes:read","kubernetes:write","kubernetes:exec","users:read","users:write","sessions:revoke","platform:adopt"]);if(!X.length||X.some((Q)=>!K.has(Q)))throw Error("Provide at least one valid capability");return[...new Set(X)]}function AP($){if($.length===0)return"No users";return M6($.map((X)=>({username:X.username,roles:X.roles.join(","),disabled:X.disabled?"yes":"no",updated:X.updatedAt})))}async function CM($="Password: "){if(!N4.isTTY||!N4.setRawMode)throw Error("Password input requires an interactive terminal");return RP.write($),N4.setRawMode(!0),N4.resume(),new Promise((X,K)=>{let Q="",G=()=>{N4.off("data",Z),N4.setRawMode(!1),N4.pause(),RP.write(`
955
955
  `)},Y=(J)=>{if(G(),J)K(J);else if(!Q)K(Error("Password is required"));else X(Q)},Z=(J)=>{for(let U of J.toString()){if(U==="\x03"||U==="\x04"){Y(Error("Password input cancelled"));return}if(U==="\r"||U===`
956
- `){Y();return}if(U==="\x7F"||U==="\b")Q=Q.slice(0,-1);else Q+=U}};N4.on("data",Z)})}async function VM($){if(!N4.isTTY)throw Error("Confirmation requires an interactive terminal; use --yes");let X=ba({input:N4,output:RP});try{return(await X.question(`Delete user '${$}'? [y/N] `)).trim().toLowerCase()==="y"}finally{X.close()}}async function xa($=W$){let X=await $("/users");return AP(X.items)}async function Ca($,X,K,Q=W$){let Y=await Q("/users",{method:"POST",json:{username:$,password:X,roles:K}});return AP([Y])}async function fM($,X,K=W$){if(Object.keys(X).length===0)throw Error("No user updates specified");let Q=await K(`/users/${encodeURIComponent($)}`,{method:"PATCH",json:X});return AP([Q])}function Va($,X,K=W$){return fM($,{disabled:X},K)}async function fa($,X,K=W$){if(!X)return"Deletion cancelled";return await K(`/users/${encodeURIComponent($)}`,{method:"DELETE"}),`Deleted user ${$}`}async function ya($,X=W$){let K=await X(`/users/${encodeURIComponent($)}/sessions/revoke`,{method:"POST"});return`Revoked ${K.revoked} session${K.revoked===1?"":"s"} for ${K.username}`}function yM($){if(!$.length)return"No API keys";return M6($.map((X)=>({id:X.id,capabilities:X.capabilities.join(","),workspace:X.workspace??"",expires:X.expiresAt,disabled:X.disabled?"yes":"no"})))}async function ha($,X=W$){let K=await X(`/users/${encodeURIComponent($)}/keys`);return yM(K.items)}async function la($,X,K=W$){return K(`/users/${encodeURIComponent($)}/keys`,{method:"POST",json:X})}async function ca($,X,K,Q=W$){if(!K)return"API key revocation cancelled";return await Q(`/users/${encodeURIComponent($)}/keys/${encodeURIComponent(X)}`,{method:"DELETE"}),`Revoked API key ${X} for ${$}`}var da=F$({meta:{name:"ls",description:"List users"},async run(){console.log(await xa())}}),ia=F$({meta:{name:"add",description:"Add a user"},args:{roles:{type:"string",description:"Comma-separated roles"}},async run({args:$}){let X=g4($._[0]);console.log(await Ca(X,await CM(),xM($.roles)))}}),ua=F$({meta:{name:"update",description:"Update a user's roles or password"},args:{roles:{type:"string",description:"Comma-separated roles"},password:{type:"boolean",description:"Prompt for a new password"}},async run({args:$}){let X=g4($._[0]),K={};if($.roles!==void 0)K.roles=xM($.roles);if($.password)K.password=await CM("New password: ");console.log(await fM(X,K))}});function MM($,X){return F$({meta:{name:$,description:`${X?"Disable":"Enable"} a user`},async run({args:K}){console.log(await Va(g4(K._[0]),X))}})}var ma=F$({meta:{name:"delete",description:"Delete a user"},args:{yes:{type:"boolean",alias:"y",description:"Delete without confirmation"}},async run({args:$}){let X=g4($._[0]),K=Boolean($.yes)||await VM(X);console.log(await fa(X,K))}}),ta=F$({meta:{name:"revoke",description:"Revoke all sessions for a user"},async run({args:$}){console.log(await ya(g4($._[0])))}}),na=F$({meta:{name:"keys",description:"Manage user API keys"},subCommands:{ls:F$({meta:{name:"ls",description:"List a user's API keys"},async run({args:$}){console.log(await ha(g4($._[0])))}}),create:F$({meta:{name:"create",description:"Create an API key"},args:{capabilities:{type:"string",required:!0,description:"Comma-separated capabilities"},workspace:{type:"string",description:"Restrict the key to a workspace"},expiresDays:{type:"string",default:"90",description:"Expiry in days (1-365)"}},async run({args:$}){let X=Number($.expiresDays);if(!Number.isSafeInteger(X)||X<1||X>365)throw Error("--expires-days must be an integer from 1 to 365");let K=await la(g4($._[0]),{capabilities:Ma($.capabilities),...$.workspace&&{workspace:$.workspace},expiresAt:new Date(Date.now()+X*24*60*60*1000).toISOString()});console.log("Store this API key securely now. It will not be shown again:"),console.log(K.token),console.log(yM([K]))}}),revoke:F$({meta:{name:"revoke",description:"Revoke an API key"},args:{yes:{type:"boolean",alias:"y",description:"Revoke without confirmation"}},async run({args:$}){let X=g4($._[0]),K=g4($._[1]),Q=Boolean($.yes)||await VM(`API key '${K}' for ${X}`);console.log(await ca(X,K,Q))}})}}),hM=F$({meta:{name:"users",description:"Administer users"},subCommands:{add:ia,delete:ma,disable:MM("disable",!0),enable:MM("enable",!1),keys:na,ls:da,revoke:ta,update:ua}});function _P($){return`/workspaces/${encodeURIComponent($)}/trust`}async function gP(){let{project:$,cwd:X}=A$();return jU($,X)}async function pa($,X=W$){await X(_P($.project),{method:"POST",json:{fingerprint:$.fingerprint}}),await jE((K)=>[...K.filter((Q)=>Q.project!==$.project||Q.fingerprint!==$.fingerprint),$]),console.log(`Trusted this directory for namespace ${$.project}`)}async function oa($,X=W$){let K=(await EW()).some((Y)=>Y.project===$.project&&Y.fingerprint===$.fingerprint),G=(await X(_P($.project))).fingerprints.includes($.fingerprint);console.log(`Namespace: ${$.project}`),console.log(`Local: ${K?"trusted":"untrusted"}`),console.log(`Server: ${G?"registered":"not registered"}`)}async function ra($,X=W$){let K;try{await X(`${_P($.project)}?fingerprint=${encodeURIComponent($.fingerprint)}`,{method:"DELETE"})}catch(Q){if(!(Q instanceof O4&&Q.status===404))K=Q}if(await jE((Q)=>Q.filter((G)=>G.project!==$.project||G.fingerprint!==$.fingerprint)),K){let Q=K instanceof Error?K.message:String(K);throw Error(`Removed local trust for namespace ${$.project}, but failed to revoke the server registration: ${Q}`,{cause:K})}console.log(`Revoked trust for namespace ${$.project}`)}var lM=F$({meta:{name:"trust",description:"Trust this directory for kuber up"},subCommands:{status:F$({meta:{name:"status",description:"Show local and server trust"},async run(){await oa(await gP())}}),revoke:F$({meta:{name:"revoke",description:"Revoke this directory trust"},async run(){await ra(await gP())}})},async run(){await pa(await gP())}});var KD=F$({meta:{name:"kuber",version:"2.3.1",description:"Docker Compose -> K8s translation layer"},args:{config:{type:"string",description:"Path to a kuber configuration file"}},subCommands:{audit:Hk,ci:NM,db:DM,down:vM,export:EM,exec:BM,logs:jM,login:HM,logout:WM,operations:kM,ps:RM,restart:AM,rollback:gM,s3:SM,start:qM,stop:bM,up:UM,users:hM,trust:lM,whoami:zM}}),cM;function dM(){return cM??=mP(KD),cM}var iM=Symbol("wrappedCommand");function SP($){if($ instanceof DI)return BW.prettifyError($);if($ instanceof Error){let X=$.stack?.split(`
956
+ `){Y();return}if(U==="\x7F"||U==="\b")Q=Q.slice(0,-1);else Q+=U}};N4.on("data",Z)})}async function VM($){if(!N4.isTTY)throw Error("Confirmation requires an interactive terminal; use --yes");let X=ba({input:N4,output:RP});try{return(await X.question(`Delete user '${$}'? [y/N] `)).trim().toLowerCase()==="y"}finally{X.close()}}async function xa($=W$){let X=await $("/users");return AP(X.items)}async function Ca($,X,K,Q=W$){let Y=await Q("/users",{method:"POST",json:{username:$,password:X,roles:K}});return AP([Y])}async function fM($,X,K=W$){if(Object.keys(X).length===0)throw Error("No user updates specified");let Q=await K(`/users/${encodeURIComponent($)}`,{method:"PATCH",json:X});return AP([Q])}function Va($,X,K=W$){return fM($,{disabled:X},K)}async function fa($,X,K=W$){if(!X)return"Deletion cancelled";return await K(`/users/${encodeURIComponent($)}`,{method:"DELETE"}),`Deleted user ${$}`}async function ya($,X=W$){let K=await X(`/users/${encodeURIComponent($)}/sessions/revoke`,{method:"POST"});return`Revoked ${K.revoked} session${K.revoked===1?"":"s"} for ${K.username}`}function yM($){if(!$.length)return"No API keys";return M6($.map((X)=>({id:X.id,capabilities:X.capabilities.join(","),workspace:X.workspace??"",expires:X.expiresAt,disabled:X.disabled?"yes":"no"})))}async function ha($,X=W$){let K=await X(`/users/${encodeURIComponent($)}/keys`);return yM(K.items)}async function la($,X,K=W$){return K(`/users/${encodeURIComponent($)}/keys`,{method:"POST",json:X})}async function ca($,X,K,Q=W$){if(!K)return"API key revocation cancelled";return await Q(`/users/${encodeURIComponent($)}/keys/${encodeURIComponent(X)}`,{method:"DELETE"}),`Revoked API key ${X} for ${$}`}var da=F$({meta:{name:"ls",description:"List users"},async run(){console.log(await xa())}}),ia=F$({meta:{name:"add",description:"Add a user"},args:{roles:{type:"string",description:"Comma-separated roles"}},async run({args:$}){let X=g4($._[0]);console.log(await Ca(X,await CM(),xM($.roles)))}}),ua=F$({meta:{name:"update",description:"Update a user's roles or password"},args:{roles:{type:"string",description:"Comma-separated roles"},password:{type:"boolean",description:"Prompt for a new password"}},async run({args:$}){let X=g4($._[0]),K={};if($.roles!==void 0)K.roles=xM($.roles);if($.password)K.password=await CM("New password: ");console.log(await fM(X,K))}});function MM($,X){return F$({meta:{name:$,description:`${X?"Disable":"Enable"} a user`},async run({args:K}){console.log(await Va(g4(K._[0]),X))}})}var ma=F$({meta:{name:"delete",description:"Delete a user"},args:{yes:{type:"boolean",alias:"y",description:"Delete without confirmation"}},async run({args:$}){let X=g4($._[0]),K=Boolean($.yes)||await VM(X);console.log(await fa(X,K))}}),ta=F$({meta:{name:"revoke",description:"Revoke all sessions for a user"},async run({args:$}){console.log(await ya(g4($._[0])))}}),na=F$({meta:{name:"keys",description:"Manage user API keys"},subCommands:{ls:F$({meta:{name:"ls",description:"List a user's API keys"},async run({args:$}){console.log(await ha(g4($._[0])))}}),create:F$({meta:{name:"create",description:"Create an API key"},args:{capabilities:{type:"string",required:!0,description:"Comma-separated capabilities"},workspace:{type:"string",description:"Restrict the key to a workspace"},expiresDays:{type:"string",default:"90",description:"Expiry in days (1-365)"}},async run({args:$}){let X=Number($.expiresDays);if(!Number.isSafeInteger(X)||X<1||X>365)throw Error("--expires-days must be an integer from 1 to 365");let K=await la(g4($._[0]),{capabilities:Ma($.capabilities),...$.workspace&&{workspace:$.workspace},expiresAt:new Date(Date.now()+X*24*60*60*1000).toISOString()});console.log("Store this API key securely now. It will not be shown again:"),console.log(K.token),console.log(yM([K]))}}),revoke:F$({meta:{name:"revoke",description:"Revoke an API key"},args:{yes:{type:"boolean",alias:"y",description:"Revoke without confirmation"}},async run({args:$}){let X=g4($._[0]),K=g4($._[1]),Q=Boolean($.yes)||await VM(`API key '${K}' for ${X}`);console.log(await ca(X,K,Q))}})}}),hM=F$({meta:{name:"users",description:"Administer users"},subCommands:{add:ia,delete:ma,disable:MM("disable",!0),enable:MM("enable",!1),keys:na,ls:da,revoke:ta,update:ua}});function _P($){return`/workspaces/${encodeURIComponent($)}/trust`}async function gP(){let{project:$,cwd:X}=A$();return jU($,X)}async function pa($,X=W$){await X(_P($.project),{method:"POST",json:{fingerprint:$.fingerprint}}),await jE((K)=>[...K.filter((Q)=>Q.project!==$.project||Q.fingerprint!==$.fingerprint),$]),console.log(`Trusted this directory for namespace ${$.project}`)}async function oa($,X=W$){let K=(await EW()).some((Y)=>Y.project===$.project&&Y.fingerprint===$.fingerprint),G=(await X(_P($.project))).fingerprints.includes($.fingerprint);console.log(`Namespace: ${$.project}`),console.log(`Local: ${K?"trusted":"untrusted"}`),console.log(`Server: ${G?"registered":"not registered"}`)}async function ra($,X=W$){let K;try{await X(`${_P($.project)}?fingerprint=${encodeURIComponent($.fingerprint)}`,{method:"DELETE"})}catch(Q){if(!(Q instanceof O4&&Q.status===404))K=Q}if(await jE((Q)=>Q.filter((G)=>G.project!==$.project||G.fingerprint!==$.fingerprint)),K){let Q=K instanceof Error?K.message:String(K);throw Error(`Removed local trust for namespace ${$.project}, but failed to revoke the server registration: ${Q}`,{cause:K})}console.log(`Revoked trust for namespace ${$.project}`)}var lM=F$({meta:{name:"trust",description:"Trust this directory for kuber up"},subCommands:{status:F$({meta:{name:"status",description:"Show local and server trust"},async run(){await oa(await gP())}}),revoke:F$({meta:{name:"revoke",description:"Revoke this directory trust"},async run(){await ra(await gP())}})},async run(){await pa(await gP())}});var KD=F$({meta:{name:"kuber",version:"2.3.2",description:"Docker Compose -> K8s translation layer"},args:{config:{type:"string",description:"Path to a kuber configuration file"}},subCommands:{audit:Hk,ci:NM,db:DM,down:vM,export:EM,exec:BM,logs:jM,login:HM,logout:WM,operations:kM,ps:RM,restart:AM,rollback:gM,s3:SM,start:qM,stop:bM,up:UM,users:hM,trust:lM,whoami:zM}}),cM;function dM(){return cM??=mP(KD),cM}var iM=Symbol("wrappedCommand");function SP($){if($ instanceof DI)return BW.prettifyError($);if($ instanceof Error){let X=$.stack?.split(`
957
957
  `).slice(0,3).join(`
958
958
  `);return X&&X.trim().length>0?X:$.message}try{return JSON.stringify($,null,2)}catch{return String($)}}function aa($){console.error(SP($)),process.exitCode=1}function qP($,X=aa){let K=$;if(K[iM])return;if(K[iM]=!0,$.run){let Q=$.run;$.run=async(...G)=>{try{return await Q(...G)}catch(Y){X(Y)}}}if(!$.subCommands||typeof $.subCommands!=="object")return;for(let Q of Object.values($.subCommands))if(Q&&typeof Q==="object")qP(Q,X)}async function sa(){await dM(),qP(KD);let $=hP(KD),{configPath:X,rawArgs:K}=zk(process.argv.slice(2)),Q=new Set(["login","logout","whoami"]);if(K[0]&&Q.has(K[0])){await $({rawArgs:K});return}await kR(()=>$({rawArgs:K}),X)}sa().catch(($)=>{console.error(SP($)),process.exitCode=1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dmgnr/kuber",
3
- "version": "2.3.1",
3
+ "version": "2.3.2",
4
4
  "description": "Docker Compose to Kubernetes translation layer",
5
5
  "bin": {
6
6
  "kuber": "dist/index.js"