private void ConnectTenantsToProjectsAndEnvironments( ProjectResource[] allProjects, SourceEnvironmentToTenantMap sourceEnvironmentToTenantEnvironmentMap, SourceToTargetEnvironmentMap sourceToTargetEnvironmentMap) { var allChannels = Repository.Channels.FindAll(); var allLifecycles = Repository.Lifecycles.FindAll(); var tenants = Repository.Tenants.Get(sourceEnvironmentToTenantEnvironmentMap.TenantIds); foreach (var project in allProjects) { var projectChannels = allChannels.Where(c => c.ProjectId == project.Id); var projectChannelLifecycleIds = projectChannels.Select(c => c.LifecycleId).Where(id => id != null); var connectedLifecycleIds = new[] { project.LifecycleId }.Concat(projectChannelLifecycleIds).Distinct().ToArray(); var connectedLifecycles = allLifecycles.Where(l => connectedLifecycleIds.Contains(l.Id)).ToArray(); foreach (var tenant in tenants) { // Figure out if any "environments pretending to be this tenant" were connected to this project var connectedSourceEnvironmentsForTenant = sourceEnvironmentToTenantEnvironmentMap.GetSourceEnvironmentsForTenants(tenant) .Where(source => connectedLifecycles.Any(l => LifecycleContainsAnyOfTheseEnvironments(l, source))) .ToArray(); if (connectedSourceEnvironmentsForTenant.Any()) { var targetEnvironmentsForTenant = sourceToTargetEnvironmentMap.GetTargetEnvironmentsForSources(connectedSourceEnvironmentsForTenant); Log.Information("Connecting {Tenant} to {Project} deploying to {Environments}", tenant.Name, project.Name, targetEnvironmentsForTenant.Select(e => e.Name)); tenant.ConnectToProjectAndEnvironments(project, targetEnvironmentsForTenant); } } } // Ensure each tenanted project is configured for tenanted deployments // NOTE: Do this before attempting to connect tenants to avoid validation issues var tenantedProjects = allProjects.Where(p => tenants.SelectMany(t => t.ProjectEnvironments.Select(pe => pe.Key)).Contains(p.Id)).ToArray(); foreach (var tenantedProject in tenantedProjects) { if (tenantedProject.TenantedDeploymentMode == ProjectTenantedDeploymentMode.Untenanted) { tenantedProject.TenantedDeploymentMode = ProjectTenantedDeploymentMode.TenantedOrUntenanted; Log.Information("Changing {Project} TenantedDeploymentMode to {Mode}", tenantedProject.Name, tenantedProject.TenantedDeploymentMode); Repository.Projects.Modify(tenantedProject); } } // Save all of the tenants now we've connected them to the project/environment combinations foreach (var tenant in tenants) { Repository.Tenants.Modify(tenant); } }
public TenantToProjectAndTargetEnvironmentsMap(IOctopusRepository repository, SourceEnvironmentToTenantMap sourceEnvironmentToTenantEnvironmentMap, SourceToTargetEnvironmentMap sourceToTargetEnvironmentMap) { var allProjects = repository.Projects.GetAll(); var allChannels = repository.Channels.FindAll(); var allLifecycles = repository.Lifecycles.FindAll(); var tenants = sourceEnvironmentToTenantEnvironmentMap.GetAllTenants(); map = allProjects.Select(project => { var projectChannels = allChannels.Where(c => c.ProjectId == project.Id); var projectChannelLifecycleIds = projectChannels.Select(c => c.LifecycleId).Where(id => id != null); var connectedLifecycleIds = new[] { project.LifecycleId }.Concat(projectChannelLifecycleIds) .Distinct().ToArray(); var connectedLifecycles = allLifecycles.Where(l => connectedLifecycleIds.Contains(l.Id)).ToArray(); tenants.Select(tenant => { // Figure out if any "environments pretending to be this tenant" were connected to this project var connectedSourceEnvironmentsForTenant = sourceEnvironmentToTenantEnvironmentMap .GetSourceEnvironmentsForTenants(tenant) .Where(source => connectedLifecycles.Any( l => LifecycleContainsAnyOfTheseEnvironments(l, source))) .ToArray(); if (connectedSourceEnvironmentsForTenant.Any()) { var targetEnvironmentsForTenant = sourceToTargetEnvironmentMap.GetTargetEnvironmentsForSources( connectedSourceEnvironmentsForTenant); Log.Information("Connecting {Tenant} to {Project} deploying to {Environments}", tenant.Name, project.Name, targetEnvironmentsForTenant.Select(e => e.Name)); tenant.ConnectToProjectAndEnvironments(project, targetEnvironmentsForTenant); } }); }); }