Beispiel #1
0
        public async Task <IProvisioningJob> Handle(ProvisionDogfeedInstanceCommand request, CancellationToken cancellationToken)
        {
            var dogfeedOptions = this.dogfeedOptionsMonitor.CurrentValue;

            if (dogfeedOptions.DockerComposeYmlFilePaths == null)
            {
                throw new InvalidOperationException("Could not find Docker Compose YML contents.");
            }

            var dockerHubOptions = dogfeedOptions.DockerHub;

            if (dockerHubOptions?.Username == null)
            {
                throw new InvalidOperationException("Could not find Docker Hub username.");
            }

            if (dockerHubOptions.Password == null)
            {
                throw new InvalidOperationException("Could not find Docker Hub password.");
            }

            var cluster = await mediator.Send(new EnsureClusterWithIdCommand(DataContext.DoggerClusterId), cancellationToken);

            var firstCapablePlan = await GetDogfeedingPlanAsync();

            var instance = new Instance()
            {
                Name          = request.InstanceName,
                Cluster       = cluster,
                IsProvisioned = false,
                PlanId        = firstCapablePlan.Id
            };

            cluster.Instances.Add(instance);
            await this.dataContext.Instances.AddAsync(instance, cancellationToken);

            await this.dataContext.SaveChangesAsync(cancellationToken);

            var dockerFiles = await GetDockerFilesAsync(dogfeedOptions);

            return(await this.provisioningService.ScheduleJobAsync(
                       new AggregateProvisioningStateFlow(
                           new ProvisionInstanceStateFlow(
                               firstCapablePlan.Id,
                               instance),
                           new DeployToClusterStateFlow(
                               request.InstanceName,
                               SanitizeDockerComposeYmlFilePaths(dogfeedOptions.DockerComposeYmlFilePaths))
            {
                Files = dockerFiles,
                Authentication = new[] {
                    new DockerAuthenticationArguments(
                        username: dockerHubOptions.Username,
                        password: dockerHubOptions.Password)
                }
            })));
        }
Beispiel #2
0
        private async Task RemoveInstanceFromDatabaseAsync(
            Instance instance,
            CancellationToken cancellationToken)
        {
            var cluster = instance.Cluster;

            cluster.Instances.Remove(instance);

            if (instance.PullDogPullRequest != null)
            {
                this.dataContext.PullDogPullRequests.Remove(instance.PullDogPullRequest);
            }

            if (cluster.Instances.Count == 0)
            {
                this.dataContext.Clusters.Remove(cluster);
            }

            this.dataContext.Instances.Remove(instance);

            await this.dataContext.SaveChangesAsync(cancellationToken);
        }
        public async Task Handle_ProvisionedNonFreeInstancePresent_SubscriptionIsUpdated()
        {
            //Arrange
            var fakeInstanceId = Guid.NewGuid();

            var fakeAmazonLightsailClient = Substitute.For <IAmazonLightsail>();

            fakeAmazonLightsailClient
            .DeleteInstanceAsync(
                Arg.Any <DeleteInstanceRequest>(),
                default)
            .Returns(new DeleteInstanceResponse()
            {
                Operations = new List <Operation>()
            });

            var fakeLightsailOperationService = Substitute.For <ILightsailOperationService>();

            await using var environment = await IntegrationTestEnvironment.CreateAsync(new EnvironmentSetupOptions ()
            {
                IocConfiguration = services =>
                {
                    services.AddSingleton(fakeAmazonLightsailClient);
                    services.AddSingleton(fakeLightsailOperationService);
                }
            });

            var stripeCustomerService = environment.ServiceProvider.GetRequiredService <CustomerService>();
            var customer = await stripeCustomerService.CreateAsync(new CustomerCreateOptions()
            {
                Email = "*****@*****.**"
            });

            var stripePaymentMethodService = environment.ServiceProvider.GetRequiredService <PaymentMethodService>();
            var paymentMethod = await stripePaymentMethodService.AttachAsync("pm_card_visa", new PaymentMethodAttachOptions()
            {
                Customer = customer.Id
            });

            var stripeSubscriptionService = environment.ServiceProvider.GetRequiredService <SubscriptionService>();
            var subscription = await stripeSubscriptionService.CreateAsync(new SubscriptionCreateOptions()
            {
                Customer             = customer.Id,
                DefaultPaymentMethod = paymentMethod.Id,
                Items = new List <SubscriptionItemOptions>()
                {
                    new SubscriptionItemOptions()
                    {
                        Plan = "nano_2_0"
                    }
                },
                Metadata = new Dictionary <string, string>()
                {
                    {
                        "InstanceId", fakeInstanceId.ToString()
                    }
                }
            });

            var clusterId = Guid.NewGuid();
            var user      = new User()
            {
                StripeCustomerId     = customer.Id,
                StripeSubscriptionId = subscription.Id
            };

            var cluster = new Cluster()
            {
                Id     = clusterId,
                User   = user,
                UserId = user.Id
            };

            user.Clusters.Add(cluster);

            var instance = new Instance()
            {
                Id            = fakeInstanceId,
                Name          = "some-instance-name",
                PlanId        = "dummy",
                Cluster       = cluster,
                ClusterId     = cluster.Id,
                IsProvisioned = true
            };

            cluster.Instances.Add(instance);

            await environment.WithFreshDataContext(async dataContext =>
            {
                await dataContext.Clusters.AddAsync(cluster);
                await dataContext.Instances.AddAsync(instance);
                await dataContext.Users.AddAsync(user);
            });

            //Act
            await environment.Mediator.Send(
                new DeleteInstanceByNameCommand("some-instance-name"),
                default);

            //Assert
            var refreshedSubscription = await stripeSubscriptionService.GetAsync(subscription.Id);

            Assert.AreNotEqual(refreshedSubscription.Status, subscription.Status);
            Assert.AreEqual("canceled", refreshedSubscription.Status);
        }