示例#1
0
 public static Task RunDFrameControllerAsync(this WebApplicationBuilder appBuilder, DFrameControllerOptions options)
 {
     return(RunDFrameControllerAsync(appBuilder, options, (_, __) => { }));
 }
 public ModuleInstallerTests()
 {
     _sut = WebApplication.CreateBuilder();
 }
示例#3
0
文件: Program.cs 项目: Coca162/Valour
        public static void ConfigureServices(WebApplicationBuilder builder)
        {
            var services = builder.Services;

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAll", builder =>
                {
                    builder
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .SetIsOriginAllowed(_ => true)
                    .AllowCredentials()
                    .WithOrigins(
                        "https://www.valour.gg",
                        "http://www.valour.gg",
                        "https://valour.gg",
                        "http://valour.gg",
                        "https://api.valour.gg",
                        "http://api.valour.gg",
                        "http://localhost:3000",
                        "https://localhost:3000",
                        "http://localhost:3001",
                        "https://localhost:3001");
                });
            });

            services.AddSignalR();

            var mapConfig = new MapperConfiguration(x =>
            {
                x.AddProfile(new MappingProfile());
            });

            IMapper mapper = mapConfig.CreateMapper();

            services.AddSingleton(mapper);

            services.AddHttpClient();

            MappingManager.Mapper = mapper;

            services.AddDbContextPool <ValourDB>(options =>
            {
                options.UseMySql(ValourDB.ConnectionString, ServerVersion.Parse("8.0.20-mysql"), options => options.EnableRetryOnFailure());
            });

            // This probably needs to be customized further but the documentation changed
            services.AddAuthentication().AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);

            // Adds user manager to dependency injection
            services.AddScoped <UserManager>();
            IdManager idManager = new();

            services.AddSingleton(idManager);
            services.AddSingleton <WebPushClient>();
            services.AddControllersWithViews().AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
                //options.JsonSerializerOptions.PropertyNameCaseInsensitive = false;
                options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;

                options.JsonSerializerOptions.PropertyNamingPolicy = null;
            }
                                                              );
            services.AddRazorPages();
            services.AddHostedService <MessageCacheWorker>();
            services.AddHostedService <PlanetMessageWorker>();
            services.AddHostedService <StatWorker>();

            services.AddEndpointsApiExplorer();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo {
                    Title = "Valour API", Description = "The official Valour API", Version = "v1.0"
                });
                c.AddSecurityDefinition("Token", new OpenApiSecurityScheme()
                {
                    Description = "The token used for authorizing your account.",
                    In          = ParameterLocation.Header,
                    Type        = SecuritySchemeType.ApiKey,
                    Scheme      = "Token"
                });
            });
        }
    /// <summary>
    /// Configure Configuration/ServiceCollection/Logging/WebHost(Kestrel)
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="args"></param>
    /// <param name="webApiAssembly"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static WebApplicationBuilder ConfigureAdncDefault(this WebApplicationBuilder builder, IServiceInfo serviceInfo)
    {
        if (builder is null)
        {
            throw new ArgumentNullException(nameof(builder));
        }
        if (serviceInfo is null)
        {
            throw new ArgumentNullException(nameof(serviceInfo));
        }

        // Configuration
        //builder.Configuration.AddCommandLine(args);
        var initialData = new List <KeyValuePair <string, string> > {
            new KeyValuePair <string, string>("ServiceName", serviceInfo.ServiceName)
        };

        builder.Configuration.AddInMemoryCollection(initialData);
        builder.Configuration.AddJsonFile($"{AppContext.BaseDirectory}/appsettings.shared.{builder.Environment.EnvironmentName}.json", true, true);
        builder.Configuration.AddJsonFile($"{AppContext.BaseDirectory}/appsettings.{builder.Environment.EnvironmentName}.json", true, true);
        if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
        {
            var consulSection = builder.Configuration.GetSection(ConsulConfig.Name);
            if (consulSection is null)
            {
                throw new NullReferenceException(nameof(consulSection));
            }

            var consulOption = consulSection.Get <ConsulConfig>();
            if (consulOption is null)
            {
                throw new NullReferenceException(nameof(consulOption));
            }

            consulOption.ConsulKeyPath = consulOption.ConsulKeyPath.Replace("$SHORTNAME", serviceInfo.ShortName);
            builder.Configuration.AddConsulConfiguration(consulOption, true);
        }
        OnSettingConfigurationChanged(builder.Configuration);

        //ServiceCollection
        builder.Services.ReplaceConfiguration(builder.Configuration);
        builder.Services.AddSingleton(typeof(IServiceInfo), serviceInfo);
        builder.Services.AddAdnc(serviceInfo);

        //Logging
        builder.Logging.ClearProviders();
        var logContainer = builder.Configuration.GetValue("Logging:LogContainer", "console");

        LogManager.LoadConfiguration($"{AppContext.BaseDirectory}/NLog/nlog-{logContainer}.config");
        builder.Host.UseNLog();

        //WebHost(Kestrel)
        builder.WebHost.ConfigureKestrel((context, serverOptions) =>
        {
            var kestrelSection = context.Configuration.GetSection(KestrelConfig.Name);
            if (kestrelSection is null)
            {
                throw new NullReferenceException(nameof(kestrelSection));
            }

            serverOptions.Configure(kestrelSection);
        });

        return(builder);
    }
示例#5
0
 public Startup(WebApplicationBuilder builder) : base(builder.Environment, (IConfiguration)builder.Services.BuildServiceProvider().GetRequiredService <IConfiguration>())
 {
 }
示例#6
0
        public override void Execute(WebApplicationBuilder builder, IServiceProvider serviceProvider = null)
        {
            base.Execute(builder, serviceProvider);

            if (namedPolicies != null && namedPolicies.Any())
            {
                builder.Services.AddCors(opt =>
                {
                    foreach (var p in namedPolicies)
                    {
                        opt.AddPolicy(p.Name, _ =>
                        {
                            var _origins = p.Origins?.Where(__ => !string.IsNullOrEmpty(__));
                            if (_origins != null && _origins.Any())
                            {
                                _.WithOrigins(_origins?.Distinct()?.ToArray());
                            }
                            else
                            {
                                _.AllowAnyOrigin();
                            };

                            var _methods = p.Methods?.Where(__ => !string.IsNullOrEmpty(__));
                            if (_methods != null && _methods.Any())
                            {
                                _.WithMethods(_methods?.Distinct()?.ToArray());
                            }
                            else
                            {
                                _.AllowAnyMethod();
                            };

                            var _headers = p.Headers?.Where(__ => !string.IsNullOrEmpty(__));
                            if (_headers != null && _headers.Any())
                            {
                                _.WithHeaders(_headers?.Distinct()?.ToArray());
                            }
                            else
                            {
                                _.AllowAnyHeader();
                            };

                            var _exposedHeaders = p.ExposedHeaders?.Where(__ => !string.IsNullOrEmpty(__));
                            if (_exposedHeaders != null && _exposedHeaders.Any())
                            {
                                _.WithExposedHeaders(_exposedHeaders?.Distinct()?.ToArray());
                            }
                            ;

                            if (p.AllowCredentials == true)
                            {
                                _.AllowCredentials();
                            }
                            else
                            {
                                _.DisallowCredentials();
                            };

                            if (p.PreflightMaxAgeInSeconds != null)
                            {
                                _.SetPreflightMaxAge(TimeSpan.FromSeconds(p.PreflightMaxAgeInSeconds.Value));
                            }
                        });
                    }
                });
            }
            else
            {
                builder.Services.AddCors();
            }
        }
示例#7
0
 public static void AddCustomMvc(this WebApplicationBuilder builder)
 {
     // TODO DaprClient good enough?
     builder.Services.AddControllers().AddDapr();
 }
示例#8
0
 /// <summary>
 /// Adds Piranha to the web application builder.
 /// </summary>
 /// <param name="builder">The web application builder</param>
 /// <param name="options">The startup options</param>
 /// <returns>The WebApplicationBuilder</returns>
 public static WebApplicationBuilder AddPiranha(this WebApplicationBuilder builder, Action <PiranhaServiceBuilder> options)
 {
     builder.Services.AddPiranha(options);
     return(builder);
 }
示例#9
0
 public static void AddAntiforgeryOptionsJavaScript(WebApplicationBuilder builder)
 {
     // <snippet_AddAntiforgeryOptionsJavaScript>
     builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
     // </snippet_AddAntiforgeryOptionsJavaScript>
 }
        public static void AddMicroserviceDefinitions(this IServiceCollection source, WebApplicationBuilder builder, params Type[] entryPointsAssembly)
        {
            var definitions = new List <IMicroserviceDefinition>();

            foreach (var entryPoint in entryPointsAssembly)
            {
                var types     = entryPoint.Assembly.ExportedTypes.Where(x => !x.IsAbstract && typeof(IMicroserviceDefinition).IsAssignableFrom(x));
                var instances = types.Select(Activator.CreateInstance).Cast <IMicroserviceDefinition>();
                definitions.AddRange(instances);
            }

            definitions.ForEach(microservice => microservice.ConfigureServices(source, builder.Configuration));
            source.AddSingleton(definitions as IReadOnlyCollection <IMicroserviceDefinition>);
        }
示例#11
0
 public override void Execute(WebApplicationBuilder builder, IServiceProvider serviceProvider = null)
 {
     base.Execute(builder, serviceProvider);
     builder.Services.TryAddTransient(typeof(IRepository <,>), typeof(Repository.FileSystem <,>));
 }
示例#12
0
 public static IConfigurationBuilder AddConfiguration(this WebApplicationBuilder builder)
 => builder.Configuration.AddYamlFile("config.yaml", false, true).AddEnvironmentVariables();
示例#13
0
    public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
    {
        builder.Services.AddRazorPages();

        var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");

        builder.Services
        .AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents       = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents     = true;
            options.Events.RaiseSuccessEvents     = true;

            // see https://docs.duendesoftware.com/identityserver/v5/fundamentals/resources/
            options.EmitStaticAudienceClaim = true;
        })
        .AddTestUsers(TestUsers.Users)
        // this adds the config data from DB (clients, resources, CORS)
        .AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = b =>
                                         b.UseSqlite(connectionString, dbOpts => dbOpts.MigrationsAssembly(typeof(Program).Assembly.FullName));
        })
        // this is something you will want in production to reduce load on and requests to the DB
        //.AddConfigurationStoreCache()
        //
        // this adds the operational data from DB (codes, tokens, consents)
        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = b =>
                                         b.UseSqlite(connectionString, dbOpts => dbOpts.MigrationsAssembly(typeof(Program).Assembly.FullName));

            // this enables automatic token cleanup. this is optional.
            options.EnableTokenCleanup   = true;
            options.RemoveConsumedTokens = true;
        });

        builder.Services.AddAuthentication()
        .AddGoogle(options =>
        {
            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;

            // register your IdentityServer with Google at https://console.developers.google.com
            // enable the Google+ API
            // set the redirect URI to https://localhost:5001/signin-google
            options.ClientId     = "copy client ID from Google here";
            options.ClientSecret = "copy client secret from Google here";
        });

        // this adds the necessary config for the simple admin/config pages
        {
            builder.Services.AddAuthorization(options =>
                                              options.AddPolicy("admin",
                                                                policy => policy.RequireClaim("sub", "1"))
                                              );

            builder.Services.Configure <RazorPagesOptions>(options =>
                                                           options.Conventions.AuthorizeFolder("/Admin", "admin"));

            builder.Services.AddTransient <ClientRepository>();
            builder.Services.AddTransient <IdentityScopeRepository>();
            builder.Services.AddTransient <ApiScopeRepository>();
        }

        return(builder.Build());
    }
    public static void ConfigureWebApp(this WebApplicationBuilder builder)
    {
        builder.Host.UseMessaging();
        builder.Host.UseSerilog((hostingContext, loggerConfiguration) =>
                                loggerConfiguration
                                .ReadFrom.Configuration(hostingContext.Configuration)
                                .Enrich.WithCorrelationId()
                                .Enrich.WithCorrelationIdHeader()
                                .WriteTo.Console(
                                    outputTemplate:
                                    "[{Level:u3}][{CorrelationId}][{Properties}] {SourceContext} {Message:lj}{NewLine}{Exception}",
                                    theme: ConsoleTheme.None));

        var services      = builder.Services;
        var configuration = builder.Configuration;
        var env           = builder.Environment;

        var opts = new SlackRedisOptions {
            REDIS_URL = Environment.GetEnvironmentVariable("REDIS_URL")
        };
        var options = new ConfigurationOptions
        {
            ClientName = opts.GetRedisUsername,
            Password   = opts.GetRedisPassword,
            EndPoints  = { opts.GetRedisServerHostAndPort }
        };
        var conn = ConnectionMultiplexer.Connect(options);

        services.AddDataProtection()
        .PersistKeysToStackExchangeRedis(conn)
        .SetApplicationName(
            "fplbot");     // set static so cookies are not encrypted differently after a reboot/deploy. https://github.com/dotnet/aspnetcore/issues/2513#issuecomment-354683162
        services.AddControllers()
        .AddJsonOptions(opts =>
        {
            opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        });

        var successUri = env.IsProduction() ? "https://www.fplbot.app/success" : "https://test.fplbot.app/success";
        var errorUri   = env.IsProduction() ? "https://www.fplbot.app/error" : "https://test.fplbot.app/error";

        services.AddSlackbotDistribution(c =>
        {
            c.CLIENT_ID          = configuration["CLIENT_ID"];
            c.CLIENT_SECRET      = configuration["CLIENT_SECRET"];
            c.SuccessRedirectUri = $"{successUri}?type=slack";
            c.OnSuccess          = async(teamId, teamName, s) =>
            {
                var msg = s.GetService <IMessageSession>();
                await msg.Publish(new AppInstalled(teamId, teamName));
            };
        });
        services.AddDiscordBotDistribution(c =>
        {
            c.CLIENT_ID          = configuration["DISCORD_CLIENT_ID"];
            c.CLIENT_SECRET      = configuration["DISCORD_CLIENT_SECRET"];
            c.SuccessRedirectUri = $"{successUri}?type=discord";
            c.ErrorRedirectUri   = errorUri;
            c.OnSuccess          = async(guildId, guildName, s) =>
            {
                var msg = s.GetService <IMessageSession>();
                await msg.Publish(new AppInstalled(guildId, guildName));
            };
        });
        services.Configure <AnalyticsOptions>(configuration);
        services.AddReducedHttpClientFactoryLogging();
        services.AddStackExchangeRedisCache(o => o.ConfigurationOptions = options);
        services.AddFplBotSlackWebEndpoints(configuration, conn);
        services.AddFplBotDiscordWebEndpoints(configuration, conn);
        services.AddVerifiedEntries(configuration);


        services.AddMediatR(typeof(WebApplicationBuilderExtensions));

        // Used in admin pages:
        services.AddIndexingServices(configuration, conn);


        services.AddAuthentication(options =>
        {
            options.DefaultSignInScheme       = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultSignOutScheme      = CookieAuthenticationDefaults.AuthenticationScheme;
        })
        .AddCookie(o =>
        {
            o.Cookie.Name        = "fplbot-admin";
            o.AccessDeniedPath   = "/forbidden";
            o.ReturnUrlParameter = "r";
            o.ForwardChallenge   = SlackAuthenticationDefaults.AuthenticationScheme;
        })
        .AddSlack(c =>
        {
            c.ClientId     = configuration.GetValue <string>("CLIENT_ID");
            c.ClientSecret = configuration.GetValue <string>("CLIENT_SECRET");
            c.Scope.Add("identity.team");

            c.Events.OnRemoteFailure = r =>
            {
                var errorMsg = r.Request.Query["error"];
                r.Response.Redirect($"/error?msg={errorMsg}");
                r.HandleResponse();
                return(Task.FromResult(0));
            };
        })
        .AddSlackbotEvents(c =>
        {
            c.SigningSecret = configuration.GetValue <string>("CLIENT_SIGNING_SECRET");
        })
        .AddDiscordbotEvents(c =>
        {
            c.PublicKey = configuration.GetValue <string>("DISCORD_PUBLICKEY");
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("IsAdmin", b =>
            {
                b.RequireClaim("urn:slack:team_id", "T016B9N3U7P");
                b.RequireClaim("urn:slack:user_id", "U016CP6EPR8", "U0172HKTB08", "U016CSWNXAP");
            });
        });
        var mvcBuilder = services
                         .AddRazorPages()
                         .AddRazorPagesOptions(options =>
        {
            options.Conventions.AuthorizeFolder("/admin", "IsAdmin");
            options.Conventions.AllowAnonymousToPage("/*");
        });

        if (env.IsDevelopment())
        {
            mvcBuilder.AddRazorRuntimeCompilation();
        }

        services.Configure <RouteOptions>(o =>
        {
            o.LowercaseQueryStrings = true;
            o.LowercaseUrls         = true;
        });
        services.Configure <ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            options.KnownNetworks.Clear();
            options.KnownProxies.Clear();
        });
        services.AddCors(options =>
        {
            options.AddPolicy(CorsOriginValidator.CustomCorsPolicyName, p =>
                              p.SetIsOriginAllowed(CorsOriginValidator.ValidateOrigin).AllowAnyHeader().AllowAnyMethod()
                              );
        });
        services.AddHttpContextAccessor();
    }
示例#15
0
 public static Task RunDFrameControllerAsync(this WebApplicationBuilder appBuilder, Action <DFrameControllerOptions> configureOptions)
 {
     return(RunDFrameControllerAsync(appBuilder, new DFrameControllerOptions(), (_, x) => configureOptions(x)));
 }
 public static void AddCustomHealthChecks(this WebApplicationBuilder builder) =>
 builder.Services.AddHealthChecks()
 .AddCheck("self", () => HealthCheckResult.Healthy())
 .AddDapr();
示例#17
0
 public static Task RunDFrameControllerAsync(this WebApplicationBuilder appBuilder, Action <WebHostBuilderContext, DFrameControllerOptions> configureOptions)
 {
     return(RunDFrameControllerAsync(appBuilder, new DFrameControllerOptions(), configureOptions));
 }
示例#18
0
        public override void Execute(WebApplicationBuilder builder, IServiceProvider serviceProvider = null)
        {
            base.Execute(builder, serviceProvider);
            var hcBuilder = builder.Services.AddHealthChecks();

            // checks
            var checks = options.Checks;

            if (checks != null)
            {
                // storage
                if (checks.Storage != null && checks.Storage.Any())
                {
                    foreach (var storage in checks.Storage.Where(_ => !string.IsNullOrEmpty(_.Driver)))
                    {
                        hcBuilder.AddDiskStorageHealthCheck(_ => _.AddDrive(storage.Driver, storage.MinimumFreeMb), $"storage-{storage.Name}", storage.Status, storage.Tags);
                    }
                }

                // memory
                if (checks.Memory != null)
                {
                    hcBuilder.AddProcessAllocatedMemoryHealthCheck(checks.Memory.MaximumAllocatedMb, $"memory-allocated", checks.Memory.Status, checks.Memory.Tags);
                }

                // win services
#pragma warning disable CA1416
                if (checks.WinService != null && checks.WinService.Any() && OperatingSystem.IsWindows())
                {
                    foreach (var service in checks.WinService.Where(_ => !string.IsNullOrEmpty(_.ServiceName)))
                    {
                        hcBuilder.AddWindowsServiceHealthCheck(service.ServiceName, _ => _.Status == System.ServiceProcess.ServiceControllerStatus.Running, name: $"service-{service.Name}", failureStatus: service.Status, tags: service.Tags);
                    }
                }
#pragma warning restore CA1416

                // process
                if (checks.Process != null && checks.Process.Any())
                {
                    foreach (var process in checks.Process.Where(_ => !string.IsNullOrEmpty(_.ProcessName)))
                    {
                        hcBuilder.AddProcessHealthCheck(process.ProcessName, _ => _.Any(p => p.HasExited == false), $"process-{process.Name}", process.Status, process.Tags);
                    }
                }

                // tcp
                if (checks.Tcp != null && checks.Tcp.Any())
                {
                    foreach (var tcp in checks.Tcp.Where(_ => !string.IsNullOrEmpty(_.Host)))
                    {
                        hcBuilder.AddTcpHealthCheck(_ => _.AddHost(tcp.Host, tcp.Port), $"tcp-{tcp.Name}", tcp.Status, tcp.Tags);
                    }
                }

                // http
                if (checks.Http != null && checks.Http.Any())
                {
                    foreach (var http in checks.Http.Where(_ => !string.IsNullOrEmpty(_.Url)))
                    {
                        hcBuilder.AddUrlGroup(new Uri(http.Url), $"http-{http.Name}", http.Status, http.Tags);
                    }
                }

                // app log
                if (checks.AppLog != null)
                {
                    hcBuilder.AddAppLog(checks.AppLog, tags: checks.AppLog.Tags);
                }
            }

            //ui
            if (options.Ui?.Enable == true)
            {
                builder.Services.AddHealthChecksUI(_ =>
                {
                    if (options.Ui.Endpoints != null && options.Ui.Endpoints.Any())
                    {
                        foreach (var endpoint in options.Ui.Endpoints.Where(_ => !string.IsNullOrEmpty(_.Uri)))
                        {
                            _.AddHealthCheckEndpoint(endpoint.Name, endpoint.Uri);
                        }
                    }

                    if (options.Ui.Webhooks != null && options.Ui.Webhooks.Any())
                    {
                        foreach (var hook in options.Ui.Webhooks.Where(_ => !string.IsNullOrEmpty(_.Uri)))
                        {
                            try
                            {
                                _.AddWebhookNotification(
                                    hook.Name,
                                    hook.Uri,
                                    hook.Payload,
                                    hook.RestorePayload,
                                    //shouldNotifyFunc: report => DateTime.UtcNow.Hour >= 8 && DateTime.UtcNow.Hour <= 23,
                                    customMessageFunc: (report) =>
                                {
                                    var failing = report.Entries.Where(e => e.Value.Status == UIHealthStatus.Unhealthy);
                                    return($"{failing.Count()} healthchecks are failing: {string.Join("/", failing.Select(_ => _.Key))} {Environment.NewLine + "--------------" + Environment.NewLine}");
                                },
                                    customDescriptionFunc: report =>
                                {
                                    var failing = report.Entries.Where(e => e.Value.Status == UIHealthStatus.Unhealthy);
                                    return(@$ "{string.Join(Environment.NewLine + "-------------- " + Environment.NewLine,
                                            failing.Select(f => $" { f.Key } : { f.Value.Description } { Environment.NewLine } " +
                                            $" { Newtonsoft.Json.JsonConvert.SerializeObject(f.Value.Data, Newtonsoft.Json.Formatting.Indented) } "))}");
                                }
                                    );
                            }
                            catch { }
                        }
                    }

                    _.SetEvaluationTimeInSeconds(options.Ui.EvaluationTimeinSeconds);
                    _.SetMinimumSecondsBetweenFailureNotifications(options.Ui.MinimumSecondsBetweenFailureNotifications);
                })
                .AddInMemoryStorage();
            }
        }
示例#19
0
 public static IHostBuilder ConfigureModules(this  WebApplicationBuilder builder)
 => builder.Host.ConfigureAppConfiguration((ctx, cfg) =>
示例#20
0
 public void Add(WebApplicationBuilder builder) => ConfigureServices(builder);
示例#21
0
        public async Task StartAsync(Application application)
        {
            var invoker = new HttpMessageInvoker(new ConnectionRetryHandler(new SocketsHttpHandler
            {
                AllowAutoRedirect      = false,
                AutomaticDecompression = DecompressionMethods.None,
                UseProxy = false
            }));

            foreach (var service in application.Services.Values)
            {
                var serviceDescription = service.Description;

                if (service.Description.RunInfo is IngressRunInfo runInfo)
                {
                    var builder = new WebApplicationBuilder();

                    builder.Services.AddSingleton <MatcherPolicy, IngressHostMatcherPolicy>();

                    builder.Logging.AddProvider(new ServiceLoggerProvider(service.Logs));

                    var addresses = new List <string>();

                    // Bind to the addresses on this resource
                    for (int i = 0; i < serviceDescription.Replicas; i++)
                    {
                        // Fake replicas since it's all running processes
                        var replica = service.Description.Name + "_" + Guid.NewGuid().ToString().Substring(0, 10).ToLower();
                        var status  = new IngressStatus(service, replica);
                        service.Replicas[replica] = status;

                        var ports = new List <int>();

                        foreach (var binding in serviceDescription.Bindings)
                        {
                            if (binding.Port == null)
                            {
                                continue;
                            }

                            var port = binding.ReplicaPorts[i];
                            ports.Add(port);
                            var url = $"{binding.Protocol}://localhost:{port}";
                            addresses.Add(url);
                        }

                        status.Ports = ports;

                        service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Added, status));
                    }

                    builder.Server.UseUrls(addresses.ToArray());
                    var webApp = builder.Build();

                    _webApplications.Add(webApp);

                    // For each ingress rule, bind to the path and host
                    foreach (var rule in runInfo.Rules)
                    {
                        if (!application.Services.TryGetValue(rule.Service, out var target))
                        {
                            continue;
                        }

                        _logger.LogInformation("Processing ingress rule: Path:{Path}, Host:{Host}, Service:{Service}", rule.Path, rule.Host, rule.Service);

                        var targetServiceDescription = target.Description;

                        var uris = new List <Uri>();

                        // HTTP before HTTPS (this might change once we figure out certs...)
                        var targetBinding = targetServiceDescription.Bindings.FirstOrDefault(b => b.Protocol == "http") ??
                                            targetServiceDescription.Bindings.FirstOrDefault(b => b.Protocol == "https");

                        if (targetBinding == null)
                        {
                            _logger.LogInformation("Service {ServiceName} does not have any HTTP or HTTPs bindings", targetServiceDescription.Name);
                            continue;
                        }

                        // For each of the target service replicas, get the base URL
                        // based on the replica port
                        for (int i = 0; i < targetServiceDescription.Replicas; i++)
                        {
                            var port = targetBinding.ReplicaPorts[i];
                            var url  = $"{targetBinding.Protocol}://localhost:{port}";
                            uris.Add(new Uri(url));
                        }

                        _logger.LogInformation("Service {ServiceName} is using {Urls}", targetServiceDescription.Name, string.Join(",", uris.Select(u => u.ToString())));

                        // The only load balancing strategy here is round robin
                        long            count = 0;
                        RequestDelegate del   = context =>
                        {
                            var next = (int)(Interlocked.Increment(ref count) % uris.Count);

                            var uri = new UriBuilder(uris[next])
                            {
                                Path = (string)context.Request.RouteValues["path"]
                            };

                            return(context.ProxyRequest(invoker, uri.Uri));
                        };

                        IEndpointConventionBuilder conventions = null !;

                        if (rule.Path != null)
                        {
                            conventions = ((IEndpointRouteBuilder)webApp).Map(rule.Path.TrimEnd('/') + "/{**path}", del);
                        }
                        else
                        {
                            conventions = webApp.MapFallback(del);
                        }

                        if (rule.Host != null)
                        {
                            conventions.WithMetadata(new IngressHostMetadata(rule.Host));
                        }

                        conventions.WithDisplayName(rule.Service);
                    }

                    await webApp.StartAsync();

                    foreach (var replica in service.Replicas)
                    {
                        service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Started, replica.Value));
                    }
                }
            }
        }
示例#22
0
        public static void Configure(WebApplicationBuilder builder)
        {
            var settings        = new PipelineWitnessSettings();
            var settingsSection = builder.Configuration.GetSection("PipelineWitness");

            settingsSection.Bind(settings);

            builder.Services.AddApplicationInsightsTelemetry(builder.Configuration);
            builder.Services.AddApplicationInsightsTelemetryProcessor <BlobNotFoundTelemetryProcessor>();
            builder.Services.AddTransient <ITelemetryInitializer, ApplicationVersionTelemetryInitializer>();

            builder.Services.AddAzureClients(builder =>
            {
                builder.UseCredential(new DefaultAzureCredential());
                builder.AddSecretClient(new Uri(settings.KeyVaultUri));
                builder.AddBlobServiceClient(new Uri(settings.BlobStorageAccountUri));
                builder.AddQueueServiceClient(new Uri(settings.QueueStorageAccountUri))
                .ConfigureOptions(o => o.MessageEncoding = Storage.Queues.QueueMessageEncoding.Base64);
            });

            builder.Services.AddSingleton <VssConnection>(provider =>
            {
                var secretClient      = provider.GetRequiredService <SecretClient>();
                KeyVaultSecret secret = secretClient.GetSecret("azure-devops-personal-access-token");
                var credential        = new VssBasicCredential("nobody", secret.Value);
                var connection        = new VssConnection(new Uri("https://dev.azure.com/azure-sdk"), credential);
                return(connection);
            });

            builder.Services.AddSingleton(provider => provider.GetRequiredService <VssConnection>().GetClient <ProjectHttpClient>());
            builder.Services.AddSingleton(provider => provider.GetRequiredService <VssConnection>().GetClient <BuildHttpClient>());
            builder.Services.AddSingleton(provider => provider.GetRequiredService <VssConnection>().GetClient <TestResultsHttpClient>());

            builder.Services.AddLogging();
            builder.Services.AddMemoryCache();
            builder.Services.AddSingleton <BlobUploadProcessor>();
            builder.Services.AddSingleton <BuildLogProvider>();
            builder.Services.AddSingleton <IFailureAnalyzer, FailureAnalyzer>();
            builder.Services.AddSingleton <IFailureClassifier, AzuriteInstallFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, CancelledTaskClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, CosmosDbEmulatorStartFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, AzurePipelinesPoolOutageClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, PythonPipelineTestFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, JavaScriptLiveTestFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, TestResourcesDeploymentFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, DotnetPipelineTestFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, JavaPipelineTestFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, JsSamplesExecutionFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, JsDevFeedPublishingFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, DownloadSecretsFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, GitCheckoutFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, AzuriteInstallFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, MavenBrokenPipeFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, CodeSigningFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, AzureArtifactsServiceUnavailableClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, DnsResolutionFailureClassifier>();
            builder.Services.AddSingleton <IFailureClassifier, CacheFailureClassifier>();
            builder.Services.Configure <PipelineWitnessSettings>(settingsSection);

            builder.Services.AddHostedService <BuildCompleteQueueWorker>(settings.BuildCompleteWorkerCount);
            builder.Services.AddHostedService <BuildLogBundleQueueWorker>(settings.BuildLogBundlesWorkerCount);
            builder.Services.AddHostedService <AzurePipelinesBuildDefinitionWorker>();
        }