def test_docker_pull_config_secret(): pull_config_str = '{"auths":{"example.com":{"username":"******","password":"******",'\ '"email":"*****@*****.**","auth":"f00BA7"}}}' migrated_dcos_secret = V1Secret( kind='Secret', api_version='v1', metadata=V1ObjectMeta(name='nothing-depends-on-this-name'), data={'nothing-depends-on-the-name-of-this-key': pull_config_str}) input_manifest_list = ManifestList() input_manifest_list.append( Manifest(pluginName="secret", manifestName="foo.docker-c_nfig", data=[migrated_dcos_secret])) app = { "id": "/foo/barify", "container": { "docker": { "pullConfig": { "secret": "pull-config" } } }, "env": { "BAR": { "secret": "pull-config" } }, # See the NOTE below "secrets": { "pull-config": { "source": "/foo/docker-c@nfig" }, "unused": { "source": "unused" }, }, } migrator = MarathonMigrator(object=app, manifest_list=input_manifest_list) manifest = migrator.migrate() # NOTE: Thit test expects that two secrets will be created: # one for the image pull config and another for everything else. # This might be not the optimal migration startegy. [deployment] = [m for m in manifest if isinstance(m, V1Deployment)] [pull_secret] = [m for m in manifest \ if isinstance(m, V1Secret) and m.type == "kubernetes.io/dockerconfigjson"] [generic_secret] = [m for m in manifest \ if isinstance(m, V1Secret) and m.type != "kubernetes.io/dockerconfigjson"] assert deployment.spec.template.spec.image_pull_secrets[ 0].name == pull_secret.metadata.name assert pull_secret.data[".dockerconfigjson"] == pull_config_str assert generic_secret.data["foo.docker-c_nfig"] == pull_config_str
def migrate(self, backupList: BackupList, manifestList: ManifestList, **kwargs: Any) -> ManifestList: ml = ManifestList() for ba in backupList.backups(pluginName='secret'): assert isinstance(ba, Backup) metadata = V1ObjectMeta() metadata.annotations = {} clusterMeta = manifestList.clusterMeta() if clusterMeta: metadata.annotations = clusterMeta.annotations logging.debug("Found backup {}".format(ba)) b = ba.data fullPath = "/".join(filter(None, [b["path"], b["key"]])) name = b["key"] metadata.annotations[utils.namespace_path( "secret-path")] = fullPath metadata.name = utils.make_subdomain(name.split('/')) sec = V1Secret(metadata=metadata) sec.api_version = 'v1' sec.kind = 'Secret' # K8s requires secret values to be base64-encoded. The secret value # is base64-encoded during backup so it can be passed as-is here. sec.data = {utils.dnsify(name): b['value']} manifest = Manifest(pluginName=self.plugin_name, manifestName=utils.dnsify(fullPath)) manifest.append(sec) ml.append(manifest) return ml
def migrate(self, backupList: BackupList, manifestList: ManifestList, **kwargs: Any) -> ManifestList: node_label_tracker = NodeLabelTracker() ml = ManifestList() for b in backupList.backups(pluginName=self.plugin_name): mig = MarathonMigrator(node_label_tracker=node_label_tracker, backup=b, backup_list=backupList, manifest_list=manifestList) try: manifest = mig.migrate() if manifest: ml.append(manifest) except Exception as e: logging.warning("Cannot migrate: {}".format(e)) app_node_labels = node_label_tracker.get_apps_by_label() if app_node_labels: logging.info( 'Node labels used by deployments generated from Marathon apps:\n{}\n' 'Please make sure that these labels are properly set on nodes\nof the' ' target Kubernetes cluster!'.format( json.dumps(list(app_node_labels)))) return ml
def create_example_list_manifest(dir: str) -> ManifestList: list = ManifestList(path=str(dir)) p = "testPlugin" b = "foobar" metadata = V1ObjectMeta(name="secret1") sec = V1Secret(metadata=metadata, kind="Secret", api_version="v1") sec.data = {"secret1": "Zm9vYmFy"} d = [sec] list.append(Manifest(pluginName=p, manifestName=b, data=d)) list.store() return list, p, b, d
def migrate(self, backupList: BackupList, manifestList: ManifestList, **kwargs: T.Any) -> ManifestList: ml = ManifestList() for b in backupList.backups(pluginName=self.plugin_name): mig = MetronomeMigrator(backup=b, backup_list=backupList, manifest_list=manifestList) manifest = mig.migrate() if manifest: ml.append(manifest) return ml
def migrate(self, backupList: BackupList, manifestList: ManifestList, **kwargs: Any) -> ManifestList: ml = ManifestList() clusterBackup = backupList.backup(pluginName=self.plugin_name, backupName='default') if not clusterBackup: logging.critical( "Cluster backup not found. Cannot provide DC/OS annotations") return ml metadata = V1ObjectMeta( name="dcos-{}".format(clusterBackup.data['CLUSTER_ID'])) metadata.annotations = { utils.namespace_path("cluster-id"): clusterBackup.data['CLUSTER_ID'], utils.namespace_path("cluster-name"): clusterBackup.data['CLUSTER'], utils.namespace_path("backup-date"): clusterBackup.data['BACKUP_DATE'], } cfgmap = V1ConfigMap(metadata=metadata) # models do not set defaults -.- cfgmap.kind = "ConfigMap" cfgmap.api_version = "v1" cfgmap.data = { 'MESOS_MASTER_STATE_SUMMARY_BASE64': b64encode( json.dumps( clusterBackup.data['MESOS_MASTER_STATE-SUMMARY']).encode( 'ascii')) } manifest = Manifest(pluginName=self.plugin_name, manifestName="dcos-cluster") manifest.append(cfgmap) ml.append(manifest) return ml
def create_manifest_list_cluster() -> ManifestList: clusterID = "test-1234-test-test" ml = ManifestList() metadata = V1ObjectMeta(name="dcos-{}".format(clusterID)) metadata.annotations = { "migration.dcos.d2iq.com/cluster-id": clusterID, "migration.dcos.d2iq.com/cluster-name": "testcluster", "migration.dcos.d2iq.com/backup-date": "2021-01-25", } cfgmap = V1ConfigMap(metadata=metadata) # models do not set defaults -.- cfgmap.kind = "ConfigMap" cfgmap.api_version = "v1" cfgmap.data = { "MESOS_MASTER_STATE_SUMMARY_BASE64": b64encode(json.dumps({ "foo": "bar" }).encode("ascii")) } manifest = Manifest(pluginName="cluster", manifestName="dcos-cluster") manifest.append(cfgmap) ml.append(manifest) secret = Manifest(pluginName="secret", manifestName="hello-world.secret") sec = V1Secret(metadata=V1ObjectMeta(name="hello-world.secret", annotations=metadata.annotations)) sec.api_version = 'v1' sec.kind = 'Secret' sec.data = {"hello-world.secret": "Zm9vYmFy"} secret.append(sec) ml.append(secret) return ml