Alessandro Pilotti 1ff2cb912e Adds KMS and AVMA licensing automation
Improves the licensing plugin by adding support for KMS and AVMA
automated product key assignment and KMS host settings.

Change-Id: I361391172a5b857c64c074c7d816322cde13d38c
Co-Authored-By: Stefan Caraiman <scaraiman@cloudbasesolutions.com>
Implements: blueprint improve-licensing-plugin
2017-02-22 09:39:42 +02:00

158 lines
6.6 KiB
Python

# Copyright 2014 Cloudbase Solutions Srl
#
# 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 importlib
import unittest
try:
import unittest.mock as mock
except ImportError:
import mock
from cloudbaseinit.plugins.common import base
from cloudbaseinit.tests import testutils
MODPATH = "cloudbaseinit.plugins.windows.licensing"
class WindowsLicensingPluginTests(unittest.TestCase):
def setUp(self):
self._wmi_mock = mock.MagicMock()
self._module_patcher = mock.patch.dict(
'sys.modules', {
'wmi': self._wmi_mock})
self.snatcher = testutils.LogSnatcher(MODPATH)
self._module_patcher.start()
licensing = importlib.import_module(MODPATH)
self._licensing = licensing.WindowsLicensingPlugin()
def tearDown(self):
self._module_patcher.stop()
@testutils.ConfPatcher('set_kms_product_key', True)
@testutils.ConfPatcher('set_avma_product_key', True)
def _test_set_product_key(self, description=None,
license_family=None, is_current=None):
mock_service = mock.Mock()
mock_manager = mock.Mock()
fake_key = mock.sentinel.key
mock_service.get_use_avma_licensing.return_value = None
mock_manager.get_kms_product.return_value = (description,
license_family,
is_current)
mock_manager.get_volume_activation_product_key.return_value = fake_key
with self.snatcher:
self._licensing._set_product_key(mock_service, mock_manager)
mock_manager.get_kms_product.assert_called_once_with()
if is_current:
expected_logs = ['Product "%s" is already the current one, '
'no need to set a product key' % description]
self.assertEqual(self.snatcher.output, expected_logs)
return
else:
mock_service.get_use_avma_licensing.assert_called_once_with()
(mock_manager.get_volume_activation_product_key.
assert_called_once_with(None, 'AVMA'))
mock_manager.set_product_key.assert_called_once_with(fake_key)
def test_set_product_key(self):
self._test_set_product_key()
def test_set_product_key_is_current(self):
self._test_set_product_key(is_current=True)
def test_set_kms_host(self):
mock_service = mock.Mock()
mock_manager = mock.Mock()
mock_host = "127.0.0.1:1688"
expected_host_call = mock_host.split(':')
mock_service.get_kms_host.return_value = mock_host
expected_logs = ["Setting KMS host: %s" % mock_host]
with self.snatcher:
self._licensing._set_kms_host(mock_service, mock_manager)
self.assertEqual(self.snatcher.output, expected_logs)
mock_manager.set_kms_host.assert_called_once_with(*expected_host_call)
def test_activate_windows(self):
activate_result = mock.Mock()
mock_service = mock.Mock()
mock_manager = mock.Mock()
mock_manager.activate_windows.return_value = activate_result
expected_logs = [
"Activating Windows",
"Activation result:\n%s" % activate_result]
with testutils.ConfPatcher('activate_windows', True):
with self.snatcher:
self._licensing._activate_windows(mock_service, mock_manager)
self.assertEqual(self.snatcher.output, expected_logs)
mock_manager.activate_windows.assert_called_once_with()
@mock.patch(MODPATH + ".WindowsLicensingPlugin._activate_windows")
@mock.patch(MODPATH + ".WindowsLicensingPlugin._set_kms_host")
@mock.patch(MODPATH + ".WindowsLicensingPlugin._set_product_key")
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')
@mock.patch('cloudbaseinit.utils.windows.licensing.get_licensing_manager')
def _test_execute(self, mock_get_licensing_manager,
mock_get_os_utils,
mock_set_product_key,
mock_set_kms_host,
mock_activate_windows,
nano=False, is_eval=True):
mock_service = mock.Mock()
mock_manager = mock.Mock()
mock_get_licensing_manager.return_value = mock_manager
mock_osutils = mock.MagicMock()
mock_osutils.is_nano_server.return_value = nano
mock_get_os_utils.return_value = mock_osutils
mock_manager.is_eval.return_value = is_eval
mock_manager.get_licensing_info.return_value = "fake"
expected_logs = []
with self.snatcher:
response = self._licensing.execute(service=mock_service,
shared_data=None)
mock_get_os_utils.assert_called_once_with()
if nano:
expected_logs = ["Licensing info and activation are "
"not available on Nano Server"]
self.assertEqual(self.snatcher.output, expected_logs)
return # no activation available
else:
if not is_eval:
mock_set_product_key.assert_called_once_with(mock_service,
mock_manager)
mock_set_kms_host.assert_called_once_with(mock_service,
mock_manager)
mock_activate_windows.assert_called_once_with(mock_service,
mock_manager)
else:
expected_logs.append("Evaluation license, skipping activation"
". Evaluation end date: %s" % is_eval)
expected_logs.append('Microsoft Windows license info:\nfake')
mock_manager.get_licensing_info.assert_called_once_with()
self.assertEqual((base.PLUGIN_EXECUTION_DONE, False), response)
self.assertEqual(self.snatcher.output, expected_logs)
def test_execute_nano(self):
self._test_execute(nano=True)
def test_execute_is_evaluated(self):
self._test_execute()
def test_execute(self):
self._test_execute(is_eval=False)