Skip to content

Commit

Permalink
Improve OS username resolution for EC2 instances (#1808)
Browse files Browse the repository at this point in the history
- Expanded supported patterns to include rhel and suse-sles images.
- Introduced a defaultUserName (ec2-user) for unsupported or unmatched image patterns.
- Updated resolveOsUserName function to handle null or undefined values for imageName.
- Fixed case-sensitivity issues by converting imageName to lowercase before matching.
- Simplified logic to ensure robust and predictable username resolution.
- Included the --region flag
  • Loading branch information
pastuxso authored Nov 19, 2024
1 parent 5c5c658 commit 3640fa7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
6 changes: 3 additions & 3 deletions examples/aws/ec2.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#Instances

```sh {"background":"true","id":"01J1B86EN48NRRJHPNVVGJAMXY"}
echo "Connecting to instance via SSH..."
aws ec2-instance-connect ssh --instance-id i-0656ca72923a992b7 --os-user=ec2-user
aws ec2-instance-connect ssh --instance-id i-0656ca72923a992b7 --region=us-east-1 --os-user=ec2-user
```

```sh {"background":"true","id":"01J1B85H6ZJ6P0VA9PW3D3Q3H7"}
echo "Connecting to instance via SSH..."
aws ec2-instance-connect ssh --instance-id i-015097a0646c45ea8 --os-user=ubuntu
aws ec2-instance-connect ssh --instance-id i-015097a0646c45ea8 --region=us-east-1 --os-user=ubuntu
```

Isn't that cool? that's a **Runme cloud renderer** in Action!
Expand Down Expand Up @@ -104,4 +104,4 @@ aws ec2-instance-connect ssh --instance-id $EC2_INSTANCE_ID --os-user=ubuntu
### Feedback welcome!

Do you have feedback or new ideas ? what about more Runme Cloud renderers for AWS features ?
Feel free to [reach out to us](https://github.com/stateful/runme?tab=readme-ov-file#feedback)
Feel free to [reach out to us](https://github.com/stateful/runme?tab=readme-ov-file#feedback)
14 changes: 7 additions & 7 deletions src/client/components/aws/ec2Helper.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
export function resolveOsUserName(imageName: string) {
export function resolveOsUserName(imageName: string | null | undefined) {
if (!imageName) {
return ''
}

const defaultUserName = 'ec2-user'
const amiPatterns: { [key: string]: string } = {
'^(amazon|amzn|al2023)': 'ec2-user',
'^(amazon|amzn|al2023|rhel|suse-sles)': defaultUserName,
'^(ubuntu|centos|redhat|debian)': '\\1', // Use backreference for matched pattern (group 1)
'.+': '\\w+',
}

for (const pattern in amiPatterns) {
const match = imageName.match(new RegExp(pattern))
if (match) {
return match[1] ? amiPatterns[pattern].replace('\\1', match[1]) : amiPatterns[pattern]
const match = imageName.toLocaleLowerCase().match(new RegExp(pattern, 'i'))
if (match && match[1]) {
return amiPatterns[pattern].replace('\\1', match[1])
}
}

return ''
return defaultUserName
}
2 changes: 1 addition & 1 deletion src/extension/messages/aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export async function handleAWSMessage({ message, editor }: AWSStatusMessaging):
editor,
'echo "Connecting to instance via SSH..."\n' +
// eslint-disable-next-line max-len
`aws ec2-instance-connect ssh --instance-id ${message.output.instance} --os-user=${message.output.osUser}`,
`aws ec2-instance-connect ssh --instance-id ${message.output.instance} --region=${message.output.region} --os-user=${message.output.osUser}`,
'sh',
true,
)
Expand Down
44 changes: 44 additions & 0 deletions tests/client/components/aws/ec2Helper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { describe, it, expect } from 'vitest'

import { resolveOsUserName } from '../../../../src/client/components/aws/ec2Helper'

describe('resolveOsUserName', () => {
it('should return empty string when imageName is empty', () => {
expect(resolveOsUserName('')).toBe('')
})

it('should return "ec2-user" for Amazon Linux image names', () => {
expect(resolveOsUserName('amazon-linux')).toBe('ec2-user')
expect(resolveOsUserName('amzn-ami')).toBe('ec2-user')
expect(resolveOsUserName('al2023')).toBe('ec2-user')
})

it('should return "ec2-user" for RHEL or SUSE Linux image names', () => {
expect(resolveOsUserName('rhel-8')).toBe('ec2-user')
expect(resolveOsUserName('suse-sles')).toBe('ec2-user')
})

it('should return the corresponding user for Ubuntu, CentOS, RedHat, or Debian image names', () => {
expect(resolveOsUserName('ubuntu-20.04')).toBe('ubuntu')
expect(resolveOsUserName('centos-7')).toBe('centos')
expect(resolveOsUserName('redhat')).toBe('redhat')
expect(resolveOsUserName('debian')).toBe('debian')
})

it('should return "ec2-user" for unknown patterns', () => {
expect(resolveOsUserName('unknown-image')).toBe('ec2-user')
expect(resolveOsUserName('custom-linux-image')).toBe('ec2-user')
})

it('should be case insensitive', () => {
expect(resolveOsUserName('UbUnTu-18.04')).toBe('ubuntu')
expect(resolveOsUserName('AMAZON-LINUX')).toBe('ec2-user')
expect(resolveOsUserName('RHEL-7')).toBe('ec2-user')
})

it('should handle edge cases gracefully', () => {
expect(resolveOsUserName(null)).toBe('')
expect(resolveOsUserName(undefined)).toBe('')
expect(resolveOsUserName(' ')).toBe('ec2-user') // Assuming whitespace counts as unknown pattern
})
})

0 comments on commit 3640fa7

Please sign in to comment.