c36ff1
From 9ccb738cf078555b68122b1fc745a45fe952c439 Mon Sep 17 00:00:00 2001
c36ff1
From: Anh Vo <anhvo@microsoft.com>
c36ff1
Date: Tue, 13 Apr 2021 17:39:39 -0400
c36ff1
Subject: [PATCH 3/7] azure: Removing ability to invoke walinuxagent (#799)
c36ff1
c36ff1
RH-Author: Eduardo Otubo <otubo@redhat.com>
c36ff1
RH-MergeRequest: 18: Add support for userdata on Azure from IMDS
c36ff1
RH-Commit: [3/7] 7431b912e3df7ea384820f45e0230b47ab54643c (otubo/cloud-init-src)
c36ff1
RH-Bugzilla: 2042351
c36ff1
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
c36ff1
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
c36ff1
c36ff1
Invoking walinuxagent from within cloud-init is no longer
c36ff1
supported/necessary
c36ff1
---
c36ff1
 cloudinit/sources/DataSourceAzure.py          | 137 ++++--------------
c36ff1
 doc/rtd/topics/datasources/azure.rst          |  62 ++------
c36ff1
 tests/unittests/test_datasource/test_azure.py |  97 -------------
c36ff1
 3 files changed, 35 insertions(+), 261 deletions(-)
c36ff1
c36ff1
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
c36ff1
index de1452ce..020b7006 100755
c36ff1
--- a/cloudinit/sources/DataSourceAzure.py
c36ff1
+++ b/cloudinit/sources/DataSourceAzure.py
c36ff1
@@ -381,53 +381,6 @@ class DataSourceAzure(sources.DataSource):
c36ff1
                     util.logexc(LOG, "handling set_hostname failed")
c36ff1
         return False
c36ff1
 
c36ff1
-    @azure_ds_telemetry_reporter
c36ff1
-    def get_metadata_from_agent(self):
c36ff1
-        temp_hostname = self.metadata.get('local-hostname')
c36ff1
-        agent_cmd = self.ds_cfg['agent_command']
c36ff1
-        LOG.debug("Getting metadata via agent.  hostname=%s cmd=%s",
c36ff1
-                  temp_hostname, agent_cmd)
c36ff1
-
c36ff1
-        self.bounce_network_with_azure_hostname()
c36ff1
-
c36ff1
-        try:
c36ff1
-            invoke_agent(agent_cmd)
c36ff1
-        except subp.ProcessExecutionError:
c36ff1
-            # claim the datasource even if the command failed
c36ff1
-            util.logexc(LOG, "agent command '%s' failed.",
c36ff1
-                        self.ds_cfg['agent_command'])
c36ff1
-
c36ff1
-        ddir = self.ds_cfg['data_dir']
c36ff1
-
c36ff1
-        fp_files = []
c36ff1
-        key_value = None
c36ff1
-        for pk in self.cfg.get('_pubkeys', []):
c36ff1
-            if pk.get('value', None):
c36ff1
-                key_value = pk['value']
c36ff1
-                LOG.debug("SSH authentication: using value from fabric")
c36ff1
-            else:
c36ff1
-                bname = str(pk['fingerprint'] + ".crt")
c36ff1
-                fp_files += [os.path.join(ddir, bname)]
c36ff1
-                LOG.debug("SSH authentication: "
c36ff1
-                          "using fingerprint from fabric")
c36ff1
-
c36ff1
-        with events.ReportEventStack(
c36ff1
-                name="waiting-for-ssh-public-key",
c36ff1
-                description="wait for agents to retrieve SSH keys",
c36ff1
-                parent=azure_ds_reporter):
c36ff1
-            # wait very long for public SSH keys to arrive
c36ff1
-            # https://bugs.launchpad.net/cloud-init/+bug/1717611
c36ff1
-            missing = util.log_time(logfunc=LOG.debug,
c36ff1
-                                    msg="waiting for SSH public key files",
c36ff1
-                                    func=util.wait_for_files,
c36ff1
-                                    args=(fp_files, 900))
c36ff1
-            if len(missing):
c36ff1
-                LOG.warning("Did not find files, but going on: %s", missing)
c36ff1
-
c36ff1
-        metadata = {}
c36ff1
-        metadata['public-keys'] = key_value or pubkeys_from_crt_files(fp_files)
c36ff1
-        return metadata
c36ff1
-
c36ff1
     def _get_subplatform(self):
c36ff1
         """Return the subplatform metadata source details."""
c36ff1
         if self.seed.startswith('/dev'):
c36ff1
@@ -1354,35 +1307,32 @@ class DataSourceAzure(sources.DataSource):
c36ff1
            On failure, returns False.
c36ff1
         """
c36ff1
 
c36ff1
-        if self.ds_cfg['agent_command'] == AGENT_START_BUILTIN:
c36ff1
-            self.bounce_network_with_azure_hostname()
c36ff1
+        self.bounce_network_with_azure_hostname()
c36ff1
 
c36ff1
-            pubkey_info = None
c36ff1
-            try:
c36ff1
-                raise KeyError(
c36ff1
-                    "Not using public SSH keys from IMDS"
c36ff1
-                )
c36ff1
-                # pylint:disable=unreachable
c36ff1
-                public_keys = self.metadata['imds']['compute']['publicKeys']
c36ff1
-                LOG.debug(
c36ff1
-                    'Successfully retrieved %s key(s) from IMDS',
c36ff1
-                    len(public_keys)
c36ff1
-                    if public_keys is not None
c36ff1
-                    else 0
c36ff1
-                )
c36ff1
-            except KeyError:
c36ff1
-                LOG.debug(
c36ff1
-                    'Unable to retrieve SSH keys from IMDS during '
c36ff1
-                    'negotiation, falling back to OVF'
c36ff1
-                )
c36ff1
-                pubkey_info = self.cfg.get('_pubkeys', None)
c36ff1
-
c36ff1
-            metadata_func = partial(get_metadata_from_fabric,
c36ff1
-                                    fallback_lease_file=self.
c36ff1
-                                    dhclient_lease_file,
c36ff1
-                                    pubkey_info=pubkey_info)
c36ff1
-        else:
c36ff1
-            metadata_func = self.get_metadata_from_agent
c36ff1
+        pubkey_info = None
c36ff1
+        try:
c36ff1
+            raise KeyError(
c36ff1
+                "Not using public SSH keys from IMDS"
c36ff1
+            )
c36ff1
+            # pylint:disable=unreachable
c36ff1
+            public_keys = self.metadata['imds']['compute']['publicKeys']
c36ff1
+            LOG.debug(
c36ff1
+                'Successfully retrieved %s key(s) from IMDS',
c36ff1
+                len(public_keys)
c36ff1
+                if public_keys is not None
c36ff1
+                else 0
c36ff1
+            )
c36ff1
+        except KeyError:
c36ff1
+            LOG.debug(
c36ff1
+                'Unable to retrieve SSH keys from IMDS during '
c36ff1
+                'negotiation, falling back to OVF'
c36ff1
+            )
c36ff1
+            pubkey_info = self.cfg.get('_pubkeys', None)
c36ff1
+
c36ff1
+        metadata_func = partial(get_metadata_from_fabric,
c36ff1
+                                fallback_lease_file=self.
c36ff1
+                                dhclient_lease_file,
c36ff1
+                                pubkey_info=pubkey_info)
c36ff1
 
c36ff1
         LOG.debug("negotiating with fabric via agent command %s",
c36ff1
                   self.ds_cfg['agent_command'])
c36ff1
@@ -1617,33 +1567,6 @@ def perform_hostname_bounce(hostname, cfg, prev_hostname):
c36ff1
     return True
c36ff1
 
c36ff1
 
c36ff1
-@azure_ds_telemetry_reporter
c36ff1
-def crtfile_to_pubkey(fname, data=None):
c36ff1
-    pipeline = ('openssl x509 -noout -pubkey < "$0" |'
c36ff1
-                'ssh-keygen -i -m PKCS8 -f /dev/stdin')
c36ff1
-    (out, _err) = subp.subp(['sh', '-c', pipeline, fname],
c36ff1
-                            capture=True, data=data)
c36ff1
-    return out.rstrip()
c36ff1
-
c36ff1
-
c36ff1
-@azure_ds_telemetry_reporter
c36ff1
-def pubkeys_from_crt_files(flist):
c36ff1
-    pubkeys = []
c36ff1
-    errors = []
c36ff1
-    for fname in flist:
c36ff1
-        try:
c36ff1
-            pubkeys.append(crtfile_to_pubkey(fname))
c36ff1
-        except subp.ProcessExecutionError:
c36ff1
-            errors.append(fname)
c36ff1
-
c36ff1
-    if errors:
c36ff1
-        report_diagnostic_event(
c36ff1
-            "failed to convert the crt files to pubkey: %s" % errors,
c36ff1
-            logger_func=LOG.warning)
c36ff1
-
c36ff1
-    return pubkeys
c36ff1
-
c36ff1
-
c36ff1
 @azure_ds_telemetry_reporter
c36ff1
 def write_files(datadir, files, dirmode=None):
c36ff1
 
c36ff1
@@ -1672,16 +1595,6 @@ def write_files(datadir, files, dirmode=None):
c36ff1
         util.write_file(filename=fname, content=content, mode=0o600)
c36ff1
 
c36ff1
 
c36ff1
-@azure_ds_telemetry_reporter
c36ff1
-def invoke_agent(cmd):
c36ff1
-    # this is a function itself to simplify patching it for test
c36ff1
-    if cmd:
c36ff1
-        LOG.debug("invoking agent: %s", cmd)
c36ff1
-        subp.subp(cmd, shell=(not isinstance(cmd, list)))
c36ff1
-    else:
c36ff1
-        LOG.debug("not invoking agent")
c36ff1
-
c36ff1
-
c36ff1
 def find_child(node, filter_func):
c36ff1
     ret = []
c36ff1
     if not node.hasChildNodes():
c36ff1
diff --git a/doc/rtd/topics/datasources/azure.rst b/doc/rtd/topics/datasources/azure.rst
c36ff1
index e04c3a33..ad9f2236 100644
c36ff1
--- a/doc/rtd/topics/datasources/azure.rst
c36ff1
+++ b/doc/rtd/topics/datasources/azure.rst
c36ff1
@@ -5,28 +5,6 @@ Azure
c36ff1
 
c36ff1
 This datasource finds metadata and user-data from the Azure cloud platform.
c36ff1
 
c36ff1
-walinuxagent
c36ff1
-------------
c36ff1
-walinuxagent has several functions within images.  For cloud-init
c36ff1
-specifically, the relevant functionality it performs is to register the
c36ff1
-instance with the Azure cloud platform at boot so networking will be
c36ff1
-permitted.  For more information about the other functionality of
c36ff1
-walinuxagent, see `Azure's documentation
c36ff1
-<https://github.com/Azure/WALinuxAgent#introduction>`_ for more details.
c36ff1
-(Note, however, that only one of walinuxagent's provisioning and cloud-init
c36ff1
-should be used to perform instance customisation.)
c36ff1
-
c36ff1
-If you are configuring walinuxagent yourself, you will want to ensure that you
c36ff1
-have `Provisioning.UseCloudInit
c36ff1
-<https://github.com/Azure/WALinuxAgent#provisioningusecloudinit>`_ set to
c36ff1
-``y``.
c36ff1
-
c36ff1
-
c36ff1
-Builtin Agent
c36ff1
--------------
c36ff1
-An alternative to using walinuxagent to register to the Azure cloud platform
c36ff1
-is to use the ``__builtin__`` agent command.  This section contains more
c36ff1
-background on what that code path does, and how to enable it.
c36ff1
 
c36ff1
 The Azure cloud platform provides initial data to an instance via an attached
c36ff1
 CD formatted in UDF.  That CD contains a 'ovf-env.xml' file that provides some
c36ff1
@@ -41,16 +19,6 @@ by calling a script in /etc/dhcp/dhclient-exit-hooks or a file in
c36ff1
 'dhclient_hook' of cloud-init itself. This sub-command will write the client
c36ff1
 information in json format to /run/cloud-init/dhclient.hook/<interface>.json.
c36ff1
 
c36ff1
-In order for cloud-init to leverage this method to find the endpoint, the
c36ff1
-cloud.cfg file must contain:
c36ff1
-
c36ff1
-.. sourcecode:: yaml
c36ff1
-
c36ff1
-  datasource:
c36ff1
-    Azure:
c36ff1
-      set_hostname: False
c36ff1
-      agent_command: __builtin__
c36ff1
-
c36ff1
 If those files are not available, the fallback is to check the leases file
c36ff1
 for the endpoint server (again option 245).
c36ff1
 
c36ff1
@@ -83,9 +51,6 @@ configuration (in ``/etc/cloud/cloud.cfg`` or ``/etc/cloud/cloud.cfg.d/``).
c36ff1
 
c36ff1
 The settings that may be configured are:
c36ff1
 
c36ff1
- * **agent_command**: Either __builtin__ (default) or a command to run to getcw
c36ff1
-   metadata. If __builtin__, get metadata from walinuxagent. Otherwise run the
c36ff1
-   provided command to obtain metadata.
c36ff1
  * **apply_network_config**: Boolean set to True to use network configuration
c36ff1
    described by Azure's IMDS endpoint instead of fallback network config of
c36ff1
    dhcp on eth0. Default is True. For Ubuntu 16.04 or earlier, default is
c36ff1
@@ -121,7 +86,6 @@ An example configuration with the default values is provided below:
c36ff1
 
c36ff1
   datasource:
c36ff1
     Azure:
c36ff1
-      agent_command: __builtin__
c36ff1
       apply_network_config: true
c36ff1
       data_dir: /var/lib/waagent
c36ff1
       dhclient_lease_file: /var/lib/dhcp/dhclient.eth0.leases
c36ff1
@@ -144,9 +108,7 @@ child of the ``LinuxProvisioningConfigurationSet`` (a sibling to ``UserName``)
c36ff1
 If both ``UserData`` and ``CustomData`` are provided behavior is undefined on
c36ff1
 which will be selected.
c36ff1
 
c36ff1
-In the example below, user-data provided is 'this is my userdata', and the
c36ff1
-datasource config provided is ``{"agent_command": ["start", "walinuxagent"]}``.
c36ff1
-That agent command will take affect as if it were specified in system config.
c36ff1
+In the example below, user-data provided is 'this is my userdata'
c36ff1
 
c36ff1
 Example:
c36ff1
 
c36ff1
@@ -184,20 +146,16 @@ The hostname is provided to the instance in the ovf-env.xml file as
c36ff1
 Whatever value the instance provides in its dhcp request will resolve in the
c36ff1
 domain returned in the 'search' request.
c36ff1
 
c36ff1
-The interesting issue is that a generic image will already have a hostname
c36ff1
-configured.  The ubuntu cloud images have 'ubuntu' as the hostname of the
c36ff1
-system, and the initial dhcp request on eth0 is not guaranteed to occur after
c36ff1
-the datasource code has been run.  So, on first boot, that initial value will
c36ff1
-be sent in the dhcp request and *that* value will resolve.
c36ff1
-
c36ff1
-In order to make the ``HostName`` provided in the ovf-env.xml resolve, a
c36ff1
-dhcp request must be made with the new value.  Walinuxagent (in its current
c36ff1
-version) handles this by polling the state of hostname and bouncing ('``ifdown
c36ff1
-eth0; ifup eth0``' the network interface if it sees that a change has been
c36ff1
-made.
c36ff1
+A generic image will already have a hostname configured.  The ubuntu
c36ff1
+cloud images have 'ubuntu' as the hostname of the system, and the
c36ff1
+initial dhcp request on eth0 is not guaranteed to occur after the
c36ff1
+datasource code has been run.  So, on first boot, that initial value
c36ff1
+will be sent in the dhcp request and *that* value will resolve.
c36ff1
 
c36ff1
-cloud-init handles this by setting the hostname in the DataSource's 'get_data'
c36ff1
-method via '``hostname $HostName``', and then bouncing the interface.  This
c36ff1
+In order to make the ``HostName`` provided in the ovf-env.xml resolve,
c36ff1
+a dhcp request must be made with the new value. cloud-init handles
c36ff1
+this by setting the hostname in the DataSource's 'get_data' method via
c36ff1
+'``hostname $HostName``', and then bouncing the interface.  This
c36ff1
 behavior can be configured or disabled in the datasource config.  See
c36ff1
 'Configuration' above.
c36ff1
 
c36ff1
diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
c36ff1
index dedebeb1..320fa857 100644
c36ff1
--- a/tests/unittests/test_datasource/test_azure.py
c36ff1
+++ b/tests/unittests/test_datasource/test_azure.py
c36ff1
@@ -638,17 +638,10 @@ scbus-1 on xpt0 bus 0
c36ff1
         def dsdevs():
c36ff1
             return data.get('dsdevs', [])
c36ff1
 
c36ff1
-        def _invoke_agent(cmd):
c36ff1
-            data['agent_invoked'] = cmd
c36ff1
-
c36ff1
         def _wait_for_files(flist, _maxwait=None, _naplen=None):
c36ff1
             data['waited'] = flist
c36ff1
             return []
c36ff1
 
c36ff1
-        def _pubkeys_from_crt_files(flist):
c36ff1
-            data['pubkey_files'] = flist
c36ff1
-            return ["pubkey_from: %s" % f for f in flist]
c36ff1
-
c36ff1
         if data.get('ovfcontent') is not None:
c36ff1
             populate_dir(os.path.join(self.paths.seed_dir, "azure"),
c36ff1
                          {'ovf-env.xml': data['ovfcontent']})
c36ff1
@@ -675,8 +668,6 @@ scbus-1 on xpt0 bus 0
c36ff1
 
c36ff1
         self.apply_patches([
c36ff1
             (dsaz, 'list_possible_azure_ds_devs', dsdevs),
c36ff1
-            (dsaz, 'invoke_agent', _invoke_agent),
c36ff1
-            (dsaz, 'pubkeys_from_crt_files', _pubkeys_from_crt_files),
c36ff1
             (dsaz, 'perform_hostname_bounce', mock.MagicMock()),
c36ff1
             (dsaz, 'get_hostname', mock.MagicMock()),
c36ff1
             (dsaz, 'set_hostname', mock.MagicMock()),
c36ff1
@@ -765,7 +756,6 @@ scbus-1 on xpt0 bus 0
c36ff1
             ret = dsrc.get_data()
c36ff1
             self.m_is_platform_viable.assert_called_with(dsrc.seed_dir)
c36ff1
             self.assertFalse(ret)
c36ff1
-            self.assertNotIn('agent_invoked', data)
c36ff1
             # Assert that for non viable platforms,
c36ff1
             # there is no communication with the Azure datasource.
c36ff1
             self.assertEqual(
c36ff1
@@ -789,7 +779,6 @@ scbus-1 on xpt0 bus 0
c36ff1
             ret = dsrc.get_data()
c36ff1
             self.m_is_platform_viable.assert_called_with(dsrc.seed_dir)
c36ff1
             self.assertFalse(ret)
c36ff1
-            self.assertNotIn('agent_invoked', data)
c36ff1
             self.assertEqual(
c36ff1
                 1,
c36ff1
                 m_report_failure.call_count)
c36ff1
@@ -806,7 +795,6 @@ scbus-1 on xpt0 bus 0
c36ff1
                 1,
c36ff1
                 m_crawl_metadata.call_count)
c36ff1
             self.assertFalse(ret)
c36ff1
-            self.assertNotIn('agent_invoked', data)
c36ff1
 
c36ff1
     def test_crawl_metadata_exception_should_report_failure_with_msg(self):
c36ff1
         data = {}
c36ff1
@@ -1086,21 +1074,6 @@ scbus-1 on xpt0 bus 0
c36ff1
         self.assertTrue(os.path.isdir(self.waagent_d))
c36ff1
         self.assertEqual(stat.S_IMODE(os.stat(self.waagent_d).st_mode), 0o700)
c36ff1
 
c36ff1
-    def test_user_cfg_set_agent_command_plain(self):
c36ff1
-        # set dscfg in via plaintext
c36ff1
-        # we must have friendly-to-xml formatted plaintext in yaml_cfg
c36ff1
-        # not all plaintext is expected to work.
c36ff1
-        yaml_cfg = "{agent_command: my_command}\n"
c36ff1
-        cfg = yaml.safe_load(yaml_cfg)
c36ff1
-        odata = {'HostName': "myhost", 'UserName': "myuser",
c36ff1
-                 'dscfg': {'text': yaml_cfg, 'encoding': 'plain'}}
c36ff1
-        data = {'ovfcontent': construct_valid_ovf_env(data=odata)}
c36ff1
-
c36ff1
-        dsrc = self._get_ds(data)
c36ff1
-        ret = self._get_and_setup(dsrc)
c36ff1
-        self.assertTrue(ret)
c36ff1
-        self.assertEqual(data['agent_invoked'], cfg['agent_command'])
c36ff1
-
c36ff1
     @mock.patch('cloudinit.sources.DataSourceAzure.device_driver',
c36ff1
                 return_value=None)
c36ff1
     def test_network_config_set_from_imds(self, m_driver):
c36ff1
@@ -1205,29 +1178,6 @@ scbus-1 on xpt0 bus 0
c36ff1
         dsrc.get_data()
c36ff1
         self.assertEqual('eastus2', dsrc.region)
c36ff1
 
c36ff1
-    def test_user_cfg_set_agent_command(self):
c36ff1
-        # set dscfg in via base64 encoded yaml
c36ff1
-        cfg = {'agent_command': "my_command"}
c36ff1
-        odata = {'HostName': "myhost", 'UserName': "myuser",
c36ff1
-                 'dscfg': {'text': b64e(yaml.dump(cfg)),
c36ff1
-                           'encoding': 'base64'}}
c36ff1
-        data = {'ovfcontent': construct_valid_ovf_env(data=odata)}
c36ff1
-
c36ff1
-        dsrc = self._get_ds(data)
c36ff1
-        ret = self._get_and_setup(dsrc)
c36ff1
-        self.assertTrue(ret)
c36ff1
-        self.assertEqual(data['agent_invoked'], cfg['agent_command'])
c36ff1
-
c36ff1
-    def test_sys_cfg_set_agent_command(self):
c36ff1
-        sys_cfg = {'datasource': {'Azure': {'agent_command': '_COMMAND'}}}
c36ff1
-        data = {'ovfcontent': construct_valid_ovf_env(data={}),
c36ff1
-                'sys_cfg': sys_cfg}
c36ff1
-
c36ff1
-        dsrc = self._get_ds(data)
c36ff1
-        ret = self._get_and_setup(dsrc)
c36ff1
-        self.assertTrue(ret)
c36ff1
-        self.assertEqual(data['agent_invoked'], '_COMMAND')
c36ff1
-
c36ff1
     def test_sys_cfg_set_never_destroy_ntfs(self):
c36ff1
         sys_cfg = {'datasource': {'Azure': {
c36ff1
             'never_destroy_ntfs': 'user-supplied-value'}}}
c36ff1
@@ -1311,51 +1261,6 @@ scbus-1 on xpt0 bus 0
c36ff1
         self.assertTrue(ret)
c36ff1
         self.assertEqual(dsrc.userdata_raw, mydata.encode('utf-8'))
c36ff1
 
c36ff1
-    def test_cfg_has_pubkeys_fingerprint(self):
c36ff1
-        odata = {'HostName': "myhost", 'UserName': "myuser"}
c36ff1
-        mypklist = [{'fingerprint': 'fp1', 'path': 'path1', 'value': ''}]
c36ff1
-        pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist]
c36ff1
-        data = {'ovfcontent': construct_valid_ovf_env(data=odata,
c36ff1
-                                                      pubkeys=pubkeys)}
c36ff1
-
c36ff1
-        dsrc = self._get_ds(data, agent_command=['not', '__builtin__'])
c36ff1
-        ret = self._get_and_setup(dsrc)
c36ff1
-        self.assertTrue(ret)
c36ff1
-        for mypk in mypklist:
c36ff1
-            self.assertIn(mypk, dsrc.cfg['_pubkeys'])
c36ff1
-            self.assertIn('pubkey_from', dsrc.metadata['public-keys'][-1])
c36ff1
-
c36ff1
-    def test_cfg_has_pubkeys_value(self):
c36ff1
-        # make sure that provided key is used over fingerprint
c36ff1
-        odata = {'HostName': "myhost", 'UserName': "myuser"}
c36ff1
-        mypklist = [{'fingerprint': 'fp1', 'path': 'path1', 'value': 'value1'}]
c36ff1
-        pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist]
c36ff1
-        data = {'ovfcontent': construct_valid_ovf_env(data=odata,
c36ff1
-                                                      pubkeys=pubkeys)}
c36ff1
-
c36ff1
-        dsrc = self._get_ds(data, agent_command=['not', '__builtin__'])
c36ff1
-        ret = self._get_and_setup(dsrc)
c36ff1
-        self.assertTrue(ret)
c36ff1
-
c36ff1
-        for mypk in mypklist:
c36ff1
-            self.assertIn(mypk, dsrc.cfg['_pubkeys'])
c36ff1
-            self.assertIn(mypk['value'], dsrc.metadata['public-keys'])
c36ff1
-
c36ff1
-    def test_cfg_has_no_fingerprint_has_value(self):
c36ff1
-        # test value is used when fingerprint not provided
c36ff1
-        odata = {'HostName': "myhost", 'UserName': "myuser"}
c36ff1
-        mypklist = [{'fingerprint': None, 'path': 'path1', 'value': 'value1'}]
c36ff1
-        pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist]
c36ff1
-        data = {'ovfcontent': construct_valid_ovf_env(data=odata,
c36ff1
-                                                      pubkeys=pubkeys)}
c36ff1
-
c36ff1
-        dsrc = self._get_ds(data, agent_command=['not', '__builtin__'])
c36ff1
-        ret = self._get_and_setup(dsrc)
c36ff1
-        self.assertTrue(ret)
c36ff1
-
c36ff1
-        for mypk in mypklist:
c36ff1
-            self.assertIn(mypk['value'], dsrc.metadata['public-keys'])
c36ff1
-
c36ff1
     def test_default_ephemeral_configs_ephemeral_exists(self):
c36ff1
         # make sure the ephemeral configs are correct if disk present
c36ff1
         odata = {}
c36ff1
@@ -1919,8 +1824,6 @@ class TestAzureBounce(CiTestCase):
c36ff1
     with_logs = True
c36ff1
 
c36ff1
     def mock_out_azure_moving_parts(self):
c36ff1
-        self.patches.enter_context(
c36ff1
-            mock.patch.object(dsaz, 'invoke_agent'))
c36ff1
         self.patches.enter_context(
c36ff1
             mock.patch.object(dsaz.util, 'wait_for_files'))
c36ff1
         self.patches.enter_context(
c36ff1
-- 
c36ff1
2.27.0
c36ff1