Пример #1
0
        public async Task ValidateAsync_Error()
        {
            var command = new ProviderProjectCreateCommand(null, new Project());
            var message = new ProviderCommandMessage(command, "http://localhost/callback");

            var result = await message.ValidateAsync().ConfigureAwait(false);

            Assert.False(result.IsValid);
        }
Пример #2
0
        public void Validate_Error()
        {
            var command = new ProviderProjectCreateCommand(null, new Project());
            var message = new ProviderCommandMessage(command, "http://localhost/callback");

            var result = message.Validate();

            Assert.False(result.IsValid);
        }
Пример #3
0
        public void Validate_Success()
        {
            var command = new ProviderProjectCreateCommand(new User(), new Project());
            var message = new ProviderCommandMessage(command, "http://localhost/callback");

            var result = message.Validate();

            Assert.True(result.IsValid);
        }
Пример #4
0
        public static async Task <Dictionary <string, string> > RunActivity(
            [ActivityTrigger] ProviderProjectCreateCommand command,
            ILogger log)
        {
            if (command is null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            return(new Dictionary <string, string>());
        }
Пример #5
0
        private async Task AssertResourceGroupAsync(ProviderProjectCreateCommand command)
        {
            var resourceGroup = await AzureResourceService
                                .GetResourceGroupAsync(ResourceGroupSubscriptionId.Value, ResourceGroupName, true)
                                .ConfigureAwait(false);

            var resources = await resourceGroup.GetResourcesAsync()
                            .ToListAsync()
                            .ConfigureAwait(false);

            var resource = resources
                           .SingleOrDefault(resource => resource.ResourceId.ResourceTypeFullName.Equals("microsoft.devtestlab/labs", StringComparison.OrdinalIgnoreCase));

            Assert.NotNull(resource);

            foreach (var user in command.Payload.Users)
            {
                switch (user.ProjectMembership(command.Payload.Id.ToString()).Role)
                {
                case ProjectUserRole.Owner:

                    await resource
                    .ShouldHaveRoleAssignmentAsync(user, AzureRoleDefinition.Contributor)
                    .ConfigureAwait(false);

                    break;

                case ProjectUserRole.Member:

                    await resource
                    .ShouldHaveRoleAssignmentAsync(user, AzureRoleDefinition.DevTestLabUser)
                    .ConfigureAwait(false);

                    break;

                case ProjectUserRole.None:

                    await resource
                    .ShouldHaveNoRoleAssignmentAsync(user)
                    .ConfigureAwait(false);

                    break;
                }
                ;
            }
        }
Пример #6
0
        public async Task <Dictionary <string, string> > RunActivity(
            [ActivityTrigger] ProviderProjectCreateCommand command,
            ILogger log)
        {
            if (command is null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var vnetPrefix = "10.0.0.0/16";
            var snetPrefix = new object[]
            {
                new
                {
                    subnetname   = "TeamCloud",
                    subnetprefix = "10.0.0.0/24"
                },
                new
                {
                    subnetname   = "AzureBastionSubnet",
                    subnetprefix = "10.0.1.0/24"
                }
            };

            var template = new ProjectCreateTemplate();

            template.Parameters["ProjectName"] = command.Payload.Name;
            //template.Parameters["Repositories"] = Array.Empty<object>();
            //template.Parameters["ImageGallery"] = "";
            template.Parameters["LabPublicEnvironments"] = "Enabled";
            template.Parameters["LabPublicArtifacts"]    = "Enabled";
            template.Parameters["LabVNetPrefix"]         = vnetPrefix;
            template.Parameters["LabSNetPrefix"]         = snetPrefix;

            var deployment = await azureDeploymentService
                             .DeployResourceGroupTemplateAsync(template, command.Payload.ResourceGroup.SubscriptionId, command.Payload.ResourceGroup.ResourceGroupName)
                             .ConfigureAwait(false);

            var deploymentOutput = await deployment
                                   .WaitAndGetOutputAsync(throwOnError : true)
                                   .ConfigureAwait(false);

            return(deploymentOutput
                   .ToDictionary(kvp => kvp.Key, kvp => kvp.Value?.ToString()));
        }
Пример #7
0
        public async Task <Dictionary <string, string> > RunActivity(
            [ActivityTrigger] ProviderProjectCreateCommand command,
            ILogger log)
        {
            if (command is null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var template = new ProjectCreateTemplate();

            template.Parameters["ProjectName"] = command.Payload.Name;

            var deployment = await azureDeploymentService
                             .DeployResourceGroupTemplateAsync(template, command.Payload.ResourceGroup.SubscriptionId, command.Payload.ResourceGroup.ResourceGroupName)
                             .ConfigureAwait(false);

            var deploymentOutput = await deployment
                                   .WaitAndGetOutputAsync(throwOnError : true)
                                   .ConfigureAwait(false);

            return(deploymentOutput
                   .ToDictionary(kvp => kvp.Key, kvp => kvp.Value?.ToString()));
        }
Пример #8
0
        private static async Task <OrchestratorProjectCreateCommandResult> ProvisionAsync(IDurableOrchestrationContext functionContext, OrchestratorProjectCreateCommand command, ILogger log)
        {
            var teamCloud = await functionContext
                            .GetTeamCloudAsync()
                            .ConfigureAwait(true);

            var commandResult = command.CreateResult();

            var project = commandResult.Result = command.Payload;

            project.Tags = teamCloud.Tags.Override(project.Tags);

            var projectUsers = project.Users.ToList();

            var providers = await functionContext
                            .ListProvidersAsync(project.Type.Providers.Select(p => p.Id).ToList())
                            .ConfigureAwait(true);

            var providerUserTasks = providers
                                    .Where(p => p.PrincipalId.HasValue)
                                    .Select(p => functionContext.GetUserAsync(p.PrincipalId.Value.ToString(), allowUnsafe: true));

            var providerUsers = await Task.WhenAll(providerUserTasks)
                                .ConfigureAwait(true);

            foreach (var u in providerUsers)
            {
                u.EnsureProjectMembership(project.Id, ProjectUserRole.Provider);
            }

            projectUsers.AddRange(providerUsers);

            using (await functionContext.LockContainerDocumentAsync(project).ConfigureAwait(true))
            {
                functionContext.SetCustomStatus($"Creating project", log);

                project = commandResult.Result = await functionContext
                                                 .CreateProjectAsync(project)
                                                 .ConfigureAwait(true);

                functionContext.SetCustomStatus($"Adding users", log);

                project.Users = await Task
                                .WhenAll(projectUsers.Select(user => functionContext.SetUserProjectMembershipAsync(user, project.Id, allowUnsafe: true)))
                                .ConfigureAwait(true);
            }

            functionContext.SetCustomStatus($"Allocating subscription", log);

            var subscriptionId = await functionContext
                                 .CallActivityWithRetryAsync <Guid>(nameof(ProjectSubscriptionSelectActivity), project)
                                 .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Initializing subscription", log);

            await functionContext
            .InitializeSubscriptionAsync(subscriptionId, waitFor : false)
            .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Provisioning resources", log);

            var deploymentOutput = await functionContext
                                   .CallDeploymentAsync(nameof(ProjectResourcesCreateActivity), (project, subscriptionId))
                                   .ConfigureAwait(true);

            using (await functionContext.LockContainerDocumentAsync(project).ConfigureAwait(true))
            {
                functionContext.SetCustomStatus($"Provisioning identity", log);

                project.Identity = await functionContext
                                   .CallActivityWithRetryAsync <ProjectIdentity>(nameof(ProjectIdentityCreateActivity), project)
                                   .ConfigureAwait(true);

                project.ResourceGroup = new AzureResourceGroup()
                {
                    SubscriptionId = subscriptionId,
                    Region         = project.Type.Region,
                    Id             = (string)deploymentOutput.GetValueOrDefault("resourceGroupId", default(string)),
                    Name           = (string)deploymentOutput.GetValueOrDefault("resourceGroupName", default(string))
                };

                project = commandResult.Result = await functionContext
                                                 .SetProjectAsync(project)
                                                 .ConfigureAwait(true);
            }

            functionContext.SetCustomStatus($"Tagging resources", log);

            await functionContext
            .CallActivityWithRetryAsync(nameof(ProjectResourcesTagActivity), project)
            .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Registering required resource providers", log);

            await functionContext
            .RegisterResourceProvidersAsync(project)
            .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Sending provider commands", log);

            var providerCommand = new ProviderProjectCreateCommand
                                  (
                command.User.PopulateExternalModel(),
                project.PopulateExternalModel(),
                command.CommandId
                                  );

            var providerResults = await functionContext
                                  .SendProviderCommandAsync <ProviderProjectCreateCommand, ProviderProjectCreateCommandResult>(providerCommand, project, failFast : true)
                                  .ConfigureAwait(true);

            var providerException = providerResults.Values?
                                    .SelectMany(result => result.Errors ?? new List <CommandError>())
                                    .ToException();

            if (providerException != null)
            {
                throw providerException;
            }

            return(commandResult);
        }