Open a new port on satellite for admin GUI (#1901)
* Set up new port 8090 for in offers Clean up commented code Rename offers to offersweb Remove unused code Add todos for adding front-end templates Add middleware for only allow local access Add comment Fix linting error Remove commented code Update storj-sim Check request IP against Host IP Use net pakcage to retrieve IP address Rename service to marketing * Add wrapper for all errors * fix conflicts * update the config file * fix linting error * remove unused packages * remove global runtime var and add flag to storj-sim for mar static dir * remove debugging lines * add new config for test data and check if static dir flag is set before passing to mux * change 'console' to 'marketing' for test data config * fix linting errors * update config flag * Trigger Jenkins * Trigger CLA
This commit is contained in:
parent
252c8ac189
commit
af66d9c6e4
@ -48,6 +48,7 @@ const (
|
||||
publicGRPC = 0
|
||||
privateGRPC = 1
|
||||
publicHTTP = 2
|
||||
privateHTTP = 3
|
||||
debugHTTP = 9
|
||||
)
|
||||
|
||||
@ -268,6 +269,8 @@ func newNetwork(flags *Flags) (*Processes, error) {
|
||||
"--console.static-dir", filepath.Join(storjRoot, "web/satellite/"),
|
||||
// TODO: remove console.auth-token after vanguard release
|
||||
"--console.auth-token", consoleAuthToken,
|
||||
"--marketing.address", net.JoinHostPort(host, port(satellitePeer, i, privateHTTP)),
|
||||
"--marketing.static-dir", filepath.Join(storjRoot, "satellite/marketing/marketingweb/static/"),
|
||||
"--server.address", process.Address,
|
||||
"--server.private-address", net.JoinHostPort(host, port(satellitePeer, i, privateGRPC)),
|
||||
|
||||
@ -279,7 +282,6 @@ func newNetwork(flags *Flags) (*Processes, error) {
|
||||
"--mail.smtp-server-address", "smtp.gmail.com:587",
|
||||
"--mail.from", "Storj <yaroslav-satellite-test@storj.io>",
|
||||
"--mail.template-path", filepath.Join(storjRoot, "web/satellite/static/emails"),
|
||||
|
||||
"--version.server-address", fmt.Sprintf("http://%s/", versioncontrol.Address),
|
||||
"--debug.addr", net.JoinHostPort(host, port(satellitePeer, i, debugHTTP)),
|
||||
},
|
||||
|
2
go.mod
2
go.mod
@ -43,7 +43,7 @@ require (
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
|
||||
github.com/gorilla/handlers v1.4.0 // indirect
|
||||
github.com/gorilla/mux v1.7.0 // indirect
|
||||
github.com/gorilla/mux v1.7.0
|
||||
github.com/gorilla/rpc v1.1.0 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
|
||||
github.com/hashicorp/go-msgpack v0.5.3 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -131,7 +131,9 @@ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135 h1:zLTLjkaOFEFIOxY5BWLFLwh+cL8vOBW4XJ2aqLE/Tf0=
|
||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.0.0-beta.2+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
|
116
satellite/marketing/marketingweb/server.go
Normal file
116
satellite/marketing/marketingweb/server.go
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright (C) 2019 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package marketingweb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"html/template"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/zeebo/errs"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// Error is satellite marketing error type
|
||||
var Error = errs.Class("satellite marketing error")
|
||||
|
||||
// Config contains configuration for marketing offersweb server
|
||||
type Config struct {
|
||||
Address string `help:"server address of the marketing Admin GUI" default:"0.0.0.0:8090"`
|
||||
StaticDir string `help:"path to static resources" default:""`
|
||||
}
|
||||
|
||||
// Server represents marketing offersweb server
|
||||
type Server struct {
|
||||
log *zap.Logger
|
||||
|
||||
config Config
|
||||
|
||||
listener net.Listener
|
||||
server http.Server
|
||||
}
|
||||
|
||||
// The three pages contained in addPages are pages all templates require
|
||||
// This exists in order to limit handler verbosity
|
||||
func (s *Server) addPages(assets []string) []string {
|
||||
rp := s.config.StaticDir + "/pages/"
|
||||
pages := []string{rp + "base.html", rp + "index.html", rp + "banner.html"}
|
||||
for _, page := range assets {
|
||||
pages = append(pages, page)
|
||||
}
|
||||
return pages
|
||||
}
|
||||
|
||||
// NewServer creates new instance of offersweb server
|
||||
func NewServer(logger *zap.Logger, config Config, listener net.Listener) *Server {
|
||||
server := Server{
|
||||
log: logger,
|
||||
config: config,
|
||||
listener: listener,
|
||||
}
|
||||
|
||||
logger.Sugar().Debugf("Starting Marketing Admin UI on %s...", server.listener.Addr().String())
|
||||
fs := http.FileServer(http.Dir(server.config.StaticDir))
|
||||
mux := mux.NewRouter()
|
||||
if server.config.StaticDir != "" {
|
||||
mux.Handle("/static/", http.StripPrefix("/static", fs))
|
||||
mux.Handle("/", http.HandlerFunc(server.appHandler))
|
||||
}
|
||||
server.server = http.Server{
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
return &server
|
||||
}
|
||||
|
||||
// appHandler is web app http handler function
|
||||
func (s *Server) appHandler(w http.ResponseWriter, req *http.Request) {
|
||||
if req.URL.Path != "/" {
|
||||
s.serveError(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
rp := s.config.StaticDir + "/pages/"
|
||||
pages := []string{rp + "home.html", rp + "refOffers.html", rp + "freeOffers.html", rp + "roModal.html", rp + "foModal.html"}
|
||||
files := s.addPages(pages)
|
||||
home := template.Must(template.New("landingPage").ParseFiles(files...))
|
||||
err := home.ExecuteTemplate(w, "base", nil)
|
||||
if err != nil {
|
||||
s.serveError(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) serveError(w http.ResponseWriter, req *http.Request) {
|
||||
rp := s.config.StaticDir + "/pages/"
|
||||
files := s.addPages([]string{rp + "404.html"})
|
||||
unavailable := template.Must(template.New("404").ParseFiles(files...))
|
||||
err := unavailable.ExecuteTemplate(w, "base", nil)
|
||||
if err != nil {
|
||||
s.serveError(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
// Run starts the server that host admin web app and api endpoint
|
||||
func (s *Server) Run(ctx context.Context) error {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
var group errgroup.Group
|
||||
group.Go(func() error {
|
||||
<-ctx.Done()
|
||||
return Error.Wrap(s.server.Shutdown(nil))
|
||||
})
|
||||
group.Go(func() error {
|
||||
defer cancel()
|
||||
return Error.Wrap(s.server.Serve(s.listener))
|
||||
})
|
||||
|
||||
return group.Wait()
|
||||
}
|
||||
|
||||
// Close closes server and underlying listener
|
||||
func (s *Server) Close() error {
|
||||
return Error.Wrap(s.server.Close())
|
||||
}
|
41
satellite/marketing/marketingweb/static/css/style.css
Normal file
41
satellite/marketing/marketingweb/static/css/style.css
Normal file
@ -0,0 +1,41 @@
|
||||
html{
|
||||
height:100vh;
|
||||
width:100vw;
|
||||
}
|
||||
|
||||
body{
|
||||
height:100%;
|
||||
width:100%;
|
||||
background-color: #DDDDDD;
|
||||
}
|
||||
|
||||
.home-link:hover,.home-link p:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.banner{
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.banner-txt{
|
||||
font-family: 'Inter';
|
||||
font-size: 18px;
|
||||
color:white;
|
||||
}
|
||||
|
||||
.offer-label{
|
||||
font-family: 'Inter';
|
||||
font-size: 11px;
|
||||
line-height: 49px;
|
||||
letter-spacing: -0.100741px;
|
||||
color: #656565;
|
||||
}
|
||||
|
||||
.toggler{
|
||||
margin-top: -15px;
|
||||
}
|
||||
|
||||
.toggler:hover{
|
||||
cursor:pointer;
|
||||
}
|
BIN
satellite/marketing/marketingweb/static/img/off.jpg
Normal file
BIN
satellite/marketing/marketingweb/static/img/off.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
BIN
satellite/marketing/marketingweb/static/img/on.jpg
Normal file
BIN
satellite/marketing/marketingweb/static/img/on.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
3
satellite/marketing/marketingweb/static/pages/404.html
Normal file
3
satellite/marketing/marketingweb/static/pages/404.html
Normal file
@ -0,0 +1,3 @@
|
||||
{{define "main"}}
|
||||
<h1>404 unavailable</h1>
|
||||
{{end}}
|
13
satellite/marketing/marketingweb/static/pages/banner.html
Normal file
13
satellite/marketing/marketingweb/static/pages/banner.html
Normal file
@ -0,0 +1,13 @@
|
||||
{{define "banner"}}
|
||||
<div class="container-fluid bg-secondary banner w-100">
|
||||
<div class="row">
|
||||
<a class="home-link" href="/">
|
||||
<img class="ml-5" src="/static/img/horizontal-tar-white.svg" height="75" width="180">
|
||||
</a>
|
||||
<span class="ml-3 mr-3 mt-4 text-white">|</span>
|
||||
<a class="home-link" href="/">
|
||||
<p class="mt-4 banner-txt text-white">Marketing Credits Dashboard</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
12
satellite/marketing/marketingweb/static/pages/base.html
Normal file
12
satellite/marketing/marketingweb/static/pages/base.html
Normal file
@ -0,0 +1,12 @@
|
||||
{{define "base"}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{{template "head" .}}
|
||||
</head>
|
||||
<body>
|
||||
{{template "body" .}}
|
||||
{{template "bootstrap" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
50
satellite/marketing/marketingweb/static/pages/foModal.html
Normal file
50
satellite/marketing/marketingweb/static/pages/foModal.html
Normal file
@ -0,0 +1,50 @@
|
||||
{{define "foModal"}}
|
||||
<div class="modal fade" id="foModal" tabindex="-1" role="dialog" aria-labelledby="foModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="foModalLabel">Create Free Credit</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-4">
|
||||
<label for="offer-name">Offer Name</label>
|
||||
<input type="text" class="form-control" id="offer-name" placeholder="May Referral">
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="description">Description</label>
|
||||
<input type="text" class="form-control" id="description" placeholder="Our test with $50 for May">
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="expiration">Credit Exp Date</label>
|
||||
<input type="date" class="form-control" id="expiration" placeholder="06/01/19">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-4">
|
||||
<label for="give-credit">Give Credit</label>
|
||||
<input type="number" id="give-credit" value="$50">
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="give-credit-exp">Give Credit Exp.</label>
|
||||
<input type="date" class="form-control" id="give-credit-exp">
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="redeemable-capacity">Redeemable Capacity</label>
|
||||
<input type="text" class="form-control" id="redeemable-capacity">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-1 text-left">
|
||||
<button type="submit" class="btn btn-secondary">Create Offer</button>
|
||||
<a class="ml-3" href="/">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
@ -0,0 +1,51 @@
|
||||
{{define "freeOffers"}}
|
||||
<table class="w-100 mt-5 mb-5 rounded table table-light table-responsive">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Give Credit</th>
|
||||
<th>Free Credits Used</th>
|
||||
<th>Redeemable Capacity</th>
|
||||
<th>Created</th>
|
||||
<th>Expiration</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
<th class="text-dark m-2"><p>DEFAULT OFFER</p></th>
|
||||
<tr>
|
||||
<td>Default Free Credit</td>
|
||||
<td>$20</td>
|
||||
<td>48</td>
|
||||
<td>N/A</td>
|
||||
<td>04/18/19</td>
|
||||
<td>N/A</td>
|
||||
<td><img class="toggler" src="/static/img/on.jpg" height="50" width="50"></td>
|
||||
</tr>
|
||||
<th class="text-dark m-2"><p>CUSTOM OFFER(S)</p></th>
|
||||
<tr>
|
||||
<td>May Free Credit</td>
|
||||
<td>$50</td>
|
||||
<td>30</td>
|
||||
<td>200</td>
|
||||
<td>05/18/19</td>
|
||||
<td>06/18/2019</td>
|
||||
<td><img class="toggler" src="/static/img/off.jpg" height="50" width="50"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>June Free Credit</td>
|
||||
<td>$40</td>
|
||||
<td>0</td>
|
||||
<td>200</td>
|
||||
<td>05/18/19</td>
|
||||
<td>06/18/2019</td>
|
||||
<td><img class="toggler" src="/static/img/off.jpg" height="50" width="50"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>July Free Credit</td>
|
||||
<td>$30</td>
|
||||
<td>0</td>
|
||||
<td>200</td>
|
||||
<td>07/01/19</td>
|
||||
<td>08/01/2019</td>
|
||||
<td><img class="toggler" src="/static/img/off.jpg" height="50" width="50"></td>
|
||||
</tr>
|
||||
</table>
|
||||
{{end}}
|
16
satellite/marketing/marketingweb/static/pages/home.html
Normal file
16
satellite/marketing/marketingweb/static/pages/home.html
Normal file
@ -0,0 +1,16 @@
|
||||
{{define "main"}}
|
||||
<div class="container">
|
||||
<div class="row mt-4 mb-4">
|
||||
<h3 class="m-4 text-dark">Referral Credit Offers</h3>
|
||||
<button type="button" class="btn btn-outline-dark m-4" data-toggle="modal" data-target="#roModal">+ Create Referral Credit</button>
|
||||
</div>
|
||||
{{template "refOffers" .}}
|
||||
{{template "roModal" .}}
|
||||
<div class="row mt-4 mb-4">
|
||||
<h3 class="m-4 text-dark">Free Credit Offers</h3>
|
||||
<button type="button" class="btn btn-outline-dark m-4" data-toggle="modal" data-target="#foModal">+ Create Free Credit</button>
|
||||
</div>
|
||||
{{template "freeOffers" .}}
|
||||
{{template "foModal" .}}
|
||||
</div>
|
||||
{{end}}
|
24
satellite/marketing/marketingweb/static/pages/index.html
Normal file
24
satellite/marketing/marketingweb/static/pages/index.html
Normal file
@ -0,0 +1,24 @@
|
||||
{{define "head"}}
|
||||
<title>Referral Admin Portal</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
|
||||
{{end}}
|
||||
|
||||
{{define "body"}}
|
||||
{{template "banner" .}}
|
||||
<div class="container">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col-12">
|
||||
<div class="text-center">
|
||||
{{block "main" .}}{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{ define "bootstrap" }}
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||||
{{end}}
|
60
satellite/marketing/marketingweb/static/pages/refOffers.html
Normal file
60
satellite/marketing/marketingweb/static/pages/refOffers.html
Normal file
@ -0,0 +1,60 @@
|
||||
{{define "refOffers"}}
|
||||
<table class="w-100 mt-5 mb-5 rounded table table-light table-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Give Credit</th>
|
||||
<th>Get Credit</th>
|
||||
<th>Referrals Used</th>
|
||||
<th>Redeemable Capacity</th>
|
||||
<th>Created</th>
|
||||
<th>Expiration</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<th class="text-dark m-2"><p>CURRENT OFFER</p></th>
|
||||
<tr>
|
||||
<td>May Referral</td>
|
||||
<td>$50</td>
|
||||
<td>$50</td>
|
||||
<td>48</td>
|
||||
<td>200</td>
|
||||
<td>05/01/19</td>
|
||||
<td>06/01/19</td>
|
||||
<th><img class="toggler" src="/static/img/on.jpg" height="50" width="50"></th>
|
||||
</tr>
|
||||
<th class="text-dark m-2"><p>OTHER OFFERS</p></th>
|
||||
<tr>
|
||||
<td>Default Offer</td>
|
||||
<td>$20</td>
|
||||
<td>$20</td>
|
||||
<td>30</td>
|
||||
<td>N/A</td>
|
||||
<td>05/18/19</td>
|
||||
<td>N/A</td>
|
||||
<th><img class="toggler" src="/static/img/off.jpg" height="50" width="50"></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>June Referral</td>
|
||||
<td>$50</td>
|
||||
<td>$50</td>
|
||||
<td>0</td>
|
||||
<td>200</td>
|
||||
<td>05/18/19</td>
|
||||
<td>06/18/2019</td>
|
||||
<th><img class="toggler" src="/static/img/off.jpg" height="50" width="50"></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>June Referral</td>
|
||||
<td>$50</td>
|
||||
<td>$50</td>
|
||||
<td>0</td>
|
||||
<td>200</td>
|
||||
<td>05/18/19</td>
|
||||
<td>06/18/2019</td>
|
||||
<th><img class="toggler" src="/static/img/off.jpg" height="50" width="50"></th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{{end}}
|
56
satellite/marketing/marketingweb/static/pages/roModal.html
Normal file
56
satellite/marketing/marketingweb/static/pages/roModal.html
Normal file
@ -0,0 +1,56 @@
|
||||
{{define "roModal"}}
|
||||
<div class="modal fade" id="roModal" tabindex="-1" role="dialog" aria-labelledby="roModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="roModalLabel">Create Referral Credit</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-4">
|
||||
<label for="offer-name">Offer Name</label>
|
||||
<input type="text" class="form-control" id="offer-name" placeholder="May Referral">
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="description">Description</label>
|
||||
<input type="text" class="form-control" id="description" placeholder="Our test with $50 for May">
|
||||
</div>
|
||||
<div class="form-group col-md-4">
|
||||
<label for="expiration">Credit Exp Date</label>
|
||||
<input type="date" class="form-control" id="expiration" placeholder="06/01/19">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-2">
|
||||
<label for="give-credit">Give Credit</label>
|
||||
<input type="number" class="form-control" id="give-credit" value="$50"> </div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="give-credit-exp">Give Credit Exp.</label>
|
||||
<input type="date" class="form-control" id="give-credit-exp">
|
||||
</div>
|
||||
<div class="form-group col-md-2">
|
||||
<label for="get-credit">Get Credit</label>
|
||||
<input type="number" class="form-control" id="get-credit" value="$50"> </div>
|
||||
<div class="form-group col-md-3">
|
||||
<label for="get-credit-exp">Get Credit Exp.</label>
|
||||
<input type="date" class="form-control" id="get-credit-exp">
|
||||
</div>
|
||||
<div class="form-group col-md-3">
|
||||
<label for="redeemable-capacity">Redeemable Capacity</label>
|
||||
<input type="text" class="form-control" id="redeemable-capacity">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-1 text-left">
|
||||
<button type="submit" class="btn btn-secondary">Create Offer</button>
|
||||
<a class="ml-3" href="/">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
@ -50,6 +50,7 @@ import (
|
||||
"storj.io/storj/satellite/mailservice"
|
||||
"storj.io/storj/satellite/mailservice/simulate"
|
||||
"storj.io/storj/satellite/marketing"
|
||||
"storj.io/storj/satellite/marketing/marketingweb"
|
||||
"storj.io/storj/satellite/metainfo"
|
||||
"storj.io/storj/satellite/orders"
|
||||
"storj.io/storj/satellite/payments"
|
||||
@ -120,6 +121,8 @@ type Config struct {
|
||||
Mail mailservice.Config
|
||||
Console consoleweb.Config
|
||||
|
||||
Marketing marketingweb.Config
|
||||
|
||||
Vouchers vouchers.Config
|
||||
|
||||
Version version.Config
|
||||
@ -204,6 +207,11 @@ type Peer struct {
|
||||
Service *console.Service
|
||||
Endpoint *consoleweb.Server
|
||||
}
|
||||
|
||||
Marketing struct {
|
||||
Listener net.Listener
|
||||
Endpoint *marketingweb.Server
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new satellite
|
||||
@ -579,6 +587,22 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, config *Config, ve
|
||||
)
|
||||
}
|
||||
|
||||
{ // setup marketing portal
|
||||
log.Debug("Setting up marketing server")
|
||||
marketingConfig := config.Marketing
|
||||
|
||||
peer.Marketing.Listener, err = net.Listen("tcp", marketingConfig.Address)
|
||||
if err != nil {
|
||||
return nil, errs.Combine(err, peer.Close())
|
||||
}
|
||||
|
||||
peer.Marketing.Endpoint = marketingweb.NewServer(
|
||||
peer.Log.Named("marketing:endpoint"),
|
||||
marketingConfig,
|
||||
peer.Marketing.Listener,
|
||||
)
|
||||
}
|
||||
|
||||
return peer, nil
|
||||
}
|
||||
|
||||
@ -626,6 +650,9 @@ func (peer *Peer) Run(ctx context.Context) (err error) {
|
||||
group.Go(func() error {
|
||||
return errs2.IgnoreCanceled(peer.Console.Endpoint.Run(ctx))
|
||||
})
|
||||
group.Go(func() error {
|
||||
return errs2.IgnoreCanceled(peer.Marketing.Endpoint.Run(ctx))
|
||||
})
|
||||
|
||||
return group.Wait()
|
||||
}
|
||||
@ -651,6 +678,12 @@ func (peer *Peer) Close() error {
|
||||
errlist.Add(peer.Mail.Service.Close())
|
||||
}
|
||||
|
||||
if peer.Marketing.Endpoint != nil {
|
||||
errlist.Add(peer.Marketing.Endpoint.Close())
|
||||
} else if peer.Marketing.Listener != nil {
|
||||
errlist.Add(peer.Marketing.Listener.Close())
|
||||
}
|
||||
|
||||
// close services in reverse initialization order
|
||||
if peer.Repair.Repairer != nil {
|
||||
errlist.Add(peer.Repair.Repairer.Close())
|
||||
|
6
scripts/testdata/satellite-config.yaml.lock
vendored
6
scripts/testdata/satellite-config.yaml.lock
vendored
@ -157,6 +157,12 @@ kademlia.operator.wallet: ""
|
||||
# uri which is used when retrieving new access token
|
||||
# mail.token-uri: ""
|
||||
|
||||
# server address of the marketing Admin GUI
|
||||
# marketing.address: "0.0.0.0:8090"
|
||||
|
||||
# path to static resources
|
||||
# marketing.static-dir: ""
|
||||
|
||||
# lifespan of bandwidth agreements in days
|
||||
# metainfo.bw-expiration: 45
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user