Working admin, starting to add reverse proxy

main
Evgeny Kovalev 2 years ago
parent 1a07ac99bf
commit 1bf61dd7ce
  1. 75
      Management/management.go
  2. 9
      Management/memento.go
  3. 133
      Management/webserver.go
  4. 93
      Proxy/proxy.go
  5. 107
      Utils/Jsonlog.go
  6. 4
      Utils/Utils.go
  7. BIN
      shield
  8. 23
      shield.go
  9. 270
      static/acls.html
  10. 15
      static/config.html
  11. 27
      static/dashboard.html
  12. 114
      static/domain.html
  13. 137
      static/domains.html
  14. 0
      static/index.html
  15. 30
      static/protection.html
  16. BIN
      static/routericon.png
  17. 270
      static/routing.html
  18. 19
      static/template.html

@ -9,16 +9,17 @@ import (
"time"
"domains"
"github.com/asaskevich/govalidator"
domains "github.com/cr3a70r/shield/Domains"
)
var Settings T_Management
type T_Management struct {
Users []T_User `json:"Users"`
Domains domains.T_Domains `json:"Names"`
Debug bool `json:"Debug"`
Users []T_User `json:"Users"`
Domains []domains.T_Domain `json:"Names"`
Debug bool `json:"Debug"`
}
type T_User struct {
@ -28,8 +29,29 @@ type T_User struct {
CreatedDate string `json:"CreatedDate"`
}
func (T_Management) SaveConfig() {
func (T_Management) SaveConfig() error {
configFile, err := os.OpenFile("config.json", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
if err == nil {
configByte, err := json.MarshalIndent(Settings, "", " ")
if err != nil {
log.Fatal("management.SaveConfig: could not Marshall Settings: ", err)
return errors.New("management.SaveConfig: could not Marshall Settings: " + err.Error())
}
_, err = configFile.Write(configByte)
if err != nil {
log.Fatal("management.SaveConfig: could not Write Settings: ", err)
return errors.New("management.SaveConfig: could not Write Settings: " + err.Error())
}
} else {
log.Fatal("management.SaveConfig: could not create new config.json file: ", err)
return errors.New("management.SaveConfig: could not create new config.json file: " + err.Error())
}
defer configFile.Close()
return nil
}
func (T_Management) LoadConfig() {
@ -149,15 +171,11 @@ func (T_Management) OnboardDomain(name string, realServer string, realPort strin
return false, errors.New("given realPort is not a valid Port number")
}
domains.Names.AddByParams(name, realServer, realPort)
Settings.AddDomainByParams(name, realServer, realPort)
return true, nil
}
func (T_Management) RemoveDomain(name string) {
domains.Names.RemoveDomain(name)
}
func (T_Management) UserFindByEmail(email string) (T_User, error) {
found := false
var temp T_User
@ -190,3 +208,40 @@ func (T_Management) ToString() string {
return string(managementString)
}
//--- Domains
func (T_Management) AddDomainByDomain(domain domains.T_Domain) {
domain.Status = domains.Onboarding
Settings.Domains = append(Settings.Domains, domain)
}
func (T_Management) AddDomainByParams(name string, realServer string, realPort string) {
var temp domains.T_Domain
temp.DomainName = name
temp.RealServer = realServer
temp.RealPort = realPort
temp.Status = domains.Onboarding
Settings.AddDomainByDomain(temp)
}
func (T_Management) RemoveDomain(name string) {
for index, v := range Settings.Domains {
if v.DomainName == name {
temp := append(Settings.Domains[:index], Settings.Domains[index+1])
Settings.Domains = temp
}
}
}
func (T_Management) FindDomainByName(name string) domains.T_Domain {
var temp domains.T_Domain
for index, v := range Settings.Domains {
if v.DomainName == name {
temp = Settings.Domains[index]
}
}
return temp
}
//--- END Domains

@ -1,4 +1,11 @@
package management
// Originator is T_Management
type Memento struct {
State T_Management
}
func (e *T_Management) CreateMemento() *Memento {
return &Memento{State: *e}
}

@ -1,9 +1,12 @@
package management
import (
"bytes"
"domains"
"encoding/json"
"log"
"net/http"
"os"
"path/filepath"
"text/template"
@ -23,9 +26,16 @@ func StartWebserver(addr string) {
router.HandleFunc("/", renderIndex)
router.HandleFunc("/config", config)
router.HandleFunc("/dashboard", dashboard)
router.HandleFunc("/protection", protection)
router.HandleFunc("/routing", routing)
router.HandleFunc("/acls", acls)
router.HandleFunc("/domains", view_domains)
router.HandleFunc("/domain/{id}", view_domain)
router.HandleFunc("/config", config)
router.HandleFunc("/api/domains", api_domains)
router.HandleFunc("/api/domain/{id}", api_domain)
log.Fatal(http.ListenAndServe(addr, router))
}
@ -99,9 +109,39 @@ func dashboard(w http.ResponseWriter, r *http.Request) {
}
}
func protection(w http.ResponseWriter, r *http.Request) {
func routing(w http.ResponseWriter, r *http.Request) {
fpTemplate := filepath.Join("static", "template.html")
fpPage := filepath.Join("static", "routing.html")
tmpl, err := template.ParseFiles(fpPage, fpTemplate)
if err != nil {
log.Println("webserver.protection: " + err.Error())
}
err = tmpl.ExecuteTemplate(w, "template.html", nil)
if err != nil {
log.Println("webserver.protection: " + err.Error())
}
}
func acls(w http.ResponseWriter, r *http.Request) {
fpTemplate := filepath.Join("static", "template.html")
fpPage := filepath.Join("static", "acls.html")
tmpl, err := template.ParseFiles(fpPage, fpTemplate)
if err != nil {
log.Println("webserver.protection: " + err.Error())
}
err = tmpl.ExecuteTemplate(w, "template.html", nil)
if err != nil {
log.Println("webserver.protection: " + err.Error())
}
}
func view_domains(w http.ResponseWriter, r *http.Request) {
fpTemplate := filepath.Join("static", "template.html")
fpPage := filepath.Join("static", "protection.html")
fpPage := filepath.Join("static", "domains.html")
tmpl, err := template.ParseFiles(fpPage, fpTemplate)
if err != nil {
@ -114,8 +154,34 @@ func protection(w http.ResponseWriter, r *http.Request) {
}
}
type ViewDomains struct {
Domain domains.T_Domain
}
func view_domain(w http.ResponseWriter, r *http.Request) {
fpTemplate := filepath.Join("static", "template.html")
fpPage := filepath.Join("static", "domain.html")
httpVars := mux.Vars(r)
id := httpVars["id"]
var view ViewDomains
view.Domain = Settings.FindDomainByName(id)
tmpl, err := template.ParseFiles(fpPage, fpTemplate)
if err != nil {
log.Println("webserver.protection: " + err.Error())
}
err = tmpl.ExecuteTemplate(w, "template.html", view)
if err != nil {
log.Println("webserver.protection: " + err.Error())
}
}
type View struct {
Data string
Data string
Config string
}
func config(w http.ResponseWriter, r *http.Request) {
@ -127,10 +193,22 @@ func config(w http.ResponseWriter, r *http.Request) {
log.Println("webserver.config: " + err.Error())
}
bt, err := json.MarshalIndent(Settings, "", " ")
vd := View{string(bt)}
logFile, err := os.Open("runlog.log")
if err != nil {
log.Fatal(err)
} else {
log.SetOutput(logFile)
}
buf := new(bytes.Buffer)
buf.ReadFrom(logFile)
//vd := ViewData{&Settings}
defer logFile.Close()
bt, err := json.MarshalIndent(Settings, "", " ")
if err != nil {
log.Println("webserver.config: " + err.Error())
}
vd := View{string(bt), buf.String()}
err = tmpl.ExecuteTemplate(w, "template.html", vd)
if err != nil {
@ -149,3 +227,44 @@ func requireAuth(h http.Handler) http.Handler {
h.ServeHTTP(w, r)
})
}
func api_domains(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
Utils.RespondJSON(Settings.Domains, http.StatusOK, w)
}
if r.Method == "POST" {
var msgJSON Utils.Msg
var req domains.T_Domain
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
log.Println("webserver.api_domains: " + err.Error())
msgJSON.Msg = err.Error()
Utils.RespondJSON(msgJSON, http.StatusBadRequest, w)
}
Settings.AddDomainByDomain(req)
err = Settings.SaveConfig()
if err != nil {
log.Println("webserver.api_domains: " + err.Error())
msgJSON.Msg = err.Error()
Utils.RespondJSON(msgJSON, http.StatusBadRequest, w)
}
msgJSON.Msg = "OK"
Utils.RespondJSON(msgJSON, http.StatusOK, w)
}
}
func api_domain(w http.ResponseWriter, r *http.Request) {
httpVars := mux.Vars(r)
id := httpVars["id"]
var msgJSON Utils.Msg
msgJSON.Msg = id
Utils.RespondJSON(msgJSON, http.StatusBadRequest, w)
}

@ -0,0 +1,93 @@
package proxy
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
logger "github.com/cr3a70r/shield/Utils"
)
type ProxyHttpServer struct {
ctx context.Context
http.Server
AddressAndPort string
Name string
logger *logger.Logger
}
type ReverseProxy struct {
url *url.URL
proxy *httputil.ReverseProxy
logger *logger.Logger
port string
}
type Override struct {
Header string
Match string
Host string
Path string
}
type Config struct {
Path string
Host string
Override Override
}
func NewProxy(urlString string, transport http.RoundTripper, director *httputil.ReverseProxy, logger *logger.Logger, port string) *ReverseProxy {
providedUrl, err := url.Parse(urlString)
if err != nil {
return nil
}
p := httputil.NewSingleHostReverseProxy(providedUrl)
p.Transport = transport
p.Director = director.Director
p.ModifyResponse = UpdateResponse
return &ReverseProxy{
url: providedUrl,
proxy: p,
logger: logger,
port: port,
}
}
func (p *ReverseProxy) Handler(w http.ResponseWriter, r *http.Request) {
p.logger.PrintInfo("", map[string]string{
"accept": r.Header.Get("Accept"),
"accept-encoding": r.Header.Get("Accept-Encoding"),
"accept-language": r.Header.Get("Accept-Language"),
"cache-control": r.Header.Get("Cache-Control"),
"connection": r.Header.Get("Connection"),
"pragma": r.Header.Get("Pragma"),
"sec-ch-ua": r.Header.Get("Sec-Ch-Ua"),
"user-agent": r.Header.Get("User-Agent"),
})
xsCode := r.Header.Get("X-Code")
if r.Header.Get(xsCode) != "" {
p.logger.PrintInfo("", map[string]string{
"xsCode": xsCode,
})
}
p.proxy.ServeHTTP(w, r)
}
func UpdateResponse(r *http.Response) error {
buf := bytes.NewBufferString("<input type=\"text\" name=\"browser\" value=\"ie\">")
r.Body = ioutil.NopCloser(buf)
r.Header["Content-Length"] = []string{fmt.Sprint(buf.Len())}
return nil
}

@ -0,0 +1,107 @@
package Utils
import (
"encoding/json"
"io"
"os"
"runtime/debug"
"sync"
"time"
)
// Define a Level type to represent the severity level for a log entry.
type Level int8
// Initialize constants which represent a specific severity level. We use the iota
// keyword as a shortcut to
const (
LevelInfo Level = iota
LevelError
LevelFatal
LevelOff
)
// assign successive integer values to the constants.
// Has the value 0. // Has the value 1. // Has the value 2. // Has the value 3.
// Return a human-friendly string for the severity level.
func (l Level) String() string {
switch l {
case LevelInfo:
return "INFO"
case LevelError:
return "ERROR"
case LevelFatal:
return "FATAL"
default:
return ""
}
}
// Define a custom Logger type. This holds the output destination that the log entries // will be written to, the minimum severity level that log entries will be written for, // plus a mutex for coordinating the writes.
type Logger struct {
out io.Writer
minLevel Level
mu sync.Mutex
}
// Return a new Logger instance which writes log entries at or above a minimum severity // level to a specific output destination.
func New(out io.Writer, minLevel Level) *Logger {
return &Logger{out: out,
minLevel: minLevel}
}
// Declare some helper methods for writing log entries at the different levels. Notice // that these all accept a map as the second parameter which can contain any arbitrary // 'properties' that you want to appear in the log entry.
func (l *Logger) PrintInfo(message string, properties map[string]string) {
l.print(LevelInfo, message, properties)
}
func (l *Logger) PrintError(err error, properties map[string]string) {
l.print(LevelError, err.Error(), properties)
}
func (l *Logger) PrintFatal(err error, properties map[string]string) {
l.print(LevelFatal, err.Error(), properties)
os.Exit(1) // For entries at the FATAL level, we also terminate the application.
}
// Print is an internal method for writing the log entry.
func (l *Logger) print(level Level, message string, properties map[string]string) (int, error) { // If the severity level of the log entry is below the minimum severity for the
// logger, then return with no further action.
if level < l.minLevel {
return 0, nil
}
// Declare an anonymous struct holding the data for the log entry.
aux := struct {
Level string `json:"level"`
Time string `json:"time"`
Message string `json:"message"`
Properties map[string]string `json:"properties,omitempty"`
Trace string `json:"trace,omitempty"`
}{
Level: level.String(),
Time: time.Now().UTC().Format(time.RFC3339), Message: message,
Properties: properties,
}
// Include a stack trace for entries at the ERROR and FATAL levels.
if level >= LevelError {
aux.Trace = string(debug.Stack())
}
// Declare a line variable for holding the actual log entry text.
var line []byte
// Marshal the anonymous struct to JSON and store it in the line variable. If there // was a problem creating the JSON, set the contents of the log entry to be that
// plain-text error message instead.
line, err := json.Marshal(aux)
if err != nil {
line = []byte(LevelError.String() + ": unable to marshal log message: " + err.Error())
}
// Lock the mutex so that no two writes to the output destination cannot happen // concurrently. If we don't do this, it's possible that the text for two or more // log entries will be intermingled in the output.
l.mu.Lock()
defer l.mu.Unlock()
// Write the log entry followed by a newline.
return l.out.Write(append(line, '\n'))
}
// We also implement a Write() method on our Logger type so that it satisfies the
// io.Writer interface. This writes a log entry at the ERROR level with no additional // properties.
func (l *Logger) Write(message []byte) (n int, err error) {
return l.print(LevelError, string(message), nil)
}

@ -5,6 +5,10 @@ import (
"net/http"
)
type Msg struct {
Msg string
}
func RespondJSON(data interface{}, code int, writer http.ResponseWriter) {
writer.Header().Add("Content-type", "application/json")
writer.WriteHeader(code)

BIN
shield

Binary file not shown.

@ -1,6 +1,7 @@
package main
import (
"fmt"
"log"
"os"
@ -14,10 +15,30 @@ func main() {
} else {
log.SetOutput(logFile)
}
defer logFile.Close()
/*
proxyLog, err := os.OpenFile("proxy.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer proxyLog.Close()
//proxy
transport := &http.Transport{
DialContext: (&net.Dialer{
Timeout: 5 * time.Second,
}).DialContext,
}
*/
management.Settings.Initialize()
management.StartWebserver("0.0.0.0:8080")
}
func cleanup() {
fmt.Println("Closing Application")
}

@ -0,0 +1,270 @@
{{define "title"}}
Protection | Shield
{{end}}
{{define "body"}}
<div class="row align-items-start">
<div class="col">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Prefix</span>
<input type="text" class="form-control" placeholder="Prefix" aria-label="Prefix" aria-describedby="basic-addon1">
<button class="btn btn-outline-secondary" type="button" id="button-addon2">show route</button>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">-Iface </span>
<input type="text" class="form-control" placeholder="Interface" aria-label="Interface" aria-describedby="basic-addon1">
<select class="form-select" aria-label="Router">
<option>rtr-somnj-dc01</option>
<option>rtr-somnj-dc02</option>
<option>rtr-halnj-dc01</option>
</select>
<button class="btn btn-outline-secondary" type="button" id="button-addon2">show iface</button>
</div>
<div class="form-floating">
<textarea style="height: 300px" class="form-control" placeholder="Leave a comment here" id="floatingTextarea">
description SOM_RCS-STG-BOSSDTC;
vlan-id 1061;
family inet {
filter {
output AT_SOM_RCS-STG-BOSSDTC_IN;
}
address 10.47.3.253/24 {
vrrp-group 100 {
virtual-address 10.47.3.254;
priority 250;
preempt;
accept-data;
}
}
}
</textarea>
<label for="floatingTextarea">rtr-somnj-dc01</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<textarea style="height: 500px" class="form-control" placeholder="Leave a comment here" id="floatingTextarea">
mgmt_junos.inet.0: 4 destinations, 5 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[Static/5] 10:04:47
> to 10.51.1.254 via fxp0.0
CORP.inet.0: 159 destinations, 918 routes (159 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:55, metric 62, tag 0
> to 10.248.1.194 via ae1.3904
[BGP/170] 09:59:51, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 16
[BGP/170] 10:00:02, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 16, Push 90(top)
[BGP/170] 09:55:37, MED 65, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:37, MED 65, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:39, MED 65, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
GENIE.inet.0: 44 destinations, 223 routes (44 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:40, metric 103, tag 0
> to 10.51.0.178 via xe-10/1/0.4022
[BGP/170] 09:59:50, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 17
[BGP/170] 09:55:29, MED 102, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:36, MED 102, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:39, MED 102, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:59:40, MED 106, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 17, Push 90(top)
PRIVATE_NonProd.inet.0: 142 destinations, 739 routes (142 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17, tag 100
> to 10.51.0.33 via ae1.4006
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
PRIVATE_PROD.inet.0: 692 destinations, 4611 routes (692 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.3.0/24 *[Direct/0] 10:01:17
> via ae1.1061
[OSPF/150] 10:00:31, metric 0, tag 0
> to 10.51.0.46 via xe-10/1/0.4007
[BGP/170] 09:53:50, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
PROD-PUBLIC.inet.0: 893692 destinations, 5748612 routes (893679 active, 1 holddown, 892904 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 216.53.104.254 via ae1.4012
[OSPF/150] 10:00:31, metric 3, tag 0
> to 10.51.0.70 via xe-10/1/0.4010
[BGP/170] 09:57:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:46, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:58, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
VOICE_NonProd-PUBLIC.inet.0: 29 destinations, 72 routes (29 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 10.51.0.9 via ae1.4003
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
</textarea>
<label for="floatingTextarea">rtr-somnj-dc01</label>
</div>
<div class="form-floating">
<textarea style="height: 500px" class="form-control" placeholder="Leave a comment here" id="floatingTextarea">
mgmt_junos.inet.0: 4 destinations, 5 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[Static/5] 10:04:47
> to 10.51.1.254 via fxp0.0
CORP.inet.0: 159 destinations, 918 routes (159 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:55, metric 62, tag 0
> to 10.248.1.194 via ae1.3904
[BGP/170] 09:59:51, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 16
[BGP/170] 10:00:02, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 16, Push 90(top)
[BGP/170] 09:55:37, MED 65, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:37, MED 65, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:39, MED 65, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
GENIE.inet.0: 44 destinations, 223 routes (44 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:40, metric 103, tag 0
> to 10.51.0.178 via xe-10/1/0.4022
[BGP/170] 09:59:50, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 17
[BGP/170] 09:55:29, MED 102, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:36, MED 102, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:39, MED 102, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:59:40, MED 106, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 17, Push 90(top)
PRIVATE_NonProd.inet.0: 142 destinations, 739 routes (142 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17, tag 100
> to 10.51.0.33 via ae1.4006
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
PRIVATE_PROD.inet.0: 692 destinations, 4611 routes (692 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.3.0/24 *[Direct/0] 10:01:17
> via ae1.1061
[OSPF/150] 10:00:31, metric 0, tag 0
> to 10.51.0.46 via xe-10/1/0.4007
[BGP/170] 09:53:50, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
PROD-PUBLIC.inet.0: 893692 destinations, 5748612 routes (893679 active, 1 holddown, 892904 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 216.53.104.254 via ae1.4012
[OSPF/150] 10:00:31, metric 3, tag 0
> to 10.51.0.70 via xe-10/1/0.4010
[BGP/170] 09:57:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:46, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:58, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
VOICE_NonProd-PUBLIC.inet.0: 29 destinations, 72 routes (29 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 10.51.0.9 via ae1.4003
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
</textarea>
<label for="floatingTextarea">rtr-somnj-dc02</label>
</div>
</div>
</div>
<script type="text/javascript">
</script>
{{ .Data }}
{{end}}

@ -4,10 +4,15 @@ Config | Shield
{{define "body"}}
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">running-config</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="30">{{ .Data }}</textarea>
</div>
<div class="row align-items-start">
<div class="col">
<label for="exampleFormControlTextarea1" class="form-label">running-config</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="30">{{ .Data }}</textarea>
</div>
<div class="col">
<label for="exampleFormControlTextarea1" class="form-label">log</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="30">{{ .Config }}</textarea>
</div>
</div>
{{end}}

@ -4,7 +4,26 @@ Dashboard | Shield
{{end}}
{{define "body"}}
<h1>Hi</h1>
dskflsjflksdjfls
dflsdfsdlfks
{{end}}
<div class="row align-items-start">
<div class="col">
<a class="btn btn-primary bi-asterisk" href="#">Routing</a>
</div>
<div class="col">
<a class="btn btn-primary bi-asterisk" href="#">ACLs</a>
</div>
</div>
<input id="test" name="Email" required value="UUU">
<script type="text/javascript">
console.log("TEST")
var e = document.getElementById("test");
console.log(e.getAttribute("value"))
</script>
{{end}}

@ -0,0 +1,114 @@
{{define "title"}}
Protection | Shield
{{end}}
{{define "body"}}
<table class="table" id="Domains">
<thead>
<tr>
<th scope="col">Domain</th>
<th scope="col">Server</th>
<th scope="col">Port</th>
<th scope="col">Stop Lists</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{{ .Domain.DomainName}}</th>
<td>{{ .Domain.RealServer}}</td>
<td>{{ .Domain.RealPort}}</td>
<td style="width: 500px;">
<select class="form-select" aria-label="Default select example">
<option selected>Known Attackers</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</td>
</tr>
</tbody>
</table>
<div class="row align-items-start">
<div class="col" id="test">
<div class="input-group mb-3">
TEST 1
</div>
<div class="input-group mb-3">
TEST 2
</div>
<div class="form-floating">
TEST - 3
</div>
</div>
</div>
<script type="text/javascript">
/*
function AddDomain() {
$.ajax({
url: "http://localhost:8080/api/domains",
type: "POST",
data: JSON.stringify({
"DomainName": $("#Domain").val(),
"RealServer": $("#Server").val(),
"RealPort": $("#Port").val(),
}),
success: function(result) {
console.log("DONE!")
console.log(result)
}
})
}
$.ajax({
url: "http://localhost:8080/api/domains",
type: "GET",
data: JSON.stringify({
}),
success: function(result) {
if (result == null) {
console.log("domain list is empty")
return
}
var content = ''
for (var i = 0; i<result.length; i++) {
content += '<th scope="row">' + i + "</th>"
content += '<tr>'
content += '<td>'
content += result[i].DomainName
content += '</td>'
content += '<td>'
content += result[i].RealServer
content += '</td>'
content += '<td>'
content += result[i].RealPort
content += '</td>'
content += '<td>'
content += '<a href="/api/domain/' + result[i].DomainName +'" type="button" class="btn btn-warning">Edit</a>'
content += '</td>'
content += '</tr>'
}
$('#Domains tbody').html(content)
console.log("DONE!")
}
})
*/
</script>
{{ .Data }}
{{end}}

@ -0,0 +1,137 @@
{{define "title"}}
Protection | Shield
{{end}}
{{define "body"}}
<table class="table" id="Domains">
<thead>
<tr>
<th scope="col">Domain</th>
<th scope="col">Server</th>
<th scope="col">Port</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>@domainname</td>
<td>@server</td>
<td>@port</td>
</tr>
</tbody>
</table>
<div class="row align-items-start">
<div class="col" id="test">
<div class="input-group mb-3">
TEST - 1
</div>
<div class="input-group mb-3">
TEST - 2
</div>
<div class="form-floating">
TEST - 3
</div>
</div>
<div class="col">
<div class="form-floating">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#DomainAddModal">
Add Domain
</button>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="DomainAddModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New Domain</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<label for="inputEmail" class="sr-only">Domain Name</label>
<input type="text" id="Domain" name="Domain" class="form-control" placeholder="contoso.co" required autofocus>
<label for="inputEmail" class="sr-only">Server</label>
<input type="text" id="Server" name="Server" class="form-control" placeholder="FQDN or IP address" required>
<label for="inputEmail" class="sr-only">Port</label>
<input type="text" id="Port" name="Port" class="form-control" placeholder="443 or any other" required>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="AddDomain()">Save</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
function AddDomain() {
$.ajax({
url: "http://localhost:8080/api/domains",
type: "POST",
data: JSON.stringify({
"DomainName": $("#Domain").val(),
"RealServer": $("#Server").val(),
"RealPort": $("#Port").val(),
}),
success: function(result) {
console.log("DONE!")
console.log(result)
}
})
}
$.ajax({
url: "http://localhost:8080/api/domains",
type: "GET",
data: JSON.stringify({
}),
success: function(result) {
if (result == null) {
console.log("domain list is empty")
return
}
var content = ''
for (var i = 0; i<result.length; i++) {
content += '<th scope="row">' + i + "</th>"
content += '<tr>'
content += '<td>'
content += result[i].DomainName
content += '</td>'
content += '<td>'
content += result[i].RealServer
content += '</td>'
content += '<td>'
content += result[i].RealPort
content += '</td>'
content += '<td>'
content += '<a href="/domain/' + result[i].DomainName +'" type="button" class="btn btn-warning">Edit</a>'
content += '</td>'
content += '</tr>'
}
$('#Domains tbody').html(content)
console.log("DONE!")
}
})
</script>
{{ .Data }}
{{end}}

@ -1,30 +0,0 @@
{{define "title"}}
Protection | Shield
{{end}}
{{define "body"}}
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">Domain</th>
<th scope="col">Real Server</th>
<th scope="col">Real Port</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr scope="row">
<td>Test</td>
<td>8.8.8.8</td>
<td>80</td>
<td>Onboarding</td>
<td><a class="btn btn-warning active" href="/protection/edit">Edit</a></td>
<td><a class="btn btn-danger active" href="/protection/delete">Delete</a></td>
</tr>
</tbody>
</table>
{{end}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

@ -0,0 +1,270 @@
{{define "title"}}
Protection | Shield
{{end}}
{{define "body"}}
<div class="row align-items-start">
<div class="col">
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">Prefix</span>
<input type="text" class="form-control" placeholder="Prefix" aria-label="Prefix" aria-describedby="basic-addon1">
<button class="btn btn-outline-secondary" type="button" id="button-addon2">show route</button>
</div>
<div class="input-group mb-3">
<span class="input-group-text" id="basic-addon1">-Iface </span>
<input type="text" class="form-control" placeholder="Interface" aria-label="Interface" aria-describedby="basic-addon1">
<select class="form-select" aria-label="Router">
<option>rtr-somnj-dc01</option>
<option>rtr-somnj-dc02</option>
<option>rtr-halnj-dc01</option>
</select>
<button class="btn btn-outline-secondary" type="button" id="button-addon2">show iface</button>
</div>
<div class="form-floating">
<textarea style="height: 300px" class="form-control" placeholder="Leave a comment here" id="floatingTextarea">
description SOM_RCS-STG-BOSSDTC;
vlan-id 1061;
family inet {
filter {
output AT_SOM_RCS-STG-BOSSDTC_IN;
}
address 10.47.3.253/24 {
vrrp-group 100 {
virtual-address 10.47.3.254;
priority 250;
preempt;
accept-data;
}
}
}
</textarea>
<label for="floatingTextarea">rtr-somnj-dc01</label>
</div>
</div>
<div class="col">
<div class="form-floating">
<textarea style="height: 500px" class="form-control" placeholder="Leave a comment here" id="floatingTextarea">
mgmt_junos.inet.0: 4 destinations, 5 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[Static/5] 10:04:47
> to 10.51.1.254 via fxp0.0
CORP.inet.0: 159 destinations, 918 routes (159 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:55, metric 62, tag 0
> to 10.248.1.194 via ae1.3904
[BGP/170] 09:59:51, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 16
[BGP/170] 10:00:02, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 16, Push 90(top)
[BGP/170] 09:55:37, MED 65, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:37, MED 65, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:39, MED 65, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
GENIE.inet.0: 44 destinations, 223 routes (44 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:40, metric 103, tag 0
> to 10.51.0.178 via xe-10/1/0.4022
[BGP/170] 09:59:50, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 17
[BGP/170] 09:55:29, MED 102, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:36, MED 102, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:39, MED 102, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:59:40, MED 106, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 17, Push 90(top)
PRIVATE_NonProd.inet.0: 142 destinations, 739 routes (142 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17, tag 100
> to 10.51.0.33 via ae1.4006
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
PRIVATE_PROD.inet.0: 692 destinations, 4611 routes (692 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.3.0/24 *[Direct/0] 10:01:17
> via ae1.1061
[OSPF/150] 10:00:31, metric 0, tag 0
> to 10.51.0.46 via xe-10/1/0.4007
[BGP/170] 09:53:50, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
PROD-PUBLIC.inet.0: 893692 destinations, 5748612 routes (893679 active, 1 holddown, 892904 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 216.53.104.254 via ae1.4012
[OSPF/150] 10:00:31, metric 3, tag 0
> to 10.51.0.70 via xe-10/1/0.4010
[BGP/170] 09:57:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:46, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:58, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
VOICE_NonProd-PUBLIC.inet.0: 29 destinations, 72 routes (29 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 10.51.0.9 via ae1.4003
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
</textarea>
<label for="floatingTextarea">rtr-somnj-dc01</label>
</div>
<div class="form-floating">
<textarea style="height: 500px" class="form-control" placeholder="Leave a comment here" id="floatingTextarea">
mgmt_junos.inet.0: 4 destinations, 5 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[Static/5] 10:04:47
> to 10.51.1.254 via fxp0.0
CORP.inet.0: 159 destinations, 918 routes (159 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:55, metric 62, tag 0
> to 10.248.1.194 via ae1.3904
[BGP/170] 09:59:51, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 16
[BGP/170] 10:00:02, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 16, Push 90(top)
[BGP/170] 09:55:37, MED 65, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:37, MED 65, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
[BGP/170] 09:54:39, MED 65, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 16
GENIE.inet.0: 44 destinations, 223 routes (44 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
0.0.0.0/0 *[OSPF/150] 10:00:40, metric 103, tag 0
> to 10.51.0.178 via xe-10/1/0.4022
[BGP/170] 09:59:50, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 10.51.0.242 via et-11/1/2.1, Push 17
[BGP/170] 09:55:29, MED 102, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:36, MED 102, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:54:39, MED 102, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17
[BGP/170] 09:59:40, MED 106, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 17, Push 32(top)
to 10.51.0.242 via et-11/1/2.1, Push 17, Push 90(top)
PRIVATE_NonProd.inet.0: 142 destinations, 739 routes (142 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17, tag 100
> to 10.51.0.33 via ae1.4006
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 18
PRIVATE_PROD.inet.0: 692 destinations, 4611 routes (692 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.3.0/24 *[Direct/0] 10:01:17
> via ae1.1061
[OSPF/150] 10:00:31, metric 0, tag 0
> to 10.51.0.46 via xe-10/1/0.4007
[BGP/170] 09:53:50, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 19
PROD-PUBLIC.inet.0: 893692 destinations, 5748612 routes (893679 active, 1 holddown, 892904 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 216.53.104.254 via ae1.4012
[OSPF/150] 10:00:31, metric 3, tag 0
> to 10.51.0.70 via xe-10/1/0.4010
[BGP/170] 09:57:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:46, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
[BGP/170] 09:55:58, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 20
VOICE_NonProd-PUBLIC.inet.0: 29 destinations, 72 routes (29 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.47.0.0/16 *[Static/5] 10:01:17
> to 10.51.0.9 via ae1.4003
[BGP/170] 09:55:29, localpref 100, from 216.53.0.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:36, localpref 100, from 216.53.65.1
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
[BGP/170] 09:54:39, localpref 100, from 216.53.65.2
AS path: I, validation-state: unverified
> to 216.53.55.2 via ae0.1, Push 21
</textarea>
<label for="floatingTextarea">rtr-somnj-dc02</label>
</div>
</div>
</div>
<script type="text/javascript">
</script>
{{ .Data }}
{{end}}

@ -6,12 +6,16 @@
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="/docs/4.0/assets/img/favicons/favicon.ico">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
<title>{{ template "title"}}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.5/dist/umd/popper.min.js" integrity="sha384-Xe+8cL9oJa6tN/veChSP7q+mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-kjU+l4N0Yf4ZOJErLsIcvOU2qSb74wXpOhqTvwVx3OElZRweTnQ6d31fXEoRD1Jy" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.min.js" integrity="sha384-kjU+l4N0Yf4ZOJErLsIcvOU2qSb74wXpOhqTvwVx3OElZRweTnQ6d31fXEoRD1Jy" crossorigin="anonymous"></script>
<script
src="https://code.jquery.com/jquery-3.6.1.js"
integrity="sha256-3zlB5s2uwoUzrXK3BT7AX3FyvojsraNFxCc2vC/7pNI="
crossorigin="anonymous"></script>
</head>
<body class="text-center" >
<nav class="navbar navbar-expand-lg navbar-light bg-light">
@ -26,11 +30,18 @@
<a class="nav-link active" aria-current="page" href="/dashboard">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/protection">Protection</a>
<a class="nav-link" href="/domains">Domains</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/routing">Tunnels</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/acls">ACLs</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
<a class="nav-link" href="/certificates">Certificates</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config" tabindex="-1" aria-disabled="true">Config</a>
</li>

Loading…
Cancel
Save