public async Task <bool> DoImportAsync(ModuleInfo moduleInfo, bool forcePublish) { // check if module has already been imported if ( !forcePublish && !(moduleInfo.Version?.IsPreRelease ?? false) && await Settings.S3Client.DoesS3ObjectExistAsync(Settings.DeploymentBucketName, moduleInfo.VersionPath) ) { return(true); } // find manifest for module to import var moduleLocation = await _loader.ResolveInfoToLocationAsync(moduleInfo, ModuleManifestDependencyType.Root, allowImport : true, showError : true); if (moduleLocation == null) { // nothing to do; loader already emitted an error return(false); } var manifest = await _loader.LoadManifestFromLocationAsync(moduleLocation); if (manifest == null) { // error has already been reported return(false); } // import module dependencies if (!await ImportDependencies(manifest)) { // error has already been reported return(false); } // import module var imported = false; foreach (var artifact in manifest.Artifacts) { imported = imported | await ImportS3Object(moduleInfo.Origin, artifact, replace : forcePublish); } imported = imported | await ImportS3Object(moduleInfo.Origin, moduleInfo.VersionPath, replace : forcePublish || moduleInfo.Version.IsPreRelease); if (imported) { Console.WriteLine($"=> Imported {moduleInfo}"); } else { Console.WriteLine($"=> Nothing to do"); } return(true); }
//--- Methods --- public async Task <bool> DoAsync( DryRunLevel?dryRun, string moduleReference, string instanceName, bool allowDataLoos, bool protectStack, Dictionary <string, string> parameters, bool forceDeploy, bool promptAllParameters, XRayTracingLevel xRayTracingLevel, bool deployOnlyIfExists, bool allowDependencyUpgrades ) { Console.WriteLine($"Resolving module reference: {moduleReference}"); // determine location of cloudformation template from module key if (!ModuleInfo.TryParse(moduleReference, out var moduleInfo)) { LogError($"invalid module reference: {moduleReference}"); return(false); } var foundModuleLocation = await _loader.ResolveInfoToLocationAsync(moduleInfo, moduleInfo.Origin, ModuleManifestDependencyType.Root, allowImport : Settings.AllowImport, showError : !deployOnlyIfExists); if (foundModuleLocation == null) { // nothing to do; loader already emitted an error return(deployOnlyIfExists); } // download module manifest var(manifest, manifestErrorReason) = await _loader.LoadManifestFromLocationAsync(foundModuleLocation); if (manifest == null) { LogError(manifestErrorReason); return(false); } // deploy module if (dryRun == null) { var stackName = Settings.GetStackName(manifest.GetFullName(), instanceName); // check version of previously deployed module if (!deployOnlyIfExists) { Console.WriteLine("=> Validating module for deployment tier"); } var updateValidation = await IsValidModuleUpdateAsync(stackName, manifest, showError : !forceDeploy && !deployOnlyIfExists); if (!forceDeploy && !updateValidation.Success) { return(false); } // check if a previous deployment was found if (deployOnlyIfExists && (updateValidation.ExistingStack == null)) { // nothing to do return(true); } var existing = updateValidation.ExistingStack; // check if existing stack checksum matches template checksum if (!forceDeploy && !parameters.Any()) { var existingChecksum = existing?.Outputs.FirstOrDefault(output => output.OutputKey == "ModuleChecksum"); if (existingChecksum?.OutputValue == manifest.TemplateChecksum) { Console.WriteLine($"{Settings.LowContrastColor}=> No changes found to deploy{Settings.ResetColor}"); return(true); } } // prompt for missing parameters var deployParameters = PromptModuleParameters(manifest, existing, parameters, promptAllParameters); if (HasErrors) { return(false); } // check if module supports AWS X-Ray for tracing if ( manifest.GetAllParameters().Any(p => p.Name == "XRayTracing") && !deployParameters.Any(p => p.ParameterKey == "XRayTracing") ) { deployParameters.Add(new CloudFormationParameter { ParameterKey = "XRayTracing", ParameterValue = xRayTracingLevel.ToString() }); } // discover shared module dependencies and prompt for missing parameters var dependencies = (await _loader.DiscoverAllDependenciesAsync(manifest, checkExisting: true, allowImport: Settings.AllowImport, allowDependencyUpgrades: allowDependencyUpgrades)) .Where(dependency => dependency.Type == ModuleManifestDependencyType.Shared) .ToList(); if (HasErrors) { return(false); } var dependenciesParameters = dependencies .Select(dependency => new { ModuleFullName = dependency.Manifest.GetFullName(), Parameters = PromptModuleParameters( dependency.Manifest, promptAll: promptAllParameters ) }) .ToDictionary(t => t.ModuleFullName, t => t.Parameters); if (HasErrors) { return(false); } // deploy module dependencies foreach (var dependency in dependencies) { var dependencyLocation = new ModuleLocation(Settings.DeploymentBucketName, dependency.ModuleLocation.ModuleInfo, dependency.ModuleLocation.Hash); if (!await new ModelUpdater(Settings, SourceFilename).DeployChangeSetAsync( dependency.Manifest, await _loader.GetNameMappingsFromLocationAsync(dependencyLocation), dependencyLocation, Settings.GetStackName(dependency.Manifest.GetFullName()), allowDataLoos, protectStack, dependenciesParameters[dependency.Manifest.GetFullName()] )) { return(false); } } // deploy module var moduleLocation = new ModuleLocation(Settings.DeploymentBucketName, manifest.ModuleInfo, manifest.TemplateChecksum); return(await new ModelUpdater(Settings, moduleReference).DeployChangeSetAsync( manifest, await _loader.GetNameMappingsFromLocationAsync(moduleLocation), moduleLocation, stackName, allowDataLoos, protectStack, deployParameters )); } return(true); }
public async Task <bool> DoImportAsync(ModuleInfo moduleInfo, bool forcePublish, string fromOrigin) { if ((fromOrigin ?? moduleInfo.Origin) == Settings.DeploymentBucketName) { LogWarn($"skipping import of {moduleInfo} because origin matches deployment bucket"); return(true); } // check if module has already been imported if ( !forcePublish && (moduleInfo.Version != null) && !moduleInfo.Version.IsPreRelease() && await Settings.S3Client.DoesS3ObjectExistAsync(Settings.DeploymentBucketName, moduleInfo.VersionPath) ) { return(true); } // find manifest for module to import var moduleLocation = await _loader.ResolveInfoToLocationAsync(moduleInfo, fromOrigin ?? moduleInfo.Origin, ModuleManifestDependencyType.Root, allowImport : true, showError : true); if (moduleLocation == null) { // nothing to do; loader already emitted an error return(false); } var manifest = await _loader.LoadManifestFromLocationAsync(moduleLocation); if (manifest == null) { // error has already been reported return(false); } // import module dependencies only if `--from-origin` was NOT specified if (!await ImportDependencies(manifest, allowImport: fromOrigin == null)) { // error has already been reported return(false); } // import module var imported = false; foreach (var artifact in manifest.Artifacts) { imported = imported | await ImportS3Object(moduleLocation.SourceBucketName, artifact, replace : forcePublish); } // don't import module manifest if any of the artifacts failed to import if (HasErrors) { return(false); } imported = imported | await ImportS3Object(moduleLocation.SourceBucketName, moduleLocation.ModuleInfo.VersionPath, replace : forcePublish || moduleLocation.ModuleInfo.Version.IsPreRelease()); if (imported) { Console.WriteLine($"=> Imported {moduleLocation.ModuleInfo}"); } else { Console.WriteLine($"=> Nothing to do"); } return(true); }