/// <summary>
        /// Substitutes the property tokens in the supplied string.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <param name="input">The input string.</param>
        /// <returns>The substituted string</returns>
        public async Task<string> SubstituteTokensInString(RuntimeContext runtimeContext, TaskContext taskContext, string input)
        {
            string output = input;

            var matches = ImageRegex.Matches(input);
            if (matches.Count > 0)
            {
                foreach (Match match in matches)
                {
                    string networkDomainId = match.Groups[1].Value;

                    var publicIps = await ListAvailablePublicIps(runtimeContext.AccountDetails, networkDomainId);
                    if (publicIps.Count == 0)
                    {
                        await AddPublicIpBlock(runtimeContext.AccountDetails, networkDomainId);
                        publicIps = await ListAvailablePublicIps(runtimeContext.AccountDetails, networkDomainId);
                    }

                    if (publicIps.Count == 0)
                    {
                        throw new InvalidOperationException("Failed to find free public IP address.");
                    }

                    output = output.Replace(match.Groups[0].Value, publicIps[0]);
                }
            }

            return output;
        }
Esempio n. 2
0
 /// <summary>
 /// Substitutes the property tokens in the supplied string.
 /// </summary>
 /// <param name="runtimeContext">The runtime context.</param>
 /// <param name="taskContext">The task execution context.</param>
 /// <param name="input">The input string.</param>
 /// <returns>The substituted string</returns>
 public async Task<string> SubstituteTokensInString(RuntimeContext runtimeContext, TaskContext taskContext, string input)
 {
     return await Task.Run(() =>
     {
         return SubstituteTokensInString(input, taskContext.Parameters, true);
     });
 }
        /// <summary>
        /// Runs the orchestration.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <param name="orchestrationObject">The orchestration object.</param>
        /// <param name="resources">The resources.</param>
        /// <returns>The async <see cref="Task"/>.</returns>
        public async Task RunOrchestration(RuntimeContext runtimeContext, TaskContext taskContext, JObject orchestrationObject, IEnumerable<Resource> resources)
        {
            _logProvider = runtimeContext.LogProvider;
            _docsApiClient = new DocsApiClient(orchestrationObject["docsServiceUrl"].Value<string>());
            _orchestratorClient = new OrchestratorApiClient(orchestrationObject["orchestratorServiceUrl"].Value<string>());

            await Macro.SubstituteTokensInJObject(runtimeContext, taskContext, orchestrationObject);

            await SendConfiguration((JArray)orchestrationObject["configuration"]);
            await SendEnvironment((JObject)orchestrationObject["environment"], resources, taskContext.ResourcesProperties);
            LaunchRunbook(orchestrationObject["runbook"].Value<string>());
        }
        /// <summary>
        /// Executes the task.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <returns>The async <see cref="Task"/>.</returns>
        public async Task Execute(RuntimeContext runtimeContext, TaskContext taskContext)
        {
            await Macro.SubstituteTokensInJObject(runtimeContext, taskContext, Resource.ResourceDefinition);
            var deployer = new ResourceDeployer(runtimeContext, Resource.ResourceId, Resource.ResourceType);
            var resourceLog = await deployer.DeployAndWait(Resource.ResourceDefinition);

            taskContext.Log.Resources.Add(resourceLog);
            taskContext.ResourcesProperties.Add(resourceLog.ResourceId, resourceLog.Details);

            if (resourceLog.DeploymentStatus == ResourceLogStatus.Failed)
            {
                taskContext.Log.Status = DeploymentLogStatus.Failed;
            }
        }
        public async Task Parameters_SubstituteTokensInString_NotFound()
        {
            var context = new TaskContext
            {
                Parameters = new Dictionary<string, string>()
                {
                    { "Param1", "Value1" }
                }
            };

            var macro = new ParametersMacro();
            var input = "Hello_$parameters['Param2']";
            await macro.SubstituteTokensInString(null, context, input);
        }
        /// <summary>
        /// Executes the task.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <returns>The async <see cref="Task"/>.</returns>
        public async Task Execute(RuntimeContext runtimeContext, TaskContext taskContext)
        {
            if (ExistingResources == null)
            {
                return;
            }

            foreach (var existingResource in ExistingResources)
            {
                existingResource.ExistingCaasId = await Macro.SubstituteTokensInString(runtimeContext, taskContext, existingResource.ExistingCaasId);
                var deployer = new ResourceDeployer(runtimeContext, existingResource.ResourceId, existingResource.ResourceType);
                var resource = await deployer.Get(existingResource.ExistingCaasId);
                taskContext.ResourcesProperties.Add(existingResource.ResourceId, resource);
            }
        }
        /// <summary>
        /// Executes the task.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <returns>The async <see cref="Task"/>.</returns>
        public async Task Execute(RuntimeContext runtimeContext, TaskContext taskContext)
        {
            if (ResourceLog.CaasId != null)
            {
                var deployer = new ResourceDeployer(runtimeContext, ResourceLog.ResourceId, ResourceLog.ResourceType);
                var resourceLog = await deployer.DeleteAndWait(ResourceLog.CaasId);

                taskContext.Log.Resources.Add(resourceLog);

                if (resourceLog.DeploymentStatus == ResourceLogStatus.Failed)
                {
                    taskContext.Log.Status = DeploymentLogStatus.Failed;
                }
            }
        }
        /// <summary>
        /// Executes the task.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <returns>The async <see cref="Task"/>.</returns>
        public async Task Execute(RuntimeContext runtimeContext, TaskContext taskContext)
        {
            var providerTypeName = Orchestration["provider"].Value<String>();
            var providerType = Type.GetType(providerTypeName);
            if (providerType == null)
            {
                runtimeContext.LogProvider.LogError($"Unable to create Orchestration Provider of type {providerTypeName}.");
                return;
            }

            var provider = (IOrchestrationProvider)Activator.CreateInstance(providerType);
            runtimeContext.LogProvider.LogMessage($"Running Orchestration Provider '{providerTypeName}'.");

            await provider.RunOrchestration(runtimeContext, taskContext, Orchestration, Resources);
        }
Esempio n. 9
0
        /// <summary>
        /// Substitutes the property tokens in the supplied string.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <param name="input">The input string.</param>
        /// <returns>The substituted string</returns>
        public static async Task<string> SubstituteTokensInString(RuntimeContext runtimeContext, TaskContext taskContext, string input)
        {
            var value = input;

            if (string.IsNullOrEmpty(value))
            {
                return value;
            }

            foreach (var macro in Macros)
            {
                value = await macro.SubstituteTokensInString(runtimeContext, taskContext, value);
            }

            return value;
        }
        public async Task Parameters_SubstituteTokensInString_Success()
        {
            var context = new TaskContext
            {
                Parameters = new Dictionary<string, string>()
                {
                    { "Param1", "Param2" },
                    { "Param2", "Param3" },
                    { "Param3", "Param4" }
                }
            };

            var macro = new ParametersMacro();
            var input = "Hello_$parameters[$parameters['Param1']]";
            var output = await macro.SubstituteTokensInString(null, context, input);

            Assert.AreEqual("Hello_Param3", output);
        }
        /// <summary>
        /// Substitutes the property tokens in the supplied string.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <param name="input">The input string.</param>
        /// <returns>The substituted string</returns>
        public async Task<string> SubstituteTokensInString(RuntimeContext runtimeContext, TaskContext taskContext, string input)
        {
            string output = input;

            var matches = ImageRegex.Matches(input);
            if (matches.Count > 0)
            {
                foreach (Match match in matches)
                {
                    string imageType = match.Groups[1].Value;
                    string location = match.Groups[2].Value;
                    string imageName = match.Groups[3].Value;

                    using (var client = HttpClientFactory.GetClient(runtimeContext.AccountDetails, "text/xml"))
                    {
                        var url = (imageType == "customerImage")
                            ? string.Format(ImageUrl, runtimeContext.AccountDetails.OrgId, imageName)
                            : string.Format(ImageUrl, "base", imageName);

                        var response = await client.GetAsync(runtimeContext.AccountDetails.BaseUrl + url);
                        response.ThrowForHttpFailure();

                        var responseBody = await response.Content.ReadAsStringAsync();
                        var document = XDocument.Parse(responseBody);
                        var imageId = document.Root
                            .Elements(ServerNamespace + "image")
                            .Where(e => e.Attribute("location").Value == location)
                            .Select(e => e.Attribute("id").Value)
                            .FirstOrDefault();

                        if (imageId == null)
                        {
                            throw new TemplateParserException($"Image '{imageName}' not found in datacenter '{location}'.");
                        }

                        output = output.Replace(match.Groups[0].Value, imageId);
                    }
                }
            }

            return output;
        }
Esempio n. 12
0
        /// <summary>
        /// Substitutes the tokens in supplied JSON object.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <param name="resourceDefinition">The resource definition.</param>
        /// <returns>The async <see cref="Task"/>.</returns>
        public static async Task SubstituteTokensInJObject(RuntimeContext runtimeContext, TaskContext taskContext, JObject resourceDefinition)
        {
            foreach (var parameter in resourceDefinition)
            {
                if (parameter.Value is JObject)
                {
                    await SubstituteTokensInJObject(runtimeContext, taskContext, (JObject)parameter.Value);
                }
                else if (parameter.Value is JValue)
                {
                    var value = parameter.Value.Value<string>();
                    value = await SubstituteTokensInString(runtimeContext, taskContext, value);

                    if (value == string.Empty)
                    {
                        parameter.Value.Replace(null);
                    }
                    else
                    {
                        parameter.Value.Replace(new JValue(value));
                    }
                }
                else if (parameter.Value is JArray)
                {
                    foreach (var jtoken in ((JArray)parameter.Value))
                    {
                        if (jtoken is JObject)
                        {
                            await SubstituteTokensInJObject(runtimeContext, taskContext, (JObject)jtoken);
                        }
                        else
                        {
                            var value = jtoken.Value<string>();
                            value = await SubstituteTokensInString(runtimeContext, taskContext, value);
                            ((JValue)jtoken).Replace(new JValue(value));
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Substitutes the property tokens in the supplied string.
        /// </summary>
        /// <param name="runtimeContext">The runtime context.</param>
        /// <param name="taskContext">The task execution context.</param>
        /// <param name="input">The input string.</param>
        /// <returns>The substituted string</returns>
        public async Task<string> SubstituteTokensInString(RuntimeContext runtimeContext, TaskContext taskContext, string input)
        {
            return await Task.Run(() =>
            {
                string output = input;

                if (taskContext.ResourcesProperties != null)
                {
                    MatchCollection resourceMatches = ResourcePropertyRegex.Matches(output);

                    while (resourceMatches.Count > 0)
                    {
                        Match resourceMatch = resourceMatches[resourceMatches.Count - 1];
                        string resourceId = resourceMatch.Groups[1].Value;
                        string property = resourceMatch.Groups[2].Value;

                        JObject resource;

                        if (!taskContext.ResourcesProperties.TryGetValue(resourceId, out resource))
                        {
                            throw new TemplateParserException($"Referenced resource '{resourceId}' not found.");
                        }

                        var newValue = resource.SelectToken(property).Value<string>();

                        if (MacroUtilities.IsNested(output, resourceMatch))
                        {
                            newValue = "'" + newValue + "'";
                        }

                        output = output.Replace(resourceMatch.Groups[0].Value, newValue);
                        resourceMatches = ResourcePropertyRegex.Matches(output);
                    }
                }

                return output;
            });
        }
        /// <summary>
        /// Gets the deployment tasks for the supplied deployment template.
        /// </summary>
        /// <param name="template">The deployment template.</param>
        /// <param name="scriptPath">The script path.</param>
        /// <param name="parameters">The deployment parameters.</param>
        /// <returns>Instance of <see cref="TaskExecutor"/> with tasks and task execution context.</returns>
        public TaskExecutor BuildTasks(DeploymentTemplate template, string scriptPath, IDictionary<string, string> parameters)
        {
            var sortedResources = ResourceDependencies.DependencySort(template.Resources).Reverse().ToList();

            // Extract the resources which already exist from the resource collection and create a task to load them.
            var existingResources = new List<Resource>();
            var resourcesWithExistingCaasId = sortedResources
                .Where(resource => !string.IsNullOrEmpty(resource.ExistingCaasId))
                .ToList();

            foreach (var resource in resourcesWithExistingCaasId)
            {
                var existingCaasId = ParametersMacro.SubstituteTokensInString(resource.ExistingCaasId, parameters, false);
                if (!string.IsNullOrEmpty(existingCaasId))
                {
                    sortedResources.Remove(resource);
                    existingResources.Add(resource);
                }
            }

            var tasks = new List<ITask>();

            if (existingResources.Count > 0)
            {
                tasks.Add(new LoadExistingResourcesTask(existingResources));

                foreach (var existingResource in existingResources)
                {
                    if ((existingResource.Scripts != null) && (existingResource.ResourceType == ResourceType.Server))
                    {
                        tasks.Add(new ExecuteScriptTask(existingResource, scriptPath));
                    }
                }
            }

            // Create the tasks to deploy new resources.
            foreach (var resource in sortedResources)
            {
                tasks.Add(new DeployResourceTask(resource));

                if ((resource.Scripts != null) && (resource.ResourceType == ResourceType.Server))
                {
                    tasks.Add(new ExecuteScriptTask(resource, scriptPath));
                }
            }

            if (template.Orchestration != null)
            {
                tasks.Add(new RunOrchestrationTask(template.Orchestration, sortedResources));
            }

            if (template.OutputParameters != null && template.OutputParameters.Properties().Any())
            {
                tasks.Add(new SetOutputParametersTask(template.OutputParameters));
            }

            // Create the task execution context.
            var context = new TaskContext
            {
                Parameters = parameters,
                ResourcesProperties = new Dictionary<string, JObject>(),
                Log = new DeploymentLog()
                {
                    DeploymentTime = DateTime.Now,
                    TemplateName = template.Metadata.TemplateName,
                    Resources = new List<ResourceLog>()
                }
            };

            return new TaskExecutor(template, tasks, context);
        }
        /// <summary>
        /// Gets the deletion tasks for the supplied deployment log.
        /// </summary>
        /// <param name="deploymentLog">The deployment log.</param>
        /// <returns>Instance of <see cref="TaskExecutor"/> with tasks and task execution context.</returns>
        public TaskExecutor BuildTasks(DeploymentLog deploymentLog)
        {
            // Create a sequential list of tasks we need to execute.
            var reversedResources = new List<ResourceLog>(deploymentLog.Resources);
            reversedResources.Reverse();

            var tasks = reversedResources
                .Where(resource => resource.CaasId != null)
                .Select(resource => (ITask)new DeleteResourceTask(resource))
                .ToList();

            // Create the task execution context.
            var context = new TaskContext
            {
                Log = new DeploymentLog()
                {
                    DeploymentTime = DateTime.Now,
                    TemplateName = deploymentLog.TemplateName,
                    Resources = new List<ResourceLog>()
                }
            };

            return new TaskExecutor(null, tasks, context);
        }
Esempio n. 16
0
 /// <summary>
 /// Executes the task.
 /// </summary>
 /// <param name="runtimeContext">The runtime context.</param>
 /// <param name="taskContext">The task execution context.</param>
 /// <returns>The async <see cref="Task"/>.</returns>
 public Task Execute(RuntimeContext runtimeContext, TaskContext taskContext)
 {
     throw new NotSupportedException("Post-Deploy script not supported.");
 }