Ejemplo n.º 1
0
        public async Task <TeamCloudInstance> RunActivity(
            [ActivityTrigger] TeamCloudInstance teamCloudInstance)
        {
            var teamCloud = await teamCloudRepository
                            .SetAsync(teamCloudInstance)
                            .ConfigureAwait(false);

            return(teamCloud);
        }
Ejemplo n.º 2
0
        public async Task <IActionResult> Put([FromBody] TeamCloudInstance teamCloudInstance)
        {
            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .BadRequest("Request body must not be empty.", ResultErrorCode.ValidationError)
                       .ToActionResult());
            }

            if (!teamCloudInstance.TryValidate(out var validationResult, serviceProvider: HttpContext.RequestServices))
            {
                return(ErrorResult
                       .BadRequest(validationResult)
                       .ToActionResult());
            }

            var teamCloudInstanceDocument = await teamCloudRepository
                                            .GetAsync()
                                            .ConfigureAwait(false);

            if (teamCloudInstanceDocument is null)
            {
                return(ErrorResult
                       .NotFound("The TeamCloud instance could not be found.")
                       .ToActionResult());
            }

            if (!string.IsNullOrEmpty(teamCloudInstance.Version))
            {
                teamCloudInstanceDocument.Version = teamCloudInstance.Version;
            }

            if (!(teamCloudInstance.ResourceGroup is null))
            {
                teamCloudInstanceDocument.ResourceGroup = teamCloudInstance.ResourceGroup;
            }

            if (teamCloudInstance.Tags?.Any() ?? false)
            {
                teamCloudInstanceDocument.MergeTags(teamCloudInstance.Tags);
            }

            if (teamCloudInstance.Applications?.Any() ?? false)
            {
                teamCloudInstanceDocument.Applications = teamCloudInstance.Applications;
            }

            var currentUser = await UserService
                              .CurrentUserAsync()
                              .ConfigureAwait(false);

            return(await Orchestrator
                   .InvokeAndReturnActionResultAsync <TeamCloudInstanceDocument, TeamCloudInstance>(new OrchestratorTeamCloudInstanceSetCommand(currentUser, teamCloudInstanceDocument), Request)
                   .ConfigureAwait(false));
        }
Ejemplo n.º 3
0
        public async Task <TeamCloudInstance> SetAsync(TeamCloudInstance teamCloudInstance)
        {
            var container = await GetContainerAsync <TeamCloudInstance>()
                            .ConfigureAwait(false);

            var response = await container
                           .UpsertItemAsync <TeamCloudInstance>(teamCloudInstance, new PartitionKey(Constants.CosmosDb.TenantName))
                           .ConfigureAwait(false);

            return(response.Value);
        }
        public async Task <IActionResult> Post([FromBody] TeamCloudInstance teamCloudInstance)
        {
            if (teamCloudInstance is null)
            {
                throw new ArgumentNullException(nameof(teamCloudInstance));
            }

            var validation = new TeamCloudInstanceValidaor().Validate(teamCloudInstance);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var existingTeamCloudInstance = await teamCloudRepository
                                            .GetAsync()
                                            .ConfigureAwait(false);

            if (existingTeamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound("The TeamCloud instance could not be found.")
                       .ActionResult());
            }

            if (existingTeamCloudInstance.ResourceGroup != null ||
                existingTeamCloudInstance.Version != null ||
                (existingTeamCloudInstance.Tags?.Any() ?? false))
            {
                return(ErrorResult
                       .Conflict($"The TeamCloud instance already exists.  Call PUT to update the existing instance.")
                       .ActionResult());
            }

            existingTeamCloudInstance.Version       = teamCloudInstance.Version;
            existingTeamCloudInstance.ResourceGroup = teamCloudInstance.ResourceGroup;
            existingTeamCloudInstance.Tags          = teamCloudInstance.Tags;

            var setResult = await orchestrator
                            .SetAsync(existingTeamCloudInstance)
                            .ConfigureAwait(false);

            var baseUrl  = HttpContext.GetApplicationBaseUrl();
            var location = new Uri(baseUrl, $"api/admin/teamCloudInstance").ToString();

            var returnSetResult = setResult.PopulateExternalModel();

            return(DataResult <TeamCloudInstance>
                   .Created(returnSetResult, location)
                   .ActionResult());
        }
        public async Task <IActionResult> Put([FromBody] TeamCloudInstance teamCloudInstance)
        {
            if (teamCloudInstance is null)
            {
                throw new ArgumentNullException(nameof(teamCloudInstance));
            }

            var validation = new TeamCloudInstanceValidaor().Validate(teamCloudInstance);

            if (!validation.IsValid)
            {
                return(ErrorResult
                       .BadRequest(validation)
                       .ActionResult());
            }

            var existingTeamCloudInstance = await teamCloudRepository
                                            .GetAsync()
                                            .ConfigureAwait(false);

            if (existingTeamCloudInstance is null)
            {
                return(ErrorResult
                       .NotFound("The TeamCloud instance could not be found.")
                       .ActionResult());
            }

            if (!string.IsNullOrEmpty(teamCloudInstance.Version))
            {
                existingTeamCloudInstance.Version = teamCloudInstance.Version;
            }

            if (!(teamCloudInstance.ResourceGroup is null))
            {
                existingTeamCloudInstance.ResourceGroup = teamCloudInstance.ResourceGroup;
            }

            if (teamCloudInstance.Tags?.Any() ?? false)
            {
                existingTeamCloudInstance.MergeTags(teamCloudInstance.Tags);
            }

            var setResult = await orchestrator
                            .SetAsync(existingTeamCloudInstance)
                            .ConfigureAwait(false);

            var returnSetResult = setResult.PopulateExternalModel();

            return(DataResult <TeamCloudInstance>
                   .Ok(returnSetResult)
                   .ActionResult());
        }
Ejemplo n.º 6
0
        public async Task <TeamCloudInstance> RunActivity(
            [ActivityTrigger] TeamCloudInstance teamCloudInstance)
        {
            if (teamCloudInstance is null)
            {
                throw new ArgumentNullException(nameof(teamCloudInstance));
            }

            teamCloudInstance = await teamCloudRepository
                                .SetAsync(teamCloudInstance)
                                .ConfigureAwait(false);

            return(teamCloudInstance);
        }
Ejemplo n.º 7
0
        public async Task <IActionResult> Post([FromBody] TeamCloudInstance teamCloudInstance)
        {
            if (teamCloudInstance is null)
            {
                return(ErrorResult
                       .BadRequest("Request body must not be empty.", ResultErrorCode.ValidationError)
                       .ToActionResult());
            }

            if (!teamCloudInstance.TryValidate(out var validationResult, serviceProvider: HttpContext.RequestServices))
            {
                return(ErrorResult
                       .BadRequest(validationResult)
                       .ToActionResult());
            }

            var teamCloudInstanceDocument = await teamCloudRepository
                                            .GetAsync()
                                            .ConfigureAwait(false);

            if (teamCloudInstanceDocument is null)
            {
                return(ErrorResult
                       .NotFound("The TeamCloud instance could not be found.")
                       .ToActionResult());
            }

            if (teamCloudInstanceDocument.ResourceGroup != null ||
                teamCloudInstanceDocument.Version != null ||
                (teamCloudInstanceDocument.Tags?.Any() ?? false))
            {
                return(ErrorResult
                       .Conflict($"The TeamCloud instance already exists.  Call PUT to update the existing instance.")
                       .ToActionResult());
            }

            teamCloudInstanceDocument.Version       = teamCloudInstance.Version;
            teamCloudInstanceDocument.ResourceGroup = teamCloudInstance.ResourceGroup;
            teamCloudInstanceDocument.Tags          = teamCloudInstance.Tags;

            var currentUser = await UserService
                              .CurrentUserAsync(allowUnsafe : true)
                              .ConfigureAwait(false);

            return(await Orchestrator
                   .InvokeAndReturnActionResultAsync <TeamCloudInstanceDocument, TeamCloudInstance>(new OrchestratorTeamCloudInstanceSetCommand(currentUser, teamCloudInstanceDocument), Request)
                   .ConfigureAwait(false));
        }
Ejemplo n.º 8
0
        public ProjectContext(TeamCloudInstance teamCloud, Project project, User user)
        {
            User                 = user;
            ProjectId            = project.Id;
            ProjectName          = project.Name;
            ProjectResourceGroup = project.ResourceGroup;
            ProjectUsers         = project.Users;
            ProjectTags          = project.Tags;

            TeamCloudId = teamCloud.Id;
            TeamCloudApplicationInsightsKey = teamCloud.ApplicationInsightsKey;
            TeamCloudAdminUsers             = teamCloud.Users.Where(u => u.Role == UserRoles.TeamCloud.Admin).ToList();
            TeamCloudTags              = teamCloud.Configuration.Tags;
            TeamCloudVariables         = teamCloud.Configuration.Variables;
            TeamCloudProviderVariables = teamCloud.Configuration.Providers.Select(p => (p.Id, p.Variables)).ToDictionary(t => t.Id, t => t.Variables);
        }
Ejemplo n.º 9
0
        public async Task <IActionResult> Post([FromBody] TeamCloudConfiguration teamCloudConfiguraiton)
        {
            if (teamCloudConfiguraiton is null)
            {
                return(new BadRequestObjectResult("Unable to parse teamcloud.yaml file."));
            }

            try
            {
                new TeamCloudConfigurationValidator().ValidateAndThrow(teamCloudConfiguraiton);
            }
            catch (ValidationException validationEx)
            {
                return(new BadRequestObjectResult(validationEx.Errors));
            }

            var teamCloud = new TeamCloudInstance
            {
                Users         = teamCloudConfiguraiton.Users,
                Configuration = teamCloudConfiguraiton
            };

            var command = new TeamCloudCreateCommand(currentUser, teamCloud);

            var commandResult = await orchestrator
                                .InvokeAsync <TeamCloudInstance>(command)
                                .ConfigureAwait(false);

            if (commandResult.Links.TryGetValue("status", out var statusUrl))
            {
                return(new AcceptedResult(statusUrl, commandResult));
            }
            else
            {
                return(new OkObjectResult(commandResult));
            }

            /* TODO:
             *
             * - Change the input to a file upload
             * - This will be in the form of a yaml file (see: https://github.com/microsoft/TeamCloud/blob/master/docs/teamcloud.yaml)
             * - Possibly save (cache) the file in storage
             * - Parse the file into the TeamCloudConfiguraiton
             * - ...
             */
        }
Ejemplo n.º 10
0
        public async Task <TeamCloudInstance> RunActivity(
            [ActivityTrigger] TeamCloudConfiguration teamCloudConfiguration)
        {
            if (teamCloudConfiguration is null)
            {
                throw new ArgumentNullException(nameof(teamCloudConfiguration));
            }

            var teamCloudInstance = new TeamCloudInstance(teamCloudConfiguration);

            var teamCloud = await teamCloudRepository
                            .SetAsync(teamCloudInstance)
                            .ConfigureAwait(false);

            foreach (var projectType in teamCloudConfiguration.ProjectTypes)
            {
                await projectTypesRepository
                .AddAsync(projectType)
                .ConfigureAwait(false);
            }

            return(teamCloud);
        }
Ejemplo n.º 11
0
 public IAsyncEnumerable <Project> RunActivity(
     [ActivityTrigger] TeamCloudInstance teamCloud)
 {
     return(projectsRepository.ListAsync());
 }
Ejemplo n.º 12
0
        public static Task <TeamCloudInstance> SetTeamCloudAsync(this IDurableOrchestrationContext durableOrchestrationContext, TeamCloudInstance teamCloud)
        {
            if (teamCloud is null)
            {
                throw new ArgumentNullException(nameof(teamCloud));
            }

            if (durableOrchestrationContext.IsLocked(out var ownedLocks) && ownedLocks.Contains(teamCloud.GetEntityId()))
            {
                return(durableOrchestrationContext
                       .CallActivityWithRetryAsync <TeamCloudInstance>(nameof(TeamCloudSetActivity), teamCloud));
            }

            throw new NotSupportedException($"Unable to set '{typeof(TeamCloudInstance)}' without acquired lock");
        }
Ejemplo n.º 13
0
        public static Task <TeamCloudInstance> SetTeamCloudAsync(this IDurableOrchestrationContext functionContext, TeamCloudInstance teamCloud)
        {
            if (teamCloud is null)
            {
                throw new ArgumentNullException(nameof(teamCloud));
            }

            if (functionContext.IsLockedByContainerDocument(teamCloud))
            {
                return(functionContext
                       .CallActivityWithRetryAsync <TeamCloudInstance>(nameof(TeamCloudSetActivity), teamCloud));
            }

            throw new NotSupportedException($"Unable to set '{typeof(TeamCloudInstance)}' without acquired lock");
        }
Ejemplo n.º 14
0
        public static async Task RunOrchestration(
            [OrchestrationTrigger] IDurableOrchestrationContext functionContext,
            ILogger log)
        {
            if (functionContext is null)
            {
                throw new ArgumentNullException(nameof(functionContext));
            }

            var(provider, command) = functionContext
                                     .GetInput <(Provider, ProviderRegisterCommand)>();

            TeamCloudInstance teamCloud = null;

            try
            {
                if (command is null)
                {
                    // no command was given !!!
                    // restart the orchestration
                    // with a new command instance.

                    var systemUser = await functionContext
                                     .CallActivityWithRetryAsync <User>(nameof(TeamCloudUserActivity), null)
                                     .ConfigureAwait(true);

                    functionContext
                    .ContinueAsNew((provider, new ProviderRegisterCommand(systemUser, new ProviderConfiguration())));
                }
                else if (provider is null)
                {
                    // no provider was given !!!
                    // fan out registration with
                    // one orchestration per provider.

                    functionContext.SetCustomStatus($"Register providers ...", log);

                    teamCloud = await functionContext
                                .GetTeamCloudAsync()
                                .ConfigureAwait(true);

                    var tasks = teamCloud.Providers
                                .Select(provider => functionContext.CallSubOrchestratorWithRetryAsync(nameof(OrchestratorProviderRegisterCommandOrchestration), (provider, command)));

                    await Task
                    .WhenAll(tasks)
                    .ConfigureAwait(true);
                }
                else
                {
                    teamCloud = await functionContext
                                .GetTeamCloudAsync()
                                .ConfigureAwait(true);

                    command.Payload
                    .TeamCloudApplicationInsightsKey = Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");

                    command.Payload
                    .Properties = teamCloud.Properties.Override(provider.Properties);

                    var commandResult = await functionContext
                                        .SendCommandAsync <ProviderRegisterCommand, ProviderRegisterCommandResult>(command, provider)
                                        .ConfigureAwait(true);

                    if (commandResult?.Result != null)
                    {
                        using (await functionContext.LockAsync(teamCloud).ConfigureAwait(true))
                        {
                            teamCloud = await functionContext
                                        .GetTeamCloudAsync()
                                        .ConfigureAwait(true);

                            provider = teamCloud.Providers
                                       .FirstOrDefault(p => p.Id == provider.Id);

                            if (provider is null)
                            {
                                log.LogWarning($"Provider '{provider.Id}' registration skipped - provider no longer exists");
                            }
                            else
                            {
                                provider.PrincipalId = commandResult.Result.PrincipalId;
                                provider.Registered  = functionContext.CurrentUtcDateTime;
                                provider.Properties  = provider.Properties.Override(commandResult.Result.Properties);

                                teamCloud = await functionContext
                                            .SetTeamCloudAsync(teamCloud)
                                            .ConfigureAwait(true);

                                functionContext.SetCustomStatus($"Provider '{provider.Id}' registration succeeded", log);
                            }
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                if (provider != null)
                {
                    functionContext.SetCustomStatus($"Failed to register provider '{provider.Id}' - {exc.Message}", log, exc);
                }
                else if (command != null)
                {
                    functionContext.SetCustomStatus($"Failed to register providers - {exc.Message}", log, exc);
                }
                else
                {
                    functionContext.SetCustomStatus($"Failed to initiate provider registration - {exc.Message}", log, exc);
                }
            }
        }
Ejemplo n.º 15
0
 public OrchestratorContext(TeamCloudInstance teamCloud, Project project = null)
 {
     TeamCloud = teamCloud;
     Project   = project;
 }