mirror of
https://github.com/clearlinux/WALinuxAgent.git
synced 2026-10-04 15:58:38 +00:00
Merge pull request #843 from brendandixon/master
Restrict access to Azure fabric services
This commit is contained in:
@@ -86,11 +86,13 @@ def load_conf_from_file(conf_file_path, conf=__conf__):
|
||||
"").format(conf_file_path, err))
|
||||
|
||||
__SWITCH_OPTIONS__ = {
|
||||
"OS.AllowHTTP" : False,
|
||||
"OS.EnableFirewall" : False,
|
||||
"OS.EnableFIPS" : False,
|
||||
"OS.EnableRDMA" : False,
|
||||
"OS.UpdateRdmaDriver" : False,
|
||||
"OS.CheckRdmaDriver" : False,
|
||||
"Logs.Verbose" : False,
|
||||
"OS.EnableFIPS" : False,
|
||||
"Provisioning.Enabled" : True,
|
||||
"Provisioning.UseCloudInit" : False,
|
||||
"Provisioning.AllowResetSysUser" : False,
|
||||
@@ -105,8 +107,7 @@ __SWITCH_OPTIONS__ = {
|
||||
"ResourceDisk.Format" : False,
|
||||
"ResourceDisk.EnableSwap" : False,
|
||||
"AutoUpdate.Enabled" : True,
|
||||
"EnableOverProvisioning" : False,
|
||||
"OS.AllowHTTP" : False
|
||||
"EnableOverProvisioning" : False
|
||||
}
|
||||
|
||||
__STRING_OPTIONS__ = {
|
||||
@@ -149,6 +150,9 @@ def get_configuration(conf=__conf__):
|
||||
|
||||
return options
|
||||
|
||||
def enable_firewall(conf=__conf__):
|
||||
return conf.get_switch("OS.EnableFirewall", False)
|
||||
|
||||
def enable_rdma(conf=__conf__):
|
||||
return conf.get_switch("OS.EnableRDMA", False) or \
|
||||
conf.get_switch("OS.UpdateRdmaDriver", False) or \
|
||||
|
||||
@@ -50,6 +50,10 @@ for all distros. Each concrete distro classes could overwrite default behavior
|
||||
if needed.
|
||||
"""
|
||||
|
||||
FIREWALL_ACCEPT = "iptables -t security -{0} OUTPUT -d {1} -p tcp -m owner --uid-owner {2} -j ACCEPT"
|
||||
FIREWALL_DROP = "iptables -t security -{0} OUTPUT -d {1} -p tcp -j DROP"
|
||||
FIREWALL_LIST = "iptables -t security -L"
|
||||
|
||||
DMIDECODE_CMD = 'dmidecode --string system-uuid'
|
||||
PRODUCT_ID_FILE = '/sys/class/dmi/id/product_uuid'
|
||||
UUID_PATTERN = re.compile(
|
||||
@@ -63,6 +67,40 @@ class DefaultOSUtil(object):
|
||||
self.selinux = None
|
||||
self.disable_route_warning = False
|
||||
|
||||
def enable_firewall(self, dst_ip=None, uid=None):
|
||||
try:
|
||||
if dst_ip is None or uid is None:
|
||||
raise Exception("Missing arguments to enable_firewall")
|
||||
|
||||
# If either firewall rule exists, make no changes
|
||||
accept_rule = FIREWALL_ACCEPT.format("C", dst_ip, uid)
|
||||
drop_rule = FIREWALL_DROP.format("C", dst_ip)
|
||||
|
||||
if shellutil.run(accept_rule, chk_err=False) == 0 or \
|
||||
shellutil.run(drop_rule, chk_err=False) == 0:
|
||||
return
|
||||
|
||||
# Neither rule exists, append both rules
|
||||
accept_rule = FIREWALL_ACCEPT.format("A", dst_ip, uid)
|
||||
drop_rule = FIREWALL_DROP.format("A", dst_ip)
|
||||
|
||||
if shellutil.run(accept_rule) != 0:
|
||||
logger.warn("Unable to add ACCEPT firewall rule '{0}'".format(
|
||||
accept_rule))
|
||||
return
|
||||
|
||||
if shellutil.run(drop_rule) != 0:
|
||||
logger.warn("Unable to add DROP firewall rule '{0}'".format(
|
||||
drop_rule))
|
||||
return
|
||||
|
||||
rc, output = shellutil.run_get_output(FIREWALL_LIST)
|
||||
logger.info("Successfully added firewall rules:\n{0}".format(
|
||||
output))
|
||||
|
||||
except Exception as e:
|
||||
logger.info("Unable to establish firewall: {0}".format(ustr(e)))
|
||||
|
||||
def _correct_instance_id(self, id):
|
||||
'''
|
||||
Azure stores the instance ID with an incorrect byte ordering for the
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
#
|
||||
# Requires Python 2.4+ and Openssl 1.0+
|
||||
#
|
||||
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import time
|
||||
import threading
|
||||
|
||||
import azurelinuxagent.common.conf as conf
|
||||
import azurelinuxagent.common.logger as logger
|
||||
from azurelinuxagent.common.exception import ProtocolError, OSUtilError, \
|
||||
@@ -231,6 +234,9 @@ class ProtocolUtil(object):
|
||||
try:
|
||||
os.remove(protocol_file_path)
|
||||
except IOError as e:
|
||||
# Ignore file-not-found errors (since the file is being removed)
|
||||
if e.errno == errno.ENOENT:
|
||||
return
|
||||
logger.error("Failed to clear protocol endpoint: {0}", e)
|
||||
|
||||
def get_protocol(self):
|
||||
|
||||
@@ -137,34 +137,33 @@ def _get_http_proxy(secure=False):
|
||||
|
||||
def _http_request(method, host, rel_uri, port=None, data=None, secure=False,
|
||||
headers=None, proxy_host=None, proxy_port=None):
|
||||
url, conn = None, None
|
||||
if secure:
|
||||
port = 443 if port is None else port
|
||||
if proxy_host is not None and proxy_port is not None:
|
||||
conn = httpclient.HTTPSConnection(proxy_host,
|
||||
proxy_port,
|
||||
timeout=10)
|
||||
conn.set_tunnel(host, port)
|
||||
# If proxy is used, full url is needed.
|
||||
url = "https://{0}:{1}{2}".format(host, port, rel_uri)
|
||||
else:
|
||||
conn = httpclient.HTTPSConnection(host,
|
||||
port,
|
||||
timeout=10)
|
||||
url = rel_uri
|
||||
|
||||
headers = {} if headers is None else headers
|
||||
use_proxy = proxy_host is not None and proxy_port is not None
|
||||
|
||||
if port is None:
|
||||
port = 443 if secure else 80
|
||||
|
||||
if use_proxy:
|
||||
conn_host, conn_port = proxy_host, proxy_port
|
||||
scheme = "https" if secure else "http"
|
||||
url = "{0}://{1}:{2}{3}".format(scheme, host, port, rel_uri)
|
||||
|
||||
else:
|
||||
port = 80 if port is None else port
|
||||
if proxy_host is not None and proxy_port is not None:
|
||||
conn = httpclient.HTTPConnection(proxy_host,
|
||||
proxy_port,
|
||||
timeout=10)
|
||||
# If proxy is used, full url is needed.
|
||||
url = "http://{0}:{1}{2}".format(host, port, rel_uri)
|
||||
else:
|
||||
conn = httpclient.HTTPConnection(host,
|
||||
port,
|
||||
timeout=10)
|
||||
url = rel_uri
|
||||
conn_host, conn_port = host, port
|
||||
url = rel_uri
|
||||
|
||||
if secure:
|
||||
conn = httpclient.HTTPSConnection(conn_host,
|
||||
conn_port,
|
||||
timeout=10)
|
||||
if use_proxy:
|
||||
conn.set_tunnel(host, port)
|
||||
|
||||
else:
|
||||
conn = httpclient.HTTPConnection(conn_host,
|
||||
conn_port,
|
||||
timeout=10)
|
||||
|
||||
logger.verbose("HTTP connection [{0}] [{1}] [{2}] [{3}]",
|
||||
method,
|
||||
@@ -172,10 +171,8 @@ def _http_request(method, host, rel_uri, port=None, data=None, secure=False,
|
||||
data,
|
||||
headers)
|
||||
|
||||
headers = {} if headers is None else headers
|
||||
conn.request(method=method, url=url, body=data, headers=headers)
|
||||
resp = conn.getresponse()
|
||||
return resp
|
||||
return conn.getresponse()
|
||||
|
||||
|
||||
def http_request(method,
|
||||
|
||||
@@ -27,6 +27,7 @@ import azurelinuxagent.common.logger as logger
|
||||
|
||||
from azurelinuxagent.common.dhcp import get_dhcp_handler
|
||||
from azurelinuxagent.common.osutil import get_osutil
|
||||
from azurelinuxagent.common.protocol import get_protocol_util
|
||||
|
||||
def get_env_handler():
|
||||
return EnvHandler()
|
||||
@@ -42,6 +43,7 @@ class EnvHandler(object):
|
||||
def __init__(self):
|
||||
self.osutil = get_osutil()
|
||||
self.dhcp_handler = get_dhcp_handler()
|
||||
self.protocol_util = get_protocol_util()
|
||||
self.stopped = True
|
||||
self.hostname = None
|
||||
self.dhcpid = None
|
||||
@@ -64,17 +66,28 @@ class EnvHandler(object):
|
||||
|
||||
def monitor(self):
|
||||
"""
|
||||
Monitor firewall rules
|
||||
Monitor dhcp client pid and hostname.
|
||||
If dhcp clinet process re-start has occurred, reset routes.
|
||||
"""
|
||||
protocol = self.protocol_util.get_protocol()
|
||||
while not self.stopped:
|
||||
self.osutil.remove_rules_files()
|
||||
|
||||
if conf.enable_firewall():
|
||||
self.osutil.enable_firewall(
|
||||
dst_ip=protocol.endpoint,
|
||||
uid=os.getuid())
|
||||
|
||||
timeout = conf.get_root_device_scsi_timeout()
|
||||
if timeout is not None:
|
||||
self.osutil.set_scsi_disks_timeout(timeout)
|
||||
|
||||
if conf.get_monitor_hostname():
|
||||
self.handle_hostname_update()
|
||||
|
||||
self.handle_dhclient_restart()
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
def handle_hostname_update(self):
|
||||
|
||||
@@ -81,3 +81,12 @@ OS.SshDir=/etc/ssh
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -107,3 +107,12 @@ OS.SshDir=/etc/ssh
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -76,4 +76,21 @@ OS.SshdConfigPath=/config/ssh/sshd_config
|
||||
OS.EnableRDMA=n
|
||||
|
||||
# Enable or disable goal state processing auto-update, default is enabled
|
||||
AutoUpdate.Enabled=y
|
||||
AutoUpdate.Enabled=y
|
||||
|
||||
# Determine the update family, this should not be changed
|
||||
# AutoUpdate.GAFamily=Prod
|
||||
|
||||
# Determine if the overprovisioning feature is enabled. If yes, hold extension
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -79,3 +79,12 @@ AutoUpdate.GAFamily=Prod
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -111,3 +111,8 @@ OS.OpensslPath=None
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
OS.AllowHTTP=y
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -105,3 +105,12 @@ OS.SudoersDir=/usr/local/etc/sudoers.d
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -104,3 +104,12 @@ AutoUpdate.Enabled=n
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -103,3 +103,12 @@ OS.PasswordPath=/etc/master.passwd
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -107,3 +107,12 @@ OS.SshDir=/etc/ssh
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -95,3 +95,12 @@ OS.SshDir=/etc/ssh
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -108,3 +108,8 @@ OS.SshDir=/etc/ssh
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -488,5 +488,82 @@ Match host 192.168.1.2\n\
|
||||
print("WRITING TO {0}".format(waagent_sudoers))
|
||||
self.assertEqual(1, count)
|
||||
|
||||
@patch('os.getuid', return_value=42)
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run_get_output')
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run')
|
||||
def test_enable_firewall(self, mock_run, mock_output, mock_uid):
|
||||
util = osutil.DefaultOSUtil()
|
||||
|
||||
dst = '1.2.3.4'
|
||||
uid = 42
|
||||
|
||||
mock_run.side_effect = [1, 1, 0, 0]
|
||||
mock_output.return_value = 0
|
||||
util.enable_firewall(dst_ip=dst, uid=uid)
|
||||
|
||||
mock_run.assert_has_calls([
|
||||
call(osutil.FIREWALL_ACCEPT.format("C", dst, uid), chk_err=False),
|
||||
call(osutil.FIREWALL_DROP.format("C", dst), chk_err=False),
|
||||
call(osutil.FIREWALL_ACCEPT.format("A", dst, uid)),
|
||||
call(osutil.FIREWALL_DROP.format("A", dst))
|
||||
])
|
||||
mock_output.assert_called_with(osutil.FIREWALL_LIST)
|
||||
|
||||
@patch('os.getuid', return_value=42)
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run_get_output')
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run')
|
||||
def test_enable_firewall_skips_if_accept_exists(self, mock_run, mock_output, mock_uid):
|
||||
util = osutil.DefaultOSUtil()
|
||||
|
||||
dst = '1.2.3.4'
|
||||
uid = 42
|
||||
|
||||
mock_run.side_effect = [0, 1, 0, 0]
|
||||
mock_output.return_value = 0
|
||||
util.enable_firewall(dst_ip=dst, uid=uid)
|
||||
|
||||
mock_run.assert_has_calls([
|
||||
call(osutil.FIREWALL_ACCEPT.format("C", dst, uid), chk_err=False)
|
||||
])
|
||||
mock_output.assert_not_called()
|
||||
|
||||
@patch('os.getuid', return_value=42)
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run_get_output')
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run')
|
||||
def test_enable_firewall_skips_if_drop_exists(self, mock_run, mock_output, mock_uid):
|
||||
util = osutil.DefaultOSUtil()
|
||||
|
||||
dst = '1.2.3.4'
|
||||
uid = 42
|
||||
|
||||
mock_run.side_effect = [1, 0, 0, 0]
|
||||
mock_output.return_value = 0
|
||||
util.enable_firewall(dst_ip=dst, uid=uid)
|
||||
|
||||
mock_run.assert_has_calls([
|
||||
call(osutil.FIREWALL_ACCEPT.format("C", dst, uid), chk_err=False),
|
||||
call(osutil.FIREWALL_DROP.format("C", dst), chk_err=False),
|
||||
])
|
||||
mock_output.assert_not_called()
|
||||
|
||||
@patch('os.getuid', return_value=42)
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run_get_output')
|
||||
@patch('azurelinuxagent.common.utils.shellutil.run')
|
||||
def test_enable_firewall_ignores_exceptions(self, mock_run, mock_output, mock_uid):
|
||||
util = osutil.DefaultOSUtil()
|
||||
|
||||
dst = '1.2.3.4'
|
||||
uid = 42
|
||||
|
||||
mock_run.side_effect = [1, 1, Exception]
|
||||
util.enable_firewall(dst_ip=dst, uid=uid)
|
||||
|
||||
mock_run.assert_has_calls([
|
||||
call(osutil.FIREWALL_ACCEPT.format("C", dst, uid), chk_err=False),
|
||||
call(osutil.FIREWALL_DROP.format("C", dst), chk_err=False),
|
||||
call(osutil.FIREWALL_ACCEPT.format("A", dst, uid))
|
||||
])
|
||||
mock_output.assert_not_called()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -63,7 +63,8 @@ class TestConf(AgentTestCase):
|
||||
"AutoUpdate.Enabled" : True,
|
||||
"AutoUpdate.GAFamily" : "Prod",
|
||||
"EnableOverProvisioning" : False,
|
||||
"OS.AllowHTTP" : False
|
||||
"OS.AllowHTTP" : False,
|
||||
"OS.EnableFirewall" : True
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
|
||||
@@ -112,3 +112,12 @@ OS.SshDir=/notareal/path
|
||||
# handling until inVMArtifactsProfile.OnHold is false.
|
||||
# Default is disabled
|
||||
# EnableOverProvisioning=n
|
||||
|
||||
# Allow fallback to HTTP if HTTPS is unavailable
|
||||
# Note: Allowing HTTP (vs. HTTPS) may cause security risks
|
||||
# OS.AllowHTTP=n
|
||||
|
||||
# Add firewall rules to protect access to Azure host node services
|
||||
# Note:
|
||||
# - The default is false to protect the state of exising VMs
|
||||
OS.EnableFirewall=y
|
||||
|
||||
@@ -39,6 +39,7 @@ Logs.Verbose = False
|
||||
OS.AllowHTTP = False
|
||||
OS.CheckRdmaDriver = False
|
||||
OS.EnableFIPS = True
|
||||
OS.EnableFirewall = True
|
||||
OS.EnableRDMA = False
|
||||
OS.HomeDir = /home
|
||||
OS.OpensslPath = /usr/bin/openssl
|
||||
|
||||
@@ -23,7 +23,7 @@ from azurelinuxagent.common.exception import BadRequestError, \
|
||||
import azurelinuxagent.common.utils.restutil as restutil
|
||||
|
||||
from azurelinuxagent.common.future import httpclient, ustr
|
||||
from tests.tools import AgentTestCase, patch, Mock, MagicMock
|
||||
from tests.tools import *
|
||||
|
||||
|
||||
class TestHttpOperations(AgentTestCase):
|
||||
@@ -118,46 +118,100 @@ class TestHttpOperations(AgentTestCase):
|
||||
self.assertEqual("foo.com", h)
|
||||
self.assertEqual(80, p)
|
||||
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPSConnection")
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPConnection")
|
||||
def test_http_request_direct(self, HTTPConnection, HTTPSConnection):
|
||||
mock_conn = \
|
||||
MagicMock(getresponse=\
|
||||
Mock(return_value=\
|
||||
Mock(read=Mock(return_value="TheResults"))))
|
||||
|
||||
HTTPConnection.return_value = mock_conn
|
||||
|
||||
resp = restutil._http_request("GET", "foo", "/bar")
|
||||
|
||||
HTTPConnection.assert_has_calls([
|
||||
call("foo", 80, timeout=10)
|
||||
])
|
||||
HTTPSConnection.assert_not_called()
|
||||
mock_conn.request.assert_has_calls([
|
||||
call(method="GET", url="/bar", body=None, headers={})
|
||||
])
|
||||
mock_conn.getresponse.assert_called_once()
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("TheResults", resp.read())
|
||||
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPSConnection")
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPConnection")
|
||||
def test_http_request(self, HTTPConnection, HTTPSConnection):
|
||||
mock_http_conn = MagicMock()
|
||||
mock_http_resp = MagicMock()
|
||||
mock_http_conn.getresponse = Mock(return_value=mock_http_resp)
|
||||
HTTPConnection.return_value = mock_http_conn
|
||||
HTTPSConnection.return_value = mock_http_conn
|
||||
def test_http_request_direct_secure(self, HTTPConnection, HTTPSConnection):
|
||||
mock_conn = \
|
||||
MagicMock(getresponse=\
|
||||
Mock(return_value=\
|
||||
Mock(read=Mock(return_value="TheResults"))))
|
||||
|
||||
mock_http_resp.read = Mock(return_value="_(:3| <)_")
|
||||
HTTPSConnection.return_value = mock_conn
|
||||
|
||||
# Test http get
|
||||
resp = restutil._http_request("GET", "foo", "bar")
|
||||
resp = restutil._http_request("GET", "foo", "/bar", secure=True)
|
||||
|
||||
HTTPConnection.assert_not_called()
|
||||
HTTPSConnection.assert_has_calls([
|
||||
call("foo", 443, timeout=10)
|
||||
])
|
||||
mock_conn.request.assert_has_calls([
|
||||
call(method="GET", url="/bar", body=None, headers={})
|
||||
])
|
||||
mock_conn.getresponse.assert_called_once()
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("_(:3| <)_", resp.read())
|
||||
self.assertEquals("TheResults", resp.read())
|
||||
|
||||
# Test https get
|
||||
resp = restutil._http_request("GET", "foo", "bar", secure=True)
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("_(:3| <)_", resp.read())
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPSConnection")
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPConnection")
|
||||
def test_http_request_proxy(self, HTTPConnection, HTTPSConnection):
|
||||
mock_conn = \
|
||||
MagicMock(getresponse=\
|
||||
Mock(return_value=\
|
||||
Mock(read=Mock(return_value="TheResults"))))
|
||||
|
||||
# Test http get with proxy
|
||||
mock_http_resp.read = Mock(return_value="_(:3| <)_")
|
||||
resp = restutil._http_request("GET", "foo", "bar", proxy_host="foo.bar",
|
||||
proxy_port=23333)
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("_(:3| <)_", resp.read())
|
||||
HTTPConnection.return_value = mock_conn
|
||||
|
||||
# Test https get
|
||||
resp = restutil._http_request("GET", "foo", "bar", secure=True)
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("_(:3| <)_", resp.read())
|
||||
resp = restutil._http_request("GET", "foo", "/bar",
|
||||
proxy_host="foo.bar", proxy_port=23333)
|
||||
|
||||
# Test https get with proxy
|
||||
mock_http_resp.read = Mock(return_value="_(:3| <)_")
|
||||
resp = restutil._http_request("GET", "foo", "bar", proxy_host="foo.bar",
|
||||
proxy_port=23333, secure=True)
|
||||
HTTPConnection.assert_has_calls([
|
||||
call("foo.bar", 23333, timeout=10)
|
||||
])
|
||||
HTTPSConnection.assert_not_called()
|
||||
mock_conn.request.assert_has_calls([
|
||||
call(method="GET", url="http://foo:80/bar", body=None, headers={})
|
||||
])
|
||||
mock_conn.getresponse.assert_called_once()
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("_(:3| <)_", resp.read())
|
||||
self.assertEquals("TheResults", resp.read())
|
||||
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPSConnection")
|
||||
@patch("azurelinuxagent.common.future.httpclient.HTTPConnection")
|
||||
def test_http_request_proxy_secure(self, HTTPConnection, HTTPSConnection):
|
||||
mock_conn = \
|
||||
MagicMock(getresponse=\
|
||||
Mock(return_value=\
|
||||
Mock(read=Mock(return_value="TheResults"))))
|
||||
|
||||
HTTPSConnection.return_value = mock_conn
|
||||
|
||||
resp = restutil._http_request("GET", "foo", "/bar",
|
||||
proxy_host="foo.bar", proxy_port=23333,
|
||||
secure=True)
|
||||
|
||||
HTTPConnection.assert_not_called()
|
||||
HTTPSConnection.assert_has_calls([
|
||||
call("foo.bar", 23333, timeout=10)
|
||||
])
|
||||
mock_conn.request.assert_has_calls([
|
||||
call(method="GET", url="https://foo:443/bar", body=None, headers={})
|
||||
])
|
||||
mock_conn.getresponse.assert_called_once()
|
||||
self.assertNotEquals(None, resp)
|
||||
self.assertEquals("TheResults", resp.read())
|
||||
|
||||
@patch("time.sleep")
|
||||
@patch("azurelinuxagent.common.utils.restutil._http_request")
|
||||
|
||||
Reference in New Issue
Block a user