storagenode: display quic status on SNO dashboard

This change includes storagenode QUIC status on SNO dashboard.
If disabled, it displays warning for SNOs to foward their
UDP port for quic.

Change-Id: I8d28c9c0f5f1e90d80b7c18b9e1e7b78c5e45609
This commit is contained in:
Clement Sam 2021-12-21 05:33:57 +00:00
parent ff653f6f22
commit 589c82f23e
10 changed files with 64 additions and 4 deletions

View File

@ -118,6 +118,9 @@ func (p *Server) DRPC() *drpcmux.Mux { return p.public.mux }
// PrivateDRPC returns the server's dRPC mux for registration purposes.
func (p *Server) PrivateDRPC() *drpcmux.Mux { return p.private.mux }
// IsQUICEnabled checks if QUIC is enabled.
func (p *Server) IsQUICEnabled() bool { return !p.public.disableQUIC && p.public.quicListener != nil }
// Close shuts down the server.
func (p *Server) Close() error {
p.mu.Lock()

View File

@ -61,13 +61,17 @@ type Service struct {
walletFeatures operator.WalletFeatures
startedAt time.Time
versionInfo version.Info
quicEnabled bool
configuredPort string
}
// NewService returns new instance of Service.
func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Store, version *checker.Service,
allocatedDiskSpace memory.Size, walletAddress string, versionInfo version.Info, trust *trust.Pool,
reputationDB reputation.DB, storageUsageDB storageusage.DB, pricingDB pricing.DB, satelliteDB satellites.DB,
pingStats *contact.PingStats, contact *contact.Service, estimation *estimatedpayouts.Service, usageCache *pieces.BlobsUsageCache, walletFeatures operator.WalletFeatures) (*Service, error) {
pingStats *contact.PingStats, contact *contact.Service, estimation *estimatedpayouts.Service, usageCache *pieces.BlobsUsageCache,
walletFeatures operator.WalletFeatures, port string, quicEnabled bool) (*Service, error) {
if log == nil {
return nil, errs.New("log can't be nil")
}
@ -119,6 +123,8 @@ func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Stor
startedAt: time.Now(),
versionInfo: versionInfo,
walletFeatures: walletFeatures,
quicEnabled: quicEnabled,
configuredPort: port,
}, nil
}
@ -149,6 +155,9 @@ type Dashboard struct {
UpToDate bool `json:"upToDate"`
StartedAt time.Time `json:"startedAt"`
ConfiguredPort string `json:"configuredPort"`
QUICEnabled bool `json:"quicEnabled"`
}
// GetDashboardData returns stale dashboard data.
@ -165,6 +174,9 @@ func (s *Service) GetDashboardData(ctx context.Context) (_ *Dashboard, err error
data.LastPinged = s.pingStats.WhenLastPinged()
data.AllowedVersion, data.UpToDate = s.version.IsAllowed(ctx)
data.QUICEnabled = s.quicEnabled
data.ConfiguredPort = s.configuredPort
stats, err := s.reputationDB.All(ctx)
if err != nil {
return nil, SNOServiceErr.Wrap(err)

View File

@ -635,6 +635,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
}
{ // setup storage node operator dashboard
_, port, _ := net.SplitHostPort(peer.Addr())
peer.Console.Service, err = console.NewService(
peer.Log.Named("console:service"),
peer.DB.Bandwidth(),
@ -653,6 +654,8 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
peer.Estimation.Service,
peer.Storage2.BlobsCache,
config.Operator.WalletFeatures,
port,
peer.Server.IsQUICEnabled(),
)
if err != nil {
return nil, errs.Combine(err, peer.Close())

View File

@ -17,6 +17,28 @@
<p v-if="online" class="title-area__info-container__info-item__content online-status">Online</p>
<p v-else class="title-area__info-container__info-item__content offline-status">Offline</p>
</div>
<div class="title-area-divider" />
<VInfo
v-if="info.quicEnabled"
:text="'QUIC is configured to use UDP port ' + info.configuredPort"
>
<div class="title-area__info-container__info-item">
<p class="title-area__info-container__info-item__title">QUIC</p>
<p class="title-area__info-container__info-item__content online-status">OK</p>
</div>
</VInfo>
<VInfo
v-if="!info.quicEnabled"
:text="'QUIC is misconfigured. You must forward port ' + info.configuredPort + ' for both TCP and UDP to enable QUIC.'"
bold-text="See https://docs.storj.io/node/dependencies/port-forwarding on how to do this."
>
<div class="title-area__info-container__info-item">
<p class="title-area__info-container__info-item__title">QUIC</p>
<p class="title-area__info-container__info-item__content offline-status">Misconfigured</p>
</div>
</VInfo>
<div class="title-area-divider" />
<div class="title-area__info-container__info-item">
<p class="title-area__info-container__info-item__title">UPTIME</p>
@ -77,14 +99,18 @@ class NodeInfo {
public allowedVersion: string;
public wallet: string;
public isLastVersion: boolean;
public quicEnabled: boolean
public configuredPort: string
public constructor(id: string, status: string, version: string, allowedVersion: string, wallet: string, isLastVersion: boolean) {
public constructor(id: string, status: string, version: string, allowedVersion: string, wallet: string, isLastVersion: boolean, quicEnabled: boolean, port: string) {
this.id = id;
this.status = status;
this.version = this.toVersionString(version);
this.allowedVersion = this.toVersionString(allowedVersion);
this.wallet = wallet;
this.isLastVersion = isLastVersion;
this.quicEnabled = quicEnabled
this.configuredPort = port
}
private toVersionString(version: string): string {
@ -116,7 +142,7 @@ export default class SNOContentTitle extends Vue {
const nodeInfo = this.$store.state.node.info;
return new NodeInfo(nodeInfo.id, nodeInfo.status, nodeInfo.version, nodeInfo.allowedVersion, nodeInfo.wallet,
nodeInfo.isLastVersion);
nodeInfo.isLastVersion, nodeInfo.quicEnabled, nodeInfo.configuredPort);
}
public get online(): boolean {

View File

@ -61,6 +61,8 @@ export function newNodeModule(service: StorageNodeService): StoreModule<StorageN
nodeInfo.wallet,
nodeInfo.walletFeatures,
nodeInfo.isUpToDate,
nodeInfo.quicEnabled,
nodeInfo.configuredPort
);
state.utilization = new Utilization(

View File

@ -45,7 +45,7 @@ export class StorageNodeApi {
const bandwidth: Traffic = new Traffic(data.bandwidth.used);
return new Dashboard(data.nodeID, data.wallet, data.walletFeatures || [], satellites, diskSpace, bandwidth,
new Date(data.lastPinged), new Date(data.startedAt), data.version, data.allowedVersion, data.upToDate);
new Date(data.lastPinged), new Date(data.startedAt), data.version, data.allowedVersion, data.upToDate, data.quicEnabled, data.configuredPort);
}
/**

View File

@ -17,6 +17,8 @@ export class Node {
public wallet: string = '',
public walletFeatures: string[] = [],
public isLastVersion: boolean = false,
public quicEnabled: boolean = false,
public configuredPort: string = '',
) {}
}
@ -73,6 +75,8 @@ export class Dashboard {
public version: string,
public allowedVersion: string,
public isUpToDate: boolean,
public quicEnabled: boolean,
public configuredPort: string,
) { }
}

View File

@ -58,6 +58,8 @@ describe('DiskStatChart', (): void => {
'0.1.1',
'0.2.2',
false,
true,
'13000',
),
),
);

View File

@ -73,6 +73,8 @@ describe('EstimationPeriodDropdown', (): void => {
'0.1.1',
'0.2.2',
false,
true,
'13000',
);
store.commit(NODE_MUTATIONS.POPULATE_STORE, dashboardInfo);

View File

@ -53,6 +53,8 @@ describe('mutations', () => {
'0.1.1',
'0.2.2',
false,
true,
'13000',
);
store.commit(NODE_MUTATIONS.POPULATE_STORE, dashboardInfo);
@ -191,6 +193,8 @@ describe('actions', () => {
'0.1.1',
'0.2.2',
false,
true,
'13000',
),
),
);
@ -335,6 +339,8 @@ describe('getters', () => {
'0.1.1',
'0.2.2',
false,
true,
'13000',
);
store.commit(NODE_MUTATIONS.POPULATE_STORE, dashboardInfo);