Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/bastion/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
Release History
===============

0.2.2
++++++
* Bug fixes
* Fixes for IP address connect

0.2.1
++++++
* Bug fixes.
Expand Down
12 changes: 11 additions & 1 deletion src/bastion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,15 @@ az network bastion rdp --name MyBastionHost --resource-group MyResourceGroup --t

### SSH to VM/VMSS using Azure Bastion host machine
```commandline
az network bastion ssh --name MyBastionHost --resource-group MyResourceGroup --enable-tunneling --target-resource-id ResourceId --auth-type password
az network bastion ssh --name MyBastionHost --resource-group MyResourceGroup --target-resource-id ResourceId --auth-type password
```

### RDP to Target IP address using Azure Bastion
```commandline
az network bastion rdp --name MyBastionHost --resource-group MyResourceGroup --target-ip-address 10.1.1.1
```

### SSH to Target IP address using Azure Bastion
```commandline
az network bastion ssh --name MyBastionHost --resource-group MyResourceGroup --target-ip-address 10.1.1.1 --auth-type password
```
15 changes: 6 additions & 9 deletions src/bastion/azext_bastion/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@ def _validate_ip_address_format(namespace):
input_value = namespace.target_ip_address
if ' ' in input_value:
raise InvalidArgumentValueError("Spaces not allowed: '{}' ".format(input_value))
input_ips = input_value.split(',')
if len(input_ips) > 8:
raise InvalidArgumentValueError('Maximum 8 IP addresses are allowed per rule.')
validated_ips = ''
for ip in input_ips:
# Use ipaddress library to validate ip network format
ip_obj = ipaddress.ip_network(ip)
validated_ips += str(ip_obj) + ','
namespace.target_ip_address = validated_ips[:-1]
try:
ipaddress.ip_address(input_value)
except ValueError as e:
raise InvalidArgumentValueError("""IP address provided is invalid.
Please verify if there are any spaces or other invalid characters.""") from e
namespace.target_ip_address = input_value
25 changes: 16 additions & 9 deletions src/bastion/azext_bastion/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ def ssh_bastion_host(cmd, auth_type, target_resource_id, target_ip_address, reso
if bastion['sku']['name'] == BastionSku.Basic.value or bastion['sku']['name'] == BastionSku.Standard.value and bastion['enableTunneling'] is not True:
raise ClientRequestError('Bastion Host SKU must be Standard and Native Client must be enabled.')

_validate_and_generate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address)
ip_connect = _is_ipconnect_request(cmd, bastion, target_ip_address)
if ip_connect:
target_resource_id = f"/subscriptions/{get_subscription_id(cmd.cli_ctx)}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/bh-hostConnect/{target_ip_address}"

_validate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address)
bastion_endpoint = _get_bastion_endpoint(cmd, bastion, resource_port, target_resource_id)

tunnel_server = _get_tunnel(cmd, bastion, bastion_endpoint, target_resource_id, resource_port)
Expand Down Expand Up @@ -235,7 +239,10 @@ def rdp_bastion_host(cmd, target_resource_id, target_ip_address, resource_group_
raise ClientRequestError('Bastion Host SKU must be Standard and Native Client must be enabled.')

ip_connect = _is_ipconnect_request(cmd, bastion, target_ip_address)
_validate_and_generate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address)
if ip_connect:
target_resource_id = f"/subscriptions/{get_subscription_id(cmd.cli_ctx)}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/bh-hostConnect/{target_ip_address}"

_validate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address)
bastion_endpoint = _get_bastion_endpoint(cmd, bastion, resource_port, target_resource_id)

if platform.system() == "Windows":
Expand Down Expand Up @@ -284,12 +291,8 @@ def _is_ipconnect_request(cmd, bastion, target_ip_address):
return False


def _validate_and_generate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address):
if target_ip_address:
if bastion['enableIpConnect'] is not True:
raise InvalidArgumentValueError("Bastion does not have IP Connect feature enabled, please enable and try again")
target_resource_id = f"/subscriptions/{get_subscription_id(cmd.cli_ctx)}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/bh-hostConnect/{target_ip_address}"
elif not is_valid_resource_id(target_resource_id):
def _validate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address):
if not is_valid_resource_id(target_resource_id):
err_msg = "Please enter a valid resource ID. If this is not working, " \
"try opening the JSON view of your resource (in the Overview tab), and copying the full resource ID."
raise InvalidArgumentValueError(err_msg)
Expand Down Expand Up @@ -346,7 +349,11 @@ def create_bastion_tunnel(cmd, target_resource_id, target_ip_address, resource_g
if bastion['sku']['name'] == BastionSku.Basic.value or bastion['sku']['name'] == BastionSku.Standard.value and bastion['enableTunneling'] is not True:
raise ClientRequestError('Bastion Host SKU must be Standard and Native Client must be enabled.')

_validate_and_generate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address)
ip_connect = _is_ipconnect_request(cmd, bastion, target_ip_address)
if ip_connect:
target_resource_id = f"/subscriptions/{get_subscription_id(cmd.cli_ctx)}/resourceGroups/{resource_group_name}/providers/Microsoft.Network/bh-hostConnect/{target_ip_address}"

_validate_resourceid(cmd, bastion, resource_group_name, target_resource_id, target_ip_address)
bastion_endpoint = _get_bastion_endpoint(cmd, bastion, resource_port, target_resource_id)

tunnel_server = _get_tunnel(cmd, bastion, bastion_endpoint, target_resource_id, resource_port, port)
Expand Down
2 changes: 2 additions & 0 deletions src/bastion/azext_bastion/tunnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def _get_auth_token(self):
else:
custom_header = {}

logger.debug("Content: %s", str(content))
web_address = f"https://{self.bastion_endpoint}/api/tokens"
response = requests.post(web_address, data=content, headers=custom_header,
verify=(not should_disable_connection_verify()))
Expand Down Expand Up @@ -219,4 +220,5 @@ def get_port(self):
return self.local_port

def set_host_name(self, hostname):
logger.debug("hereeeeeee")
self.host_name = hostname
2 changes: 1 addition & 1 deletion src/bastion/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


# HISTORY.rst entry.
VERSION = '0.2.1'
VERSION = '0.2.2'

# The full list of classifiers is available at
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
Expand Down