public async Task <ILogger> CreateLoggerAsync(ComponentTask componentTask, ILogger logger)
    {
        if (componentTask is null)
        {
            throw new ArgumentNullException(nameof(componentTask));
        }

        logger ??= NullLogger.Instance;

        try
        {
            var project = await projectRepository
                          .GetAsync(componentTask.Organization, componentTask.ProjectId)
                          .ConfigureAwait(false);

            if (AzureResourceIdentifier.TryParse(project?.StorageId, out var storageId))
            {
                var storageAccount = await azureResourceService
                                     .GetResourceAsync <AzureStorageAccountResource>(storageId.ToString(), false)
                                     .ConfigureAwait(false);

                if (storageAccount is not null)
                {
                    var shareClient = await storageAccount
                                      .CreateShareClientAsync(componentTask.ComponentId)
                                      .ConfigureAwait(false);

                    var directoryClient = shareClient
                                          .GetDirectoryClient(".output");

                    await directoryClient
                    .CreateIfNotExistsAsync()
                    .ConfigureAwait(false);

                    var fileClient = directoryClient
                                     .GetFileClient($"{componentTask.Id}");

                    var fileStream = await fileClient
                                     .OpenWriteAsync(true, 0)
                                     .ConfigureAwait(false);

                    return(new AdapterInitializationLogger(logger, fileStream));
                }
            }
        }
        catch
        {
            // swallow
        }

        return(logger);
    }
Пример #2
0
 internal static Task <DurableOrchestrationStatus> GetCommandStatusAsync(this IDurableOrchestrationContext orchestrationContext, ComponentTask componentTask, bool showHistory = false, bool showHistoryOutput = false, bool showInput = true)
 => orchestrationContext.GetCommandStatusAsync(Guid.Parse(componentTask.Id), showHistory, showHistoryOutput, showInput);
Пример #3
0
 internal static Task TerminateCommandAsync(this IDurableOrchestrationContext orchestrationContext, ComponentTask componentTask, string reason = null)
 => orchestrationContext.TerminateCommandAsync(Guid.Parse(componentTask.Id), reason);
    public override async Task <ICommandResult> HandleAsync(ComponentCreateCommand command, IAsyncCollector <ICommand> commandQueue, IDurableOrchestrationContext orchestrationContext, ILogger log)
    {
        if (command is null)
        {
            throw new ArgumentNullException(nameof(command));
        }

        if (commandQueue is null)
        {
            throw new ArgumentNullException(nameof(commandQueue));
        }

        var commandResult = command.CreateResult();

        try
        {
            commandResult.Result = await componentRepository
                                   .AddAsync(command.Payload)
                                   .ConfigureAwait(false);

            var deploymentScope = await deploymentScopeRepository
                                  .GetAsync(commandResult.Result.Organization, commandResult.Result.DeploymentScopeId)
                                  .ConfigureAwait(false);

            if (adapterProvider.GetAdapter(deploymentScope.Type) is IAdapterIdentity adapterIdentity)
            {
                var servicePrincipal = await adapterIdentity
                                       .GetServiceIdentityAsync(commandResult.Result)
                                       .ConfigureAwait(false);

                var servicePrincipalUser = await userRepository
                                           .GetAsync(commandResult.Result.Organization, servicePrincipal.Id.ToString())
                                           .ConfigureAwait(false);

                if (servicePrincipalUser is null)
                {
                    servicePrincipalUser ??= new User
                    {
                        Id               = servicePrincipal.Id.ToString(),
                        Role             = OrganizationUserRole.Adapter,
                        UserType         = Model.Data.UserType.Service,
                        Organization     = commandResult.Result.Organization,
                        OrganizationName = commandResult.Result.OrganizationName
                    };

                    servicePrincipalUser.EnsureProjectMembership(commandResult.Result.ProjectId, ProjectUserRole.Adapter);

                    await commandQueue
                    .AddAsync(new ProjectUserCreateCommand(command.User, servicePrincipalUser, commandResult.Result.ProjectId))
                    .ConfigureAwait(false);
                }
            }

            var componentTask = new ComponentTask
            {
                Organization     = commandResult.Result.Organization,
                OrganizationName = commandResult.Result.OrganizationName,
                ComponentId      = commandResult.Result.Id,
                ComponentName    = commandResult.Result.Slug,
                ProjectId        = commandResult.Result.ProjectId,
                ProjectName      = commandResult.Result.ProjectName,
                Type             = ComponentTaskType.Create,
                RequestedBy      = commandResult.Result.Creator,
                InputJson        = commandResult.Result.InputJson
            };

            await commandQueue
            .AddAsync(new ComponentTaskCreateCommand(command.User, componentTask))
            .ConfigureAwait(false);

            commandResult.RuntimeStatus = CommandRuntimeStatus.Completed;
        }
        catch (Exception exc)
        {
            commandResult.Errors.Add(exc);
        }

        return(commandResult);
    }
    private async Task <object[]> GetContainersAsync(Organization organization, Component component, ComponentTemplate componentTemplate, ComponentTask componentTask, string runnerHost, int runnerCpu, int runnerMemory)
    {
        var taskToken = CreateUniqueString(30);

        var containers = new List <object>()
        {
            new
            {
                name       = componentTask.Id,
                properties = new
                {
                    image     = await GetContainerImageAsync(organization, componentTemplate).ConfigureAwait(false),
                    resources = new
                    {
                        requests = new
                        {
                            cpu        = runnerCpu,
                            memoryInGB = runnerMemory
                        }
                    },
                    environmentVariables = GetRunnerEnvironmentVariables(),
                    volumeMounts         = new []
                    {
                        new
                        {
                            name      = "templates",
                            mountPath = "/mnt/templates",
                            readOnly  = false
                        },
                        new
                        {
                            name      = "storage",
                            mountPath = "/mnt/storage",
                            readOnly  = false
                        },
                        new
                        {
                            name      = "secrets",
                            mountPath = "/mnt/secrets",
                            readOnly  = false
                        },
                        new
                        {
                            name      = "credentials",
                            mountPath = "/mnt/credentials",
                            readOnly  = false
                        },
                        new
                        {
                            name      = "temporary",
                            mountPath = "/mnt/temporary",
                            readOnly  = false
                        }
                    }
                }
            }
        };

        if (componentTemplate.TaskRunner?.WebServer ?? false)
        {
            containers.Add(new
            {
                name       = "webserver",
                properties = new
                {
                    image = runnerOptions.WebServerImage,
                    ports = new[]
                    {
                        new {
                            protocol = "tcp",
                            port     = 80
                        },
                        new {
                            protocol = "tcp",
                            port     = 443
                        }
                    },
                    resources = new
                    {
                        requests = new
                        {
                            cpu        = 1,
                            memoryInGB = 1
                        }
                    },
                    //readinessProbe = new
                    //{
                    //    httpGet = new
                    //    {
                    //        scheme = "http",
                    //        port = 80,
                    //        path = "/"

                    //    },
                    //    initialDelaySeconds = 2,
                    //    periodSeconds = 2,
                    //    timeoutSeconds = 300
                    //},
                    environmentVariables = new object[]
                    {
                        new
                        {
                            name  = "TaskHost",
                            value = runnerHost
                        },
                        new
                        {
                            name  = "TaskToken",
                            value = taskToken
                        }
                    },
                    volumeMounts = new[]
                    {
                        new
                        {
                            name      = "templates",
                            mountPath = "/mnt/templates",
                            readOnly  = true
                        }
                    }
                }
            });
        }

        return(containers.ToArray());

        object[] GetRunnerEnvironmentVariables()
        {
            var envVariables = componentTemplate.TaskRunner?.With ?? new Dictionary <string, string>();

            envVariables["TaskId"]                      = componentTask.Id;
            envVariables["TaskHost"]                    = runnerHost;
            envVariables["TaskToken"]                   = taskToken;
            envVariables["TaskType"]                    = componentTask.TypeName ?? componentTask.Type.ToString();
            envVariables["WebServerEnabled"]            = ((componentTemplate.TaskRunner?.WebServer ?? false) ? 1 : 0).ToString();
            envVariables["ComponentLocation"]           = organization.Location;
            envVariables["ComponentTemplateBaseUrl"]    = $"http://{runnerHost}/{componentTemplate.Folder.Trim().TrimStart('/')}";
            envVariables["ComponentTemplateFolder"]     = $"file:///mnt/templates/{componentTemplate.Folder.Trim().TrimStart('/')}";
            envVariables["ComponentTemplateParameters"] = string.IsNullOrWhiteSpace(component.InputJson) ? "{}" : component.InputJson;
            envVariables["ComponentResourceId"]         = component.ResourceId;

            if (AzureResourceIdentifier.TryParse(component.ResourceId, out var componentResourceId))
            {
                envVariables["ComponentResourceGroup"] = componentResourceId.ResourceGroup;
                envVariables["ComponentSubscription"]  = componentResourceId.SubscriptionId.ToString();
            }

            return(envVariables
                   .Where(kvp => kvp.Value is not null)
                   .Select(kvp => new { name = kvp.Key, value = kvp.Value })
                   .ToArray());
        }
    }
Пример #6
0
    public override async Task <ICommandResult> HandleAsync(ComponentDeleteCommand command, IAsyncCollector <ICommand> commandQueue, IDurableOrchestrationContext orchestrationContext, ILogger log)
    {
        if (command is null)
        {
            throw new ArgumentNullException(nameof(command));
        }

        if (commandQueue is null)
        {
            throw new ArgumentNullException(nameof(commandQueue));
        }

        var commandResult = command.CreateResult();

        try
        {
            commandResult.Result = await componentRepository
                                   .RemoveAsync(command.Payload, true)
                                   .ConfigureAwait(false);

            var existingComponentTasks = componentTaskRepository
                                         .ListAsync(commandResult.Result.Id)
                                         .Where(ct => ct.Type == ComponentTaskType.Custom && ct.TaskState.IsActive());

            await foreach (var existingComponentTask in existingComponentTasks)
            {
                var cancelCommand = new ComponentTaskCancelCommand(command.User, existingComponentTask);

                await commandQueue
                .AddAsync(cancelCommand)
                .ConfigureAwait(false);
            }

            var componentTask = new ComponentTask
            {
                Organization     = commandResult.Result.Organization,
                OrganizationName = commandResult.Result.OrganizationName,
                ComponentId      = commandResult.Result.Id,
                ComponentName    = commandResult.Result.Slug,
                ProjectId        = commandResult.Result.ProjectId,
                ProjectName      = commandResult.Result.ProjectName,
                Type             = ComponentTaskType.Delete,
                RequestedBy      = command.User.Id,
                InputJson        = commandResult.Result.InputJson
            };

            componentTask = await componentTaskRepository
                            .AddAsync(componentTask)
                            .ConfigureAwait(false);

            await commandQueue
            .AddAsync(new ComponentTaskRunCommand(command.User, componentTask))
            .ConfigureAwait(false);

            commandResult.RuntimeStatus = CommandRuntimeStatus.Completed;
        }
        catch (Exception exc)
        {
            commandResult.Errors.Add(exc);
        }

        return(commandResult);
    }