Skip to content

Commit

Permalink
Merge branch 'master' into add-registry-sidecar-support
Browse files Browse the repository at this point in the history
  • Loading branch information
jesusbv committed Apr 17, 2024
2 parents 243d380 + faa4594 commit 9d041bb
Show file tree
Hide file tree
Showing 22 changed files with 514 additions and 215 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/ci-testing.yml
@@ -0,0 +1,28 @@
name: CI-Code-Style

on: [push]

jobs:
unit_tests:
name: Linter checks
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.6]

steps:
- uses: actions/checkout@v3
- name: Python${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install Tox
run: |
python -m pip install --upgrade pip
python -m pip install tox
- name: Run code checks
run: |
tox -e check
tox -e "unit_py${PY_VER/./_}" -- -n auto
env:
PY_VER: ${{ matrix.python-version }}
9 changes: 9 additions & 0 deletions .gitignore
@@ -0,0 +1,9 @@
# Distribution / packaging
*.egg-info

# Unit test / coverage reports
.tox/
.coverage
.cache
**/*/__pycache__/
.pytest_cache
15 changes: 15 additions & 0 deletions .virtualenv.dev-requirements.txt
@@ -0,0 +1,15 @@
-r .virtualenv.requirements.txt

# python unit testing framework
pytest
pytest-cov
coverage

# Rolling backport of unittest.mock for all Pythons
mock

# Python style guide checker
flake8

# Version-bump your software with a single command!
bumpversion
4 changes: 4 additions & 0 deletions .virtualenv.requirements.txt
@@ -0,0 +1,4 @@
lxml
requests
dnspython
M2Crypto
5 changes: 4 additions & 1 deletion cloud-regionsrv-client.spec
Expand Up @@ -16,7 +16,7 @@
#


%define base_version 10.1.6
%define base_version 10.1.8
Name: cloud-regionsrv-client
Version: %{base_version}
Release: 0
Expand Down Expand Up @@ -188,6 +188,9 @@ fi
%dir %{_usr}/lib/zypp/plugins/urlresolver
%dir /var/cache/cloudregister
%{_mandir}/man*/*
# Do not expect the user that needs containers to have root access
# on the system
%{_bindir}/cloudguestregistryauth
%{_sbindir}/cloudguest-repo-service
%{_sbindir}/containerbuild-regionsrv
%{_sbindir}/createregioninfo
Expand Down
3 changes: 2 additions & 1 deletion etc/regionserverclnt.cfg
@@ -1,12 +1,13 @@
[server]
api = regionInfo
certLocation = /var/lib/regionService/certs
certLocation = /usr/lib/regionService/certs
regionsrv = COMMA_SEP_LIST_OF_CLOUD_SPECIFIC_REGION_SERVER
metadata_server = OPTIONAL_URL_FOR_METADATA_SERVER_SMT_INFO

[instance]
dataProvider = none
instanceArgs = none
httpsOnly = true

[service]
verifyAccess = none
Expand Down
13 changes: 10 additions & 3 deletions integration_test-process.txt
Expand Up @@ -35,6 +35,13 @@ After installing the test package with "zypper in"
+ success message on stdout
+ $? is 0
+ zypper lr has repos
- Update server failover
+ ip=`grep susecloud.net /etc/hosts | cut -f1`
+ iptables -A OUTPUT -d $ip -j DROP
+ zypper ref
+ grep -i equivalent /var/log/cloudregister
+ grep susecloud.net /etc/hosts
+ IP addresses in the last two outputs should match

byos - test on SLES4SAP instance
After installing the test package with "zypper in"
Expand All @@ -57,9 +64,9 @@ After installing the test package with "zypper in"
+ no error no message
+ zypper lr has no repos
- SUSEConnect -r XXX
+ registartion successful
+ registration successful
- SUSEConnect -p sle-module-public-cloud/$VERSION/x86_64
+ registartion successful
+ registration successful
- SUSEConnect -d -p sle-module-public-cloud/$VERSION/x86_64
+ module deletion successful
+ Requires SUSEConnect > 0.3.32
Expand All @@ -79,7 +86,7 @@ After installing the test package with "zypper in"
+ $? is 0
+ repos include HA
- SUSEConnect -p sle-module-public-cloud/$VERSION/x86_64
+ registartion successful
+ registration successful
+ Cloud based RMT server is the target
- registercloudguest --clean

Expand Down
2 changes: 1 addition & 1 deletion lib/cloudregister/VERSION
@@ -1 +1 @@
10.1.6
10.1.8
11 changes: 5 additions & 6 deletions lib/cloudregister/amazonec2.py
Expand Up @@ -32,18 +32,18 @@ def generateRegionSrvArgs():
for imds_ip in imds_ips:
imds_addr = imds_ip
if ':' in imds_ip:
imds_addr = '[%s]' %imds_ip
imds_addr = '[%s]' % imds_ip
try:
token_resp = requests.put(
token_url %imds_addr,
token_url % imds_addr,
headers=token_header
)
if token_resp.status_code == 200:
zone_req_header = {'X-aws-ec2-metadata-token': token_resp.text}
else:
continue
except requests.exceptions.RequestException:
msg = 'Unable to retrieve IMDSv2 token using %s' %imds_ip
msg = 'Unable to retrieve IMDSv2 token using %s' % imds_ip
logging.info(msg)
continue
break
Expand All @@ -58,8 +58,8 @@ def generateRegionSrvArgs():
for imds_ip in imds_ips:
imds_addr = imds_ip
if ':' in imds_ip and '[' not in imds_ip:
imds_addr = '[%s]' %imds_ip
metadata_url = 'http://%s/latest/meta-data/' %imds_addr
imds_addr = '[%s]' % imds_ip
metadata_url = 'http://%s/latest/meta-data/' % imds_addr
zone_info = 'placement/availability-zone'

try:
Expand Down Expand Up @@ -104,6 +104,5 @@ def generateRegionSrvArgs():
logging.warning('\tMessage: %s' % zone_resp.text)
if imds_ip == imds_ips[-1]:
return
continue

return 'regionHint=' + region
24 changes: 18 additions & 6 deletions lib/cloudregister/registerutils.py
Expand Up @@ -461,7 +461,10 @@ def get_available_smt_servers():
if not os.path.exists(get_state_dir()):
return available_smt_servers
smt_data_files = glob.glob(
os.path.join(get_state_dir(), AVAILABLE_SMT_SERVER_DATA_FILE_NAME % '*')
os.path.join(
get_state_dir(),
AVAILABLE_SMT_SERVER_DATA_FILE_NAME % '*'
)
)
for smt_data in smt_data_files:
available_smt_servers.append(get_smt_from_store(smt_data))
Expand Down Expand Up @@ -564,6 +567,14 @@ def set_registry_order_search(registry_fqdn):
_set_registry_order_search_docker(registry_fqdn)


def refresh_registry_credentials():
"""Refresh registry credentials."""
# to silence InsecureRequestWarning
# should be fixed on a different PR
requests.packages.urllib3.disable_warnings()
return get_activations()


# ----------------------------------------------------------------------------
def get_credentials_file(update_server, service_name=None):
"""Return the credentials filename.
Expand Down Expand Up @@ -617,9 +628,9 @@ def get_current_smt():
smt_ipv6 = smt.get_ipv6()
smt_fqdn = smt.get_FQDN()
# A bit cumbersome to support Python 3.4
ipv4_search = '%s\s' % smt_ipv4
ipv6_search = '%s\s' % smt_ipv6
fqdn_search = '\s%s\s' % smt_fqdn
ipv4_search = r'%s\s' % smt_ipv4
ipv6_search = r'%s\s' % smt_ipv6
fqdn_search = r'\s%s\s' % smt_fqdn
with open(HOSTSFILE_PATH, 'rb') as hosts_file:
hosts = hosts_file.read()
if (
Expand Down Expand Up @@ -808,6 +819,7 @@ def get_smt(cache_refreshed=None):
# Fetch cert for new target server
import_smt_cert(new_target)
# Verify the new target server has our credentials
replace_hosts_entry(current_smt, new_target)
credentials_file_path = get_credentials_file(new_target)
user, password = get_credentials(credentials_file_path)
if not has_smt_access(
Expand All @@ -824,8 +836,8 @@ def get_smt(cache_refreshed=None):
msg += 'current, %s, target update server.'
msg += 'Try again later.'
logging.error(msg % (new_target_ips, original_smt_ips))
replace_hosts_entry(new_target, current_smt)
return current_smt
replace_hosts_entry(current_smt, new_target)
set_as_current_smt(new_target)
return new_target
else:
Expand Down Expand Up @@ -992,7 +1004,7 @@ def has_region_changed(cfg):
registered_region = json.loads(
framework_file.read()
)
except:
except Exception:
return False

if (
Expand Down
6 changes: 3 additions & 3 deletions lib/cloudregister/smt.py
Expand Up @@ -211,7 +211,7 @@ def write_cert(self, target_dir):
# we write here with the known pattern.
for cert_name in certs_to_write:
try:
with open(ca_file_path %cert_name, 'w') as smt_ca_file:
with open(ca_file_path % cert_name, 'w') as smt_ca_file:
smt_ca_file.write(cert)
except IOError:
errMsg = 'Could not store update server certificate'
Expand All @@ -232,8 +232,8 @@ def _form_srv_check_urls(self):
rmt_ip = srv_ip
# Per rfc3986 IPv6 addresses in a URI are enclosed in []
if isinstance(ipaddress.ip_address(rmt_ip), ipaddress.IPv6Address):
rmt_ip = '[%s]' %srv_ip
health_url = 'https://%s/api/health/status' %rmt_ip
rmt_ip = '[%s]' % srv_ip
health_url = 'https://%s/api/health/status' % rmt_ip
cert_url = '%s://%s/' % (self._protocol, rmt_ip)
check_urls[health_url] = cert_url

Expand Down
12 changes: 12 additions & 0 deletions man/man1/cloudguestregistryauth.1
@@ -0,0 +1,12 @@
.\" Process this file with
.\" groff -man -Tascii cloudguestregstryauth.1
.\"
.TH cloudguestregstryauth.1
.SH NAME
cloudguestregstryauth \- Refresh registry credentials for a registered SUSE Linux Enterprise instance
.SH SYNOPSIS
.B cloudguestregstryauth
.SH DESCRIPTION
.B cloudguestregstryauth
Refresh registry credentials for a registered SUSE Linux Enterprise instance. The client will reach
out to the already configured update server to refresh the existing credentials.
2 changes: 1 addition & 1 deletion tests/data/regionserverclnt.cfg
@@ -1,5 +1,5 @@
[server]
api = regionInfo
certLocation = /var/lib/regionService/certs
certLocation = /usr/lib/regionService/certs
regionsrv = COMMA_SEP_LIST_OF_CLOUD_SPECIFIC_REGION_SERVER
metadata_server = OPTIONAL_URL_FOR_METADATA_SERVER_SMT_INFO
2 changes: 1 addition & 1 deletion tests/test_azureplugin.py
Expand Up @@ -24,7 +24,7 @@

sys.path.insert(0, code_path)

import msftazure as azure
import msftazure as azure # noqa


# ----------------------------------------------------------------------------
Expand Down
90 changes: 90 additions & 0 deletions tests/test_cloudguestregistryauth.py
@@ -0,0 +1,90 @@
import inspect
import os
import sys

from lxml import etree

from cloudregister.smt import SMT
from importlib.machinery import SourceFileLoader

from pytest import raises
from textwrap import dedent
from unittest.mock import patch

test_path = os.path.abspath(
os.path.dirname(inspect.getfile(inspect.currentframe())))
code_path = os.path.abspath('%s/../lib' % test_path)
data_path = test_path + os.sep + 'data/'

sys.path.insert(0, code_path)

# Hack to get the script without the .py imported for testing
cloudguestregistryauth = SourceFileLoader(
'cloudguestregistryauth',
'./usr/bin/cloudguestregistryauth'
).load_module()


@patch('cloudguestregistryauth.os.geteuid')
def test_registry_call_as_root(mock_os_geteuid):
mock_os_geteuid.return_value = 1
with raises(SystemExit) as pytest_wrapped_e:
cloudguestregistryauth.main()

assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 'You must be root'


@patch('cloudregister.registerutils.get_activations')
@patch('cloudregister.registerutils.is_registered')
@patch('cloudregister.registerutils.get_current_smt')
@patch('cloudguestregistryauth.os.geteuid')
def test_registry_get_activations_error(
mock_os_geteuid, mock_get_current_smt,
mock_is_registered, mock_get_activations
):
mock_os_geteuid.return_value = 0
mock_is_registered.return_value = True
smt_data_ipv46 = dedent('''\
<smtInfo fingerprint="00:11:22:33"
SMTserverIP="192.168.1.1"
SMTserverIPv6="fc00::1"
SMTserverName="fantasy.example.com"
SMTregistryName="registry-fantasy.example.com"
region="antarctica-1"/>''')
smt_server = SMT(etree.fromstring(smt_data_ipv46))
mock_get_current_smt.return_value = smt_server
mock_get_activations.return_value = {}

with raises(SystemExit) as pytest_wrapped_e:
cloudguestregistryauth.main()

assert pytest_wrapped_e.type == SystemExit
assert pytest_wrapped_e.value.code == 'Could not refresh credentials'


@patch('builtins.print')
@patch('cloudregister.registerutils.get_activations')
@patch('cloudregister.registerutils.is_registered')
@patch('cloudregister.registerutils.get_current_smt')
@patch('cloudguestregistryauth.os.geteuid')
def test_registry_get_activations(
mock_os_geteuid, mock_get_current_smt,
mock_is_registered, mock_get_activations,
mock_print
):
mock_os_geteuid.return_value = 0
mock_is_registered.return_value = True
smt_data_ipv46 = dedent('''\
<smtInfo fingerprint="00:11:22:33"
SMTserverIP="192.168.1.1"
SMTserverIPv6="fc00::1"
SMTserverName="fantasy.example.com"
SMTregistryName="registry-fantasy.example.com"
region="antarctica-1"/>''')
smt_server = SMT(etree.fromstring(smt_data_ipv46))
mock_get_current_smt.return_value = smt_server
mock_get_activations.return_value = {'foo': 'bar'}

cloudguestregistryauth.main()
mock_print.assert_called_once_with('Credentials refreshed')

0 comments on commit 9d041bb

Please sign in to comment.