Add ability to specify NO_PROXY variable

Add ability to bypass proxies for some domains
by adding them to NO_PROXY list.

Change-Id: I4b1e63918d467d6ee6bb90f69fc0cbf5b7be4961
Closes-Bug:#1534505
This commit is contained in:
Fedor Zhadaev 2017-01-30 19:28:06 +04:00
parent 8af5a4df68
commit b9aaa446a8
2 changed files with 103 additions and 9 deletions

View File

@ -14,6 +14,7 @@
# under the License.
import copy
import logging
import os
import re
import requests
import types
@ -35,6 +36,7 @@ localhost_pattern = re.compile(r'(127.0.0.1|localhost)')
BOOTSTRAP_HTTP_PROXY_KEY = "BOOTSTRAP/http_proxy"
BOOTSTRAP_HTTPS_PROXY_KEY = "BOOTSTRAP/https_proxy"
BOOTSTRAP_NO_PROXY_KEY = "BOOTSTRAP/no_proxy"
BOOTSTRAP_REPOS_KEY = "BOOTSTRAP/repos"
BOOTSTRAP_SKIP_BUILD_KEY = "BOOTSTRAP/skip_default_img_build"
@ -59,6 +61,7 @@ class BootstrapImage(urwid.WidgetWrap):
modulehelper.BLANK_KEY,
BOOTSTRAP_HTTP_PROXY_KEY,
BOOTSTRAP_HTTPS_PROXY_KEY,
BOOTSTRAP_NO_PROXY_KEY,
modulehelper.BLANK_KEY,
BOOTSTRAP_REPOS_KEY,
ADD_REPO_BUTTON_KEY
@ -101,6 +104,10 @@ class BootstrapImage(urwid.WidgetWrap):
"label": "HTTPS proxy",
"tooltip": "Use this proxy when building the bootstrap image",
"value": ""},
BOOTSTRAP_NO_PROXY_KEY: {
"label": "Bypass proxy for",
"tooltip": "Bypass proxy for domains from this list",
"value": ""},
BOOTSTRAP_REPOS_KEY: {
"label": "List of repositories",
"type": modulehelper.WidgetType.LIST,
@ -158,11 +165,12 @@ class BootstrapImage(urwid.WidgetWrap):
http_proxy = responses[BOOTSTRAP_HTTP_PROXY_KEY].strip()
https_proxy = responses[BOOTSTRAP_HTTPS_PROXY_KEY].strip()
no_proxy = responses[BOOTSTRAP_NO_PROXY_KEY].strip()
proxies = {
'http': http_proxy,
'https': https_proxy
}
# Set up proxy settings
os.environ['HTTP_PROXY'] = http_proxy
os.environ['HTTPS_PROXY'] = https_proxy
os.environ['NO_PROXY'] = no_proxy
repos = responses.get(BOOTSTRAP_REPOS_KEY)
@ -186,7 +194,7 @@ class BootstrapImage(urwid.WidgetWrap):
"'deb uri distribution [component1] [...]'."
.format(name))
continue
if not self._check_repo(repo['uri'], repo['suite'], proxies):
if not self._check_repo(repo['uri'], repo['suite']):
errors.append("URL for repository {0} is not accessible."
.format(name))
@ -343,16 +351,16 @@ class BootstrapImage(urwid.WidgetWrap):
# Update self.defaults
self._update_defaults(self.defaults, self.parent.settings)
def check_url(self, url, proxies):
def check_url(self, url):
try:
resp = requests.get(url, proxies=proxies, verify=False)
resp = requests.get(url, verify=False)
except (requests.exceptions.RequestException,
requests.exceptions.BaseHTTPError) as e:
log.error(e)
return False
return resp.ok
def _check_repo(self, base_url, suite, proxies):
def _check_repo(self, base_url, suite):
release_url = '{base_url}/dists/{suite}/Release'.format(
base_url=base_url, suite=suite)
host = urlparse.urlparse(release_url).netloc.split(':')[0]
@ -366,7 +374,7 @@ class BootstrapImage(urwid.WidgetWrap):
'repository: {}'.format(release_url))
return True
return self.check_url(release_url, proxies)
return self.check_url(release_url)
def refresh(self):
pass

View File

@ -0,0 +1,86 @@
# Copyright 2017 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from mock import patch
from requests import adapters
from fuelmenu.modules import bootstrapimg
from fuelmenu.tests import base
class TestBootstrapImg(base.BaseModuleTests):
def setUp(self, responses=None):
super(TestBootstrapImg, self).setUp()
if responses:
self.responses = responses
self.module = bootstrapimg.BootstrapImage(self.parent)
# unset proxy settings before start
os.environ['HTTP_PROXY'] = ''
os.environ['NO_PROXY'] = ''
os.environ['HTTPS_PROXY'] = ''
@patch.object(adapters.HTTPAdapter, 'send')
def test_check_url_without_proxies(self, send_mock):
self.module.check_url('http://some_url')
call_args = send_mock.call_args_list
self.assertEqual(1, len(call_args))
call_args = call_args[0]
args, kwargs = call_args
self.assertIn('proxies', kwargs)
self.assertNotIn('http', kwargs['proxies'])
self.assertNotIn('https', kwargs['proxies'])
@patch.object(adapters.HTTPAdapter, 'send')
def test_check_url_with_proxies(self, send_mock):
http_proxy_url = 'http://http_proxy_url'
https_proxy_url = 'https://https_proxy_url'
os.environ['HTTP_PROXY'] = http_proxy_url
os.environ['HTTPS_PROXY'] = https_proxy_url
self.module.check_url('http://some_url')
call_args = send_mock.call_args_list
self.assertEqual(1, len(call_args))
call_args = call_args[0]
args, kwargs = call_args
self.assertIn('proxies', kwargs)
self.assertIn('http', kwargs['proxies'])
self.assertIn('https', kwargs['proxies'])
self.assertEqual(kwargs['proxies']['http'],
http_proxy_url)
self.assertEqual(kwargs['proxies']['https'],
https_proxy_url)
@patch.object(adapters.HTTPAdapter, 'send')
def test_check_url_with_no_proxy(self, send_mock):
http_proxy_url = 'http://http_proxy_url'
https_proxy_url = 'https://https_proxy_url'
os.environ['HTTP_PROXY'] = http_proxy_url
os.environ['HTTPS_PROXY'] = https_proxy_url
os.environ['NO_PROXY'] = 'direct_url'
self.module.check_url('http://direct_url')
call_args = send_mock.call_args_list
self.assertEqual(1, len(call_args))
call_args = call_args[0]
args, kwargs = call_args
self.assertIn('proxies', kwargs)
self.assertNotIn('http', kwargs['proxies'])
self.assertNotIn('https', kwargs['proxies'])