566 lines
27 KiB
HTML
566 lines
27 KiB
HTML
<div class="container">
|
|
<div class="content">
|
|
|
|
<div class="columns is-multiline" *ngIf="keys?.length">
|
|
<div class="column is-12">
|
|
|
|
<div class="search-container">
|
|
<span class="icon"><i class="fas fa-search"></i></span>
|
|
<input type="text" placeholder="Filter by name or id ..." [(ngModel)]="keyword" (ngModelChange)="filter()">
|
|
</div>
|
|
|
|
<div class="tabs" *ngIf="keys?.length">
|
|
<ul>
|
|
<li *ngFor="let provider of keys" [class.is-active]="tab === provider" (click)="tab = provider">
|
|
<a>{{ provider }}</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div *ngIf="keys?.length">
|
|
<div class="columns">
|
|
<!-- Frontends -->
|
|
<div class="column is-6">
|
|
<h2 class="subtitle"><span class="tag is-info">{{ providers[tab]?.frontends.length }}</span> Frontends</h2>
|
|
<div class="message" *ngFor="let p of providers[tab]?.frontends; let i = index;">
|
|
<div class="message-header">
|
|
<h2>
|
|
<div>
|
|
<i class="icon fas fa-globe"></i>
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-info">{{ p.id }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div *ngIf="p.backend">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<a class="tags has-addons" [href]="'#' + p.backend">
|
|
<span class="tag is-light">Backend</span>
|
|
<span class="tag is-primary">{{ p.backend }}</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</h2>
|
|
</div>
|
|
|
|
<div class="message-body">
|
|
<div class="tabs is-fullwidth is-small is-boxed">
|
|
<ul>
|
|
<li [class.is-active]="p.section !== 'details'" (click)="p.section = 'main'"><a>Main</a></li>
|
|
<li [class.is-active]="p.section === 'details'" (click)="p.section = 'details'"><a>Details</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Main -->
|
|
<div *ngIf="p.section !== 'details'">
|
|
|
|
<div *ngIf="p.routes && p.routes.length">
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr>
|
|
<td>Route Rule</td>
|
|
</tr>
|
|
<tr *ngFor="let route of p.routes; let ri = index;">
|
|
<td><span class="has-text-grey" title="{{ route.title }}">{{ route.rule }}</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div *ngIf="p.entryPoints && p.entryPoints.length">
|
|
<hr>
|
|
<div class="columns">
|
|
<div class="column is-3">
|
|
<h2>Entry Points</h2>
|
|
</div>
|
|
<div class="column is-9">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags">
|
|
<span class="tag is-info" *ngFor="let ep of p.entryPoints; let ri = index;">{{ ep }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Details -->
|
|
<div *ngIf="p.section === 'details'">
|
|
|
|
<div>
|
|
<div class="columns">
|
|
<div class="column is-3">
|
|
<h2>Misc.</h2>
|
|
</div>
|
|
<div class="column is-9">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Priority</span>
|
|
<span class="tag is-info">{{ p.priority }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Host Header</span>
|
|
<span class="tag is-info">{{ p.passHostHeader }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control" *ngIf="p.passTLSCert">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">TLS Cert</span>
|
|
<span class="tag is-info">{{ p.passTLSCert }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.basicAuth && p.basicAuth.length">
|
|
<hr/>
|
|
<h2>Basic Authentication</h2>
|
|
<div class="tags padding-5-10">
|
|
<span class="tag is-info" *ngFor="let auth of p.basicAuth; let ri = index;">{{ auth }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.errors">
|
|
<hr/>
|
|
<h2>Error Pages</h2>
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr>
|
|
<td>Backend</td>
|
|
<td>Query</td>
|
|
<td>Status</td>
|
|
</tr>
|
|
<tr *ngFor="let key of p.errors | keys">
|
|
<td><span class="has-text-grey-light">{{ p.errors[key].backend }}</span></td>
|
|
<td><span class="has-text-grey">{{ p.errors[key].query }}</span></td>
|
|
<td>
|
|
<span class="tag is-light" *ngFor="let state of p.errors[key].status">{{ state }}</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div *ngIf="p.whiteList">
|
|
<hr/>
|
|
<div class="columns is-gapless is-multiline is-mobile">
|
|
<div class="column is-half">
|
|
<h2>Whitelist</h2>
|
|
</div>
|
|
<div class="column is-half">
|
|
<div class="field">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">useXForwardedFor</span>
|
|
<span class="tag is-info">{{ p.whiteList.useXForwardedFor }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags">
|
|
<span class="tag is-info" *ngFor="let wlRange of p.whiteList.sourceRange; let ri = index;">{{ wlRange }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.headers">
|
|
<hr/>
|
|
<h2>Headers</h2>
|
|
<div class="columns is-multiline">
|
|
|
|
<div class="column is-12" *ngIf="p.headers.customRequestHeaders">
|
|
<h2>Custom Request Headers</h2>
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr *ngFor="let key of p.headers.customRequestHeaders | keys">
|
|
<td><span class="has-text-grey-light">{{ key }}</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.customRequestHeaders[key] }}</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="column is-12" *ngIf="p.headers.customResponseHeaders">
|
|
<h2>Custom Response Headers</h2>
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr *ngFor="let key of p.headers.customResponseHeaders | keys">
|
|
<td><span class="has-text-grey-light">{{ key }}</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.customResponseHeaders[key] }}</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="column is-12">
|
|
<h2>Secure</h2>
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr *ngIf="p.headers.browserXssFilter">
|
|
<td><span class="has-text-grey">Browser XSS Filter</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.browserXssFilter }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.contentSecurityPolicy">
|
|
<td><span class="has-text-grey">Content Security Policy</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.contentSecurityPolicy }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.contentTypeNoSniff">
|
|
<td><span class="has-text-grey">Content Type (No sniff)</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.contentTypeNoSniff }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.customFrameOptionsValue">
|
|
<td><span class="has-text-grey">Custom Frame Options Value</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.customFrameOptionsValue }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.forceSTSHeader">
|
|
<td><span class="has-text-grey">Force STS Header</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.forceSTSHeader }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.frameDeny">
|
|
<td><span class="has-text-grey">Frame Deny</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.frameDeny }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.isDevelopment">
|
|
<td><span class="has-text-grey">Is Development</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.isDevelopment }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.publicKey">
|
|
<td><span class="has-text-grey">Public Key</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.publicKey }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.referrerPolicy">
|
|
<td><span class="has-text-grey">Referrer Policy</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.referrerPolicy }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.sslHost">
|
|
<td><span class="has-text-grey">SSL Host</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.sslHost }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.sslRedirect">
|
|
<td><span class="has-text-grey">SSL Redirect</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.sslRedirect }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.sslTemporaryRedirect">
|
|
<td><span class="has-text-grey">SSL Temporary Redirect</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.sslTemporaryRedirect }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.stsIncludeSubdomains">
|
|
<td><span class="has-text-grey">STS Include Subdomains</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.stsIncludeSubdomains }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.stsPreload">
|
|
<td><span class="has-text-grey">STS Preload</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.stsPreload }}</span></td>
|
|
</tr>
|
|
<tr *ngIf="p.headers.stsSeconds">
|
|
<td><span class="has-text-grey">STS Seconds</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.stsSeconds }}</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="column is-12" *ngIf="p.headers.allowedHosts">
|
|
<h2>Allowed Hosts</h2>
|
|
<div class="tags-list">
|
|
<span class="tag is-light" *ngFor="let host of p.headers.allowedHosts">{{ host }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="column is-12" *ngIf="p.headers.sslProxyHeaders">
|
|
<h2>SSL Proxy Headers</h2>
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr *ngFor="let key of p.headers.sslProxyHeaders | keys">
|
|
<td><span class="has-text-grey-light">{{ key }}</span></td>
|
|
<td><span class="has-text-grey">{{ p.headers.sslProxyHeaders[key] }}</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="column is-12" *ngIf="p.headers.hostsProxyHeaders">
|
|
<h2>Hosts Proxy Headers</h2>
|
|
<div class="tags-list">
|
|
<span class="tag is-light" *ngFor="let h of p.headers.hostsProxyHeaders">{{ h }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Backends -->
|
|
<div class="column is-6">
|
|
<h2 class="subtitle"><span class="tag is-primary">{{ providers[tab]?.backends.length }}</span> Backends</h2>
|
|
<div class="message" *ngFor="let p of providers[tab]?.backends; let i = index;">
|
|
<div class="message-header">
|
|
<h2 [id]="p.id">
|
|
<div>
|
|
<i class="icon fas fa-server"></i>
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-primary">{{ p.id }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</h2>
|
|
</div>
|
|
<div class="message-body">
|
|
|
|
<div class="tabs is-fullwidth is-small is-boxed">
|
|
<ul>
|
|
<li [class.is-active]="p.section !== 'details'" (click)="p.section = 'main'"><a>Main</a></li>
|
|
<li [class.is-active]="p.section === 'details'" (click)="p.section = 'details'"><a>Details</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Main -->
|
|
<div *ngIf="p.section !== 'details'">
|
|
<table class="table is-fullwidth is-hoverable">
|
|
<tbody>
|
|
<tr>
|
|
<td>Server</td>
|
|
<td>Weight</td>
|
|
</tr>
|
|
<tr *ngFor="let server of p.servers; let ri = index;">
|
|
<td><a href="{{ server.url }}" title="{{ server.title }}">{{ server.url }}</a></td>
|
|
<td><span class="has-text-grey">{{ server.weight }}</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Details -->
|
|
<div *ngIf="p.section === 'details'">
|
|
|
|
<div *ngIf="p.loadBalancer">
|
|
<div class="columns">
|
|
<div class="column is-3">
|
|
<h2>Load Balancer</h2>
|
|
</div>
|
|
<div class="column is-9">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Method</span>
|
|
<span class="tag is-info">{{ p.loadBalancer.method }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control">
|
|
<div class="tags has-addons" *ngIf="p.loadBalancer.stickiness || p.loadBalancer.sticky">
|
|
<span class="tag is-light">Stickiness</span>
|
|
<span class="tag is-info">true</span>
|
|
</div>
|
|
</div>
|
|
<div class="control" *ngIf="p.loadBalancer.stickiness">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Cookie Name</span>
|
|
<span class="tag is-info">{{ p.loadBalancer.stickiness.cookieName }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.maxConn">
|
|
<hr/>
|
|
<div class="columns">
|
|
<div class="column is-3">
|
|
<h2>Max Connections</h2>
|
|
</div>
|
|
<div class="column is-9">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Amount</span>
|
|
<span class="tag is-info">{{ p.maxConn.amount }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Extractor Function</span>
|
|
<span class="tag is-info">{{ p.maxConn.extractorFunc }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.circuitBreaker">
|
|
<hr/>
|
|
<div class="columns">
|
|
<div class="column is-3">
|
|
<h2>Circuit Breaker</h2>
|
|
</div>
|
|
<div class="column is-9">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Expression</span>
|
|
<span class="tag is-info">{{ p.circuitBreaker.expression }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.healthCheck">
|
|
<hr/>
|
|
<div class="columns">
|
|
<div class="column is-3">
|
|
<h2>Health Check</h2>
|
|
</div>
|
|
<div class="column is-9">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Path</span>
|
|
<span class="tag is-info">{{ p.healthCheck.path }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control" *ngIf="p.healthCheck.port">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Port</span>
|
|
<span class="tag is-info">{{ p.healthCheck.port }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control" *ngIf="p.healthCheck.interval">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Interval</span>
|
|
<span class="tag is-info">{{ p.healthCheck.interval }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="control" *ngIf="p.healthCheck.hostname">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Hostname</span>
|
|
<span class="tag is-info">{{ p.healthCheck.hostname }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="p.buffering">
|
|
<hr>
|
|
<div class="columns list-title">
|
|
<div class="column is-12">
|
|
<h2>Buffering</h2>
|
|
</div>
|
|
</div>
|
|
<div class="list-item">
|
|
<div class="columns">
|
|
<div class="column is-4">
|
|
<span>Request Body Bytes</span>
|
|
</div>
|
|
<div class="column is-4">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Max</span>
|
|
<span class="tag is-info">{{ p.buffering.maxRequestBodyBytes }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column is-4">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Men</span>
|
|
<span class="tag is-info">{{ p.buffering.memRequestBodyBytes }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="list-item">
|
|
<div class="columns">
|
|
<div class="column is-4">
|
|
<span>Response Body Bytes</span>
|
|
</div>
|
|
<div class="column is-4">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Max</span>
|
|
<span class="tag is-info">{{ p.buffering.maxResponseBodyBytes }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column is-4">
|
|
<div class="field is-grouped is-grouped-multiline">
|
|
<div class="control">
|
|
<div class="tags has-addons">
|
|
<span class="tag is-light">Men</span>
|
|
<span class="tag is-info">{{ p.buffering.memResponseBodyBytes }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="list-item">
|
|
<div class="columns">
|
|
<div class="column is-4">
|
|
<span>Retry Expression</span>
|
|
</div>
|
|
<div class="column is-8">
|
|
<span class="tag is-info">{{ p.buffering.retryExpression }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="columns" *ngIf="!keys || !keys.length">
|
|
<div class="column is-12">
|
|
<div class="notification">
|
|
No providers found.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|