示例#1
0
 public SecretInputBinding(string name, string filename, ServiceEntry service, ServiceBinding binding)
 {
     Name     = name;
     Filename = filename;
     Service  = service;
     Binding  = binding;
 }
示例#2
0
        public static Application ToHostingApplication(this ApplicationBuilder application)
        {
            var services = new Dictionary <string, Service>();

            foreach (var service in application.Services)
            {
                RunInfo?runInfo;
                Probe?  liveness;
                Probe?  readiness;
                int     replicas;
                var     env = new List <EnvironmentVariable>();
                if (service is ExternalServiceBuilder)
                {
                    runInfo   = null;
                    liveness  = null;
                    readiness = null;
                    replicas  = 1;
                }
                else if (service is DockerFileServiceBuilder dockerFile)
                {
                    var dockerRunInfo = new DockerRunInfo(dockerFile.Image, dockerFile.Args)
                    {
                        IsAspNet  = dockerFile.IsAspNet,
                        BuildArgs = dockerFile.BuildArgs
                    };

                    if (!string.IsNullOrEmpty(dockerFile.DockerFile))
                    {
                        dockerRunInfo.DockerFile = new FileInfo(dockerFile.DockerFile);
                        if (!string.IsNullOrEmpty(dockerFile.DockerFileContext))
                        {
                            dockerRunInfo.DockerFileContext = new FileInfo(dockerFile.DockerFileContext);
                        }
                        else
                        {
                            dockerRunInfo.DockerFileContext = new FileInfo(dockerRunInfo.DockerFile.DirectoryName !);
                        }
                    }

                    foreach (var mapping in dockerFile.Volumes)
                    {
                        dockerRunInfo.VolumeMappings.Add(new DockerVolume(mapping.Source, mapping.Name, mapping.Target));
                    }

                    runInfo  = dockerRunInfo;
                    replicas = dockerFile.Replicas;
                    liveness = dockerFile.Liveness != null?GetProbeFromBuilder(dockerFile.Liveness) : null;

                    readiness = dockerFile.Readiness != null?GetProbeFromBuilder(dockerFile.Readiness) : null;

                    foreach (var entry in dockerFile.EnvironmentVariables)
                    {
                        env.Add(entry.ToHostingEnvironmentVariable());
                    }
                }

                else if (service is ContainerServiceBuilder container)
                {
                    var dockerRunInfo = new DockerRunInfo(container.Image, container.Args)
                    {
                        IsAspNet = container.IsAspNet
                    };

                    foreach (var mapping in container.Volumes)
                    {
                        dockerRunInfo.VolumeMappings.Add(new DockerVolume(mapping.Source, mapping.Name, mapping.Target));
                    }

                    runInfo  = dockerRunInfo;
                    replicas = container.Replicas;
                    liveness = container.Liveness != null?GetProbeFromBuilder(container.Liveness) : null;

                    readiness = container.Readiness != null?GetProbeFromBuilder(container.Readiness) : null;

                    foreach (var entry in container.EnvironmentVariables)
                    {
                        env.Add(entry.ToHostingEnvironmentVariable());
                    }
                }
                else if (service is ExecutableServiceBuilder executable)
                {
                    runInfo  = new ExecutableRunInfo(executable.Executable, executable.WorkingDirectory, executable.Args);
                    replicas = executable.Replicas;
                    liveness = executable.Liveness != null?GetProbeFromBuilder(executable.Liveness) : null;

                    readiness = executable.Readiness != null?GetProbeFromBuilder(executable.Readiness) : null;

                    foreach (var entry in executable.EnvironmentVariables)
                    {
                        env.Add(entry.ToHostingEnvironmentVariable());
                    }
                }
                else if (service is DotnetProjectServiceBuilder project)
                {
                    if (project.RunCommand == null)
                    {
                        throw new InvalidOperationException($"Unable to run {project.Name}. The project does not have a run command");
                    }

                    var projectInfo = new ProjectRunInfo(project);

                    foreach (var mapping in project.Volumes)
                    {
                        projectInfo.VolumeMappings.Add(new DockerVolume(mapping.Source, mapping.Name, mapping.Target));
                    }

                    runInfo  = projectInfo;
                    replicas = project.Replicas;
                    liveness = project.Liveness != null?GetProbeFromBuilder(project.Liveness) : null;

                    readiness = project.Readiness != null?GetProbeFromBuilder(project.Readiness) : null;

                    foreach (var entry in project.EnvironmentVariables)
                    {
                        env.Add(entry.ToHostingEnvironmentVariable());
                    }
                }
                else if (service is AzureFunctionServiceBuilder function)
                {
                    var functionInfo = new AzureFunctionRunInfo(function);

                    runInfo   = functionInfo;
                    replicas  = function.Replicas;
                    liveness  = null;
                    readiness = null;

                    foreach (var entry in function.EnvironmentVariables)
                    {
                        env.Add(entry.ToHostingEnvironmentVariable());
                    }
                }
                else
                {
                    throw new InvalidOperationException($"Cannot figure out how to run service '{service.Name}'.");
                }

                var description = new ServiceDescription(service.Name, runInfo)
                {
                    Replicas  = replicas,
                    Liveness  = liveness,
                    Readiness = readiness
                };

                description.Configuration.AddRange(env);
                description.Dependencies.AddRange(service.Dependencies);

                foreach (var binding in service.Bindings)
                {
                    var sb = new ServiceBinding()
                    {
                        ConnectionString = binding.ConnectionString,
                        Host             = binding.Host,
                        ContainerPort    = binding.ContainerPort,
                        Name             = binding.Name,
                        Port             = binding.Port,
                        Protocol         = binding.Protocol,
                    };
                    sb.Routes.AddRange(binding.Routes);
                    description.Bindings.Add(sb);
                }

                services.Add(service.Name, new Service(description, service.Source));
            }

            // Ingress get turned into services for hosting
            foreach (var ingress in application.Ingress)
            {
                var rules = new List <IngressRule>();

                foreach (var rule in ingress.Rules)
                {
                    rules.Add(new IngressRule(rule.Host, rule.Path, rule.Service !, rule.PreservePath));
                }

                var runInfo = new IngressRunInfo(rules);

                var description = new ServiceDescription(ingress.Name, runInfo)
                {
                    Replicas = ingress.Replicas,
                };

                foreach (var binding in ingress.Bindings)
                {
                    description.Bindings.Add(new ServiceBinding()
                    {
                        Name      = binding.Name,
                        Port      = binding.Port,
                        Protocol  = binding.Protocol,
                        IPAddress = binding.IPAddress,
                    });
                }

                services.Add(ingress.Name, new Service(description, ServiceSource.Host));
            }

            return(new Application(application.Name, application.Source, application.DashboardPort, services, application.ContainerEngine)
            {
                Network = application.Network,
                BuildSolution = application.BuildSolution
            });
        }
示例#3
0
        internal static async Task<TemporaryApplicationAdapter> CreateApplicationAdapterAsync(OutputContext output, ConfigApplication application, bool interactive, bool requireRegistry)
        {
            var globals = new ApplicationGlobals()
            {
                Name = application.Name,
                Registry = application.Registry is null ? null : new ContainerRegistry(application.Registry),
            };

            var services = new List<Tye.ServiceEntry>();
            foreach (var configService in application.Services)
            {
                if (configService.Project is string projectFile)
                {
                    var fullPathProjectFile = Path.Combine(application.Source.DirectoryName, projectFile);
                    var project = new Project(fullPathProjectFile);
                    var service = new Service(configService.Name)
                    {
                        Source = project,
                    };

                    service.Replicas = configService.Replicas ?? 1;

                    foreach (var configBinding in configService.Bindings)
                    {
                        var binding = new ServiceBinding(configBinding.Name ?? service.Name)
                        {
                            ConnectionString = configBinding.ConnectionString,
                            Host = configBinding.Host,
                            Port = configBinding.Port,
                            Protocol = configBinding.Protocol,
                        };

                        binding.Protocol ??= "http";

                        if (binding.Port == null && configBinding.AutoAssignPort)
                        {
                            if (binding.Protocol == "http" || binding.Protocol == null)
                            {
                                binding.Port = 80;
                            }
                            else if (binding.Protocol == "https")
                            {
                                binding.Port = 443;
                            }
                        }

                        service.Bindings.Add(binding);
                    }

                    var serviceEntry = new ServiceEntry(service, configService.Name);

                    await ProjectReader.ReadProjectDetailsAsync(output, new FileInfo(fullPathProjectFile), project);

                    var container = new ContainerInfo()
                    {
                        UseMultiphaseDockerfile = false,
                    };
                    service.GeneratedAssets.Container = container;
                    services.Add(serviceEntry);
                }
                else
                {
                    // For a non-project, we don't really need much info about it, just the name and bindings
                    var service = new Service(configService.Name);
                    foreach (var configBinding in configService.Bindings)
                    {
                        service.Bindings.Add(new ServiceBinding(configBinding.Name ?? service.Name)
                        {
                            ConnectionString = configBinding.ConnectionString,
                            Host = configBinding.Host,
                            Port = configBinding.Port,
                            Protocol = configBinding.Protocol,
                        });
                    }

                    var serviceEntry = new ServiceEntry(service, configService.Name);
                    services.Add(serviceEntry);
                }
            }

            var temporaryApplication = new TemporaryApplicationAdapter(application, globals, services);
            if (temporaryApplication.Globals.Registry?.Hostname == null && interactive)
            {
                var registry = output.Prompt("Enter the Container Registry (ex: 'example.azurecr.io' for Azure or 'example' for dockerhub)", allowEmpty: !requireRegistry);
                if (!string.IsNullOrWhiteSpace(registry))
                {
                    temporaryApplication.Globals.Registry = new ContainerRegistry(registry.Trim());
                }
            }
            else if (temporaryApplication.Globals.Registry?.Hostname == null && requireRegistry)
            {
                throw new CommandException("A registry is required for deploy operations. Add the registry to 'tye.yaml' or use '-i' for interactive mode.");
            }
            else
            {
                // No registry specified, and that's OK!
            }

            foreach (var service in temporaryApplication.Services)
            {
                if (service.Service.Source is Project project && service.Service.GeneratedAssets.Container is ContainerInfo container)
                {
                    DockerfileGenerator.ApplyContainerDefaults(temporaryApplication, service, project, container);
                }
            }

            return temporaryApplication;
        }