def setUp(self):
        self.temp_dir = tempfile.mkdtemp(
            prefix='subman-container-plugin-tests')
        self.src_certs_dir = join(self.temp_dir, "etc/pki/entitlement")
        os.makedirs(self.src_certs_dir)

        # This is where we'll setup for container certs:
        container_dir = join(self.temp_dir, "etc/docker/certs.d/")
        os.makedirs(container_dir)

        # Where we expect our certs to actually land:
        self.dest_dir = join(container_dir, 'cdn.redhat.com')
        self.report = ContainerUpdateReport()
        self.container_dir = ContainerCertDir(self.report,
                                              'cdn.redhat.com',
                                              host_cert_dir=container_dir)
        self.container_dir._rh_cdn_ca_exists = mock.Mock(return_value=True)
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp(prefix='subman-container-plugin-tests')
        self.src_certs_dir = join(self.temp_dir, "etc/pki/entitlement")
        os.makedirs(self.src_certs_dir)

        # This is where we'll setup for container certs:
        container_dir = join(self.temp_dir,
            "etc/docker/certs.d/")
        os.makedirs(container_dir)

        # Where we expect our certs to actually land:
        self.dest_dir = join(container_dir, 'cdn.redhat.com')
        self.report = ContainerUpdateReport()
        self.container_dir = ContainerCertDir(self.report, 'cdn.redhat.com',
            host_cert_dir=container_dir)
        self.container_dir._rh_cdn_ca_exists = mock.Mock(return_value=True)
class TestContainerCertDir(fixture.SubManFixture):

    def setUp(self):
        self.temp_dir = tempfile.mkdtemp(prefix='subman-container-plugin-tests')
        self.src_certs_dir = join(self.temp_dir, "etc/pki/entitlement")
        os.makedirs(self.src_certs_dir)

        # This is where we'll setup for container certs:
        container_dir = join(self.temp_dir,
            "etc/docker/certs.d/")
        os.makedirs(container_dir)

        # Where we expect our certs to actually land:
        self.dest_dir = join(container_dir, 'cdn.redhat.com')
        self.report = ContainerUpdateReport()
        self.container_dir = ContainerCertDir(self.report, 'cdn.redhat.com',
            host_cert_dir=container_dir)
        self.container_dir._rh_cdn_ca_exists = mock.Mock(return_value=True)

    def tearDown(self):
        shutil.rmtree(self.temp_dir)

    def _touch(self, dir_path, filename):
        """
        Create an empty file in the given directory with the given filename.
        """
        if not exists(dir_path):
            os.makedirs(dir_path)
        open(join(dir_path, filename), 'a').close()

    def test_first_install(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
            join(self.src_certs_dir, key1))
        self.container_dir.sync([kp])
        self.assertTrue(exists(join(self.dest_dir, '1234.cert')))
        self.assertTrue(exists(join(self.dest_dir, '1234.key')))
        self.assertEquals(2, len(self.report.added))

    def test_old_certs_cleaned_out(self):
        cert1 = '1234.cert'
        key1 = '1234.key'
        ca = 'myca.crt'  # This file extension should be left alone:
        self._touch(self.dest_dir, cert1)
        self._touch(self.dest_dir, key1)
        self._touch(self.dest_dir, ca)
        self.assertTrue(exists(join(self.dest_dir, '1234.cert')))
        self.assertTrue(exists(join(self.dest_dir, '1234.key')))
        self.assertTrue(exists(join(self.dest_dir, ca)))
        self.container_dir.sync([])
        self.assertFalse(exists(join(self.dest_dir, '1234.cert')))
        self.assertFalse(exists(join(self.dest_dir, '1234.key')))
        self.assertTrue(exists(join(self.dest_dir, ca)))
        self.assertEquals(2, len(self.report.removed))

    def test_all_together_now(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        cert2 = '12345.pem'
        key2 = '12345-key.pem'
        old_cert = '444.cert'
        old_key = '444.key'
        old_key2 = 'another.key'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        self._touch(self.src_certs_dir, cert2)
        self._touch(self.src_certs_dir, key2)
        self._touch(self.dest_dir, old_cert)
        self._touch(self.dest_dir, old_key)
        self._touch(self.dest_dir, old_key2)
        kp = KeyPair(join(self.src_certs_dir, cert1),
            join(self.src_certs_dir, key1))
        kp2 = KeyPair(join(self.src_certs_dir, cert2),
            join(self.src_certs_dir, key2))
        self.container_dir.sync([kp, kp2])
        self.assertTrue(exists(join(self.dest_dir, '1234.cert')))
        self.assertTrue(exists(join(self.dest_dir, '1234.key')))
        self.assertTrue(exists(join(self.dest_dir, '12345.cert')))
        self.assertTrue(exists(join(self.dest_dir, '12345.key')))

        self.assertFalse(exists(join(self.dest_dir, '444.cert')))
        self.assertFalse(exists(join(self.dest_dir, '444.key')))
        self.assertEquals(4, len(self.report.added))
        self.assertEquals(3, len(self.report.removed))

    @mock.patch("os.symlink")
    def test_cdn_ca_symlink(self, mock_link):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
            join(self.src_certs_dir, key1))
        self.container_dir.sync([kp])

        expected_symlink = join(self.dest_dir, "%s.crt" % os.path.splitext(CA_NAME)[0])
        mock_link.assert_called_once_with(RH_CDN_CA, expected_symlink)

    def test_cdn_ca_doesnt_exist_no_symlink(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
            join(self.src_certs_dir, key1))
        # Mock that /etc/rhsm/ca/redhat-entitlement-authority.pem doesn't exist:
        self.container_dir._rh_cdn_ca_exists = mock.Mock(return_value=False)
        self.container_dir.sync([kp])

        expected_symlink = join(self.dest_dir, "%s.crt" % os.path.splitext(CA_NAME)[0])
        self.assertFalse(exists(expected_symlink))

    def test_cdn_ca_symlink_already_exists(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
            join(self.src_certs_dir, key1))
        self.container_dir.sync([kp])

        expected_symlink = join(self.dest_dir, "%s.crt" % os.path.splitext(CA_NAME)[0])

        # Run it again, the symlink already exists:
        with mock.patch("os.symlink") as mock_link:
            with mock.patch("os.path.exists") as mock_exists:
                # Make the real os.path.exists call unless the module is asking
                # about the symlink which should already exist in this test
                def side_effects(path):
                    if path == expected_symlink:
                        return True
                    return os.path.exists(path)
                mock_exists.side_effects = side_effects
                self.container_dir.sync([kp])
                self.assertFalse(mock_link.called)
class TestContainerCertDir(fixture.SubManFixture):
    def setUp(self):
        self.temp_dir = tempfile.mkdtemp(
            prefix='subman-container-plugin-tests')
        self.src_certs_dir = join(self.temp_dir, "etc/pki/entitlement")
        os.makedirs(self.src_certs_dir)

        # This is where we'll setup for container certs:
        container_dir = join(self.temp_dir, "etc/docker/certs.d/")
        os.makedirs(container_dir)

        # Where we expect our certs to actually land:
        self.dest_dir = join(container_dir, 'cdn.redhat.com')
        self.report = ContainerUpdateReport()
        self.container_dir = ContainerCertDir(self.report,
                                              'cdn.redhat.com',
                                              host_cert_dir=container_dir)
        self.container_dir._rh_cdn_ca_exists = mock.Mock(return_value=True)

    def tearDown(self):
        shutil.rmtree(self.temp_dir)

    def _touch(self, dir_path, filename):
        """
        Create an empty file in the given directory with the given filename.
        """
        if not exists(dir_path):
            os.makedirs(dir_path)
        open(join(dir_path, filename), 'a').close()

    def test_first_install(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
                     join(self.src_certs_dir, key1))
        self.container_dir.sync([kp])
        self.assertTrue(exists(join(self.dest_dir, '1234.cert')))
        self.assertTrue(exists(join(self.dest_dir, '1234.key')))
        self.assertEqual(2, len(self.report.added))

    def test_old_certs_cleaned_out(self):
        cert1 = '1234.cert'
        key1 = '1234.key'
        ca = 'myca.crt'  # This file extension should be left alone:
        self._touch(self.dest_dir, cert1)
        self._touch(self.dest_dir, key1)
        self._touch(self.dest_dir, ca)
        self.assertTrue(exists(join(self.dest_dir, '1234.cert')))
        self.assertTrue(exists(join(self.dest_dir, '1234.key')))
        self.assertTrue(exists(join(self.dest_dir, ca)))
        self.container_dir.sync([])
        self.assertFalse(exists(join(self.dest_dir, '1234.cert')))
        self.assertFalse(exists(join(self.dest_dir, '1234.key')))
        self.assertTrue(exists(join(self.dest_dir, ca)))
        self.assertEqual(2, len(self.report.removed))

    def test_all_together_now(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        cert2 = '12345.pem'
        key2 = '12345-key.pem'
        old_cert = '444.cert'
        old_key = '444.key'
        old_key2 = 'another.key'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        self._touch(self.src_certs_dir, cert2)
        self._touch(self.src_certs_dir, key2)
        self._touch(self.dest_dir, old_cert)
        self._touch(self.dest_dir, old_key)
        self._touch(self.dest_dir, old_key2)
        kp = KeyPair(join(self.src_certs_dir, cert1),
                     join(self.src_certs_dir, key1))
        kp2 = KeyPair(join(self.src_certs_dir, cert2),
                      join(self.src_certs_dir, key2))
        self.container_dir.sync([kp, kp2])
        self.assertTrue(exists(join(self.dest_dir, '1234.cert')))
        self.assertTrue(exists(join(self.dest_dir, '1234.key')))
        self.assertTrue(exists(join(self.dest_dir, '12345.cert')))
        self.assertTrue(exists(join(self.dest_dir, '12345.key')))

        self.assertFalse(exists(join(self.dest_dir, '444.cert')))
        self.assertFalse(exists(join(self.dest_dir, '444.key')))
        self.assertEqual(4, len(self.report.added))
        self.assertEqual(3, len(self.report.removed))

    @mock.patch("os.symlink")
    def test_cdn_ca_symlink(self, mock_link):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
                     join(self.src_certs_dir, key1))
        self.container_dir.sync([kp])

        expected_symlink = join(self.dest_dir,
                                "%s.crt" % os.path.splitext(CA_NAME)[0])
        mock_link.assert_called_once_with(RH_CDN_CA, expected_symlink)

    def test_cdn_ca_doesnt_exist_no_symlink(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
                     join(self.src_certs_dir, key1))
        # Mock that /etc/rhsm/ca/redhat-entitlement-authority.pem doesn't exist:
        self.container_dir._rh_cdn_ca_exists = mock.Mock(return_value=False)
        self.container_dir.sync([kp])

        expected_symlink = join(self.dest_dir,
                                "%s.crt" % os.path.splitext(CA_NAME)[0])
        self.assertFalse(exists(expected_symlink))

    def test_cdn_ca_symlink_already_exists(self):
        cert1 = '1234.pem'
        key1 = '1234-key.pem'
        self._touch(self.src_certs_dir, cert1)
        self._touch(self.src_certs_dir, key1)
        kp = KeyPair(join(self.src_certs_dir, cert1),
                     join(self.src_certs_dir, key1))
        self.container_dir.sync([kp])

        expected_symlink = join(self.dest_dir,
                                "%s.crt" % os.path.splitext(CA_NAME)[0])

        # Run it again, the symlink already exists:
        with mock.patch("os.symlink") as mock_link:
            with mock.patch("os.path.exists") as mock_exists:
                # Make the real os.path.exists call unless the module is asking
                # about the symlink which should already exist in this test
                def side_effects(path):
                    if path == expected_symlink:
                        return True
                    return os.path.exists(path)

                mock_exists.side_effects = side_effects
                self.container_dir.sync([kp])
                self.assertFalse(mock_link.called)