@@ -1635,32 +1635,44 @@ export default class OtomiStack {
16351635 return ( await getKubernetesVersion ( ) ) as string
16361636 }
16371637
1638- async connectCloudtty ( data : Cloudtty ) : Promise < Cloudtty | any > {
1638+ async connectCloudtty ( teamId : string , sessionUser : SessionUser ) : Promise < Cloudtty > {
1639+ if ( ! sessionUser . sub ) {
1640+ debug ( 'No user sub found, cannot connect to shell.' )
1641+ throw new OtomiError ( 500 , 'No user sub found, cannot connect to shell.' )
1642+ }
1643+ const userTeams = sessionUser . teams . map ( ( teamName ) => `team-${ teamName } ` )
16391644 const variables = {
1640- FQDN : data . domain ,
1641- EMAIL : data . emailNoSymbols ,
1642- SUB : data . sub ,
1645+ FQDN : '' ,
1646+ SUB : sessionUser . sub ,
1647+ }
1648+ try {
1649+ const { cluster } = this . getSettings ( [ 'cluster' ] )
1650+ variables . FQDN = cluster ?. domainSuffix || ''
1651+ } catch ( error ) {
1652+ debug ( 'Error getting cluster settings for cloudtty:' , error . message )
1653+ }
1654+ if ( ! variables . FQDN ) {
1655+ debug ( 'No cluster domain suffix found, cannot connect to shell.' )
1656+ throw new OtomiError ( 500 , 'No cluster domain suffix found, cannot connect to shell.' )
16431657 }
16441658
1645- const { userTeams } = data
1646-
1647- // if cloudtty does not exists then check if the pod is running and return it
1648- if ( await checkPodExists ( 'team-admin' , `tty-${ data . emailNoSymbols } ` ) ) {
1649- return { ...data , iFrameUrl : `https://tty.${ data . domain } /${ data . emailNoSymbols } ` }
1659+ // if cloudtty shell does not exists then check if the pod is running and return it
1660+ if ( await checkPodExists ( 'team-admin' , `tty-${ sessionUser . sub } ` ) ) {
1661+ return { iFrameUrl : `https://tty.${ variables . FQDN } /${ sessionUser . sub } ` }
16501662 }
16511663
16521664 if ( await pathExists ( '/tmp/ttyd.yaml' ) ) await unlink ( '/tmp/ttyd.yaml' )
16531665
16541666 //if user is admin then read the manifests from ./dist/src/ttyManifests/adminTtyManifests
1655- const files = data . isAdmin
1667+ const files = sessionUser . isPlatformAdmin
16561668 ? await readdir ( './dist/src/ttyManifests/adminTtyManifests' , 'utf-8' )
16571669 : await readdir ( './dist/src/ttyManifests' , 'utf-8' )
16581670 const filteredFiles = files . filter ( ( file ) => file . startsWith ( 'tty' ) )
16591671 const variableKeys = Object . keys ( variables )
16601672
16611673 const podContentAddTargetTeam = ( fileContent ) => {
16621674 const regex = new RegExp ( `\\$TARGET_TEAM` , 'g' )
1663- return fileContent . replace ( regex , data . teamId )
1675+ return fileContent . replace ( regex , teamId )
16641676 }
16651677
16661678 // iterates over the rolebinding file and replace the $TARGET_TEAM with the team name for teams
@@ -1676,41 +1688,45 @@ export default class OtomiStack {
16761688
16771689 const fileContents = await Promise . all (
16781690 filteredFiles . map ( async ( file ) => {
1679- let fileContent = data . isAdmin
1691+ let fileContent = sessionUser . isPlatformAdmin
16801692 ? await readFile ( `./dist/src/ttyManifests/adminTtyManifests/${ file } ` , 'utf-8' )
16811693 : await readFile ( `./dist/src/ttyManifests/${ file } ` , 'utf-8' )
16821694 variableKeys . forEach ( ( key ) => {
16831695 const regex = new RegExp ( `\\$${ key } ` , 'g' )
1684- fileContent = fileContent . replace ( regex , variables [ key ] )
1696+ fileContent = fileContent . replace ( regex , variables [ key ] as string )
16851697 } )
16861698 if ( file === 'tty_02_Pod.yaml' ) fileContent = podContentAddTargetTeam ( fileContent )
1687- if ( ! data . isAdmin && file === 'tty_03_Rolebinding.yaml' ) fileContent = rolebindingContentsForUsers ( fileContent )
1699+ if ( ! sessionUser . isPlatformAdmin && file === 'tty_03_Rolebinding.yaml' )
1700+ fileContent = rolebindingContentsForUsers ( fileContent )
16881701 return fileContent
16891702 } ) ,
16901703 )
16911704 await writeFile ( '/tmp/ttyd.yaml' , fileContents , 'utf-8' )
16921705 await apply ( '/tmp/ttyd.yaml' )
1693- await watchPodUntilRunning ( 'team-admin' , `tty-${ data . emailNoSymbols } ` )
1706+ await watchPodUntilRunning ( 'team-admin' , `tty-${ sessionUser . sub } ` )
16941707
16951708 // check the pod every 30 minutes and terminate it after 2 hours of inactivity
16961709 const ISACTIVE_INTERVAL = 30 * 60 * 1000
16971710 const TERMINATE_TIMEOUT = 2 * 60 * 60 * 1000
16981711 const intervalId = setInterval ( ( ) => {
1699- getCloudttyActiveTime ( 'team-admin' , `tty-${ data . emailNoSymbols } ` ) . then ( ( activeTime : number ) => {
1712+ getCloudttyActiveTime ( 'team-admin' , `tty-${ sessionUser . sub } ` ) . then ( ( activeTime : number ) => {
17001713 if ( activeTime > TERMINATE_TIMEOUT ) {
1701- this . deleteCloudtty ( data )
1714+ this . deleteCloudtty ( sessionUser )
17021715 clearInterval ( intervalId )
17031716 debug ( `Cloudtty terminated after ${ TERMINATE_TIMEOUT / ( 60 * 60 * 1000 ) } hours of inactivity` )
17041717 }
17051718 } )
17061719 } , ISACTIVE_INTERVAL )
17071720
1708- return { ... data , iFrameUrl : `https://tty.${ data . domain } /${ data . emailNoSymbols } ` }
1721+ return { iFrameUrl : `https://tty.${ variables . FQDN } /${ sessionUser . sub } ` }
17091722 }
17101723
1711- async deleteCloudtty ( data : Cloudtty ) {
1724+ async deleteCloudtty ( sessionUser : SessionUser ) : Promise < void > {
1725+ const { sub, isPlatformAdmin, teams } = sessionUser as { sub : string ; isPlatformAdmin : boolean ; teams : string [ ] }
1726+ const userTeams = teams . map ( ( teamName ) => `team-${ teamName } ` )
17121727 try {
1713- if ( await checkPodExists ( 'team-admin' , `tty-${ data . emailNoSymbols } ` ) ) await k8sdelete ( data )
1728+ if ( await checkPodExists ( 'team-admin' , `tty-${ sessionUser . sub } ` ) )
1729+ await k8sdelete ( { sub, isPlatformAdmin, userTeams } )
17141730 } catch ( error ) {
17151731 debug ( 'Failed to delete cloudtty' )
17161732 }
0 commit comments