Skip to content

Commit 8903fa5

Browse files
committed
Add whitespace checks to audit analyze
Whitespace in a leafnode server name, JetStream domain, etc. could cause issues. As discussed in nats-io/nats-server#5676. Signed-off-by: reubenninan <reuben@nats.io>
1 parent 80dfaa1 commit 8903fa5

File tree

3 files changed

+108
-2
lines changed

3 files changed

+108
-2
lines changed

internal/audit/checks.go

+15
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,21 @@ func GetDefaultChecks() []Check {
156156
Description: "Verify that all nodes part of the meta group agree on the meta cluster leader",
157157
fun: checkMetaClusterLeader,
158158
},
159+
{
160+
Name: "Whitespace in leafnode server names",
161+
Description: "Verify that no leafnode contains whitespace in its name",
162+
fun: checkLeafnodeServerNamesForWhitespace,
163+
},
164+
{
165+
Name: "Whitespace in JetStream domains",
166+
Description: "Verify that no JetStream server is configured with whitespace in its domain",
167+
fun: checkJetStreamDomainsForWhitespace,
168+
},
169+
{
170+
Name: "Whitespace in cluster name",
171+
Description: "Verify that no cluster name contains whitespace",
172+
fun: checkClusterNamesForWhitespace,
173+
},
159174
}
160175
}
161176

internal/audit/cluster_checks.go

+60-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ package audit
1616
import (
1717
"errors"
1818
"fmt"
19+
"reflect"
20+
"sort"
21+
"strings"
22+
"unicode"
23+
1924
"github.com/dustin/go-humanize"
2025
"github.com/nats-io/nats-server/v2/server"
2126
"github.com/nats-io/natscli/internal/archive"
22-
"reflect"
23-
"sort"
27+
"golang.org/x/exp/maps"
2428
)
2529

2630
// checkClusterMemoryUsageOutliers creates a parametrized check to verify the memory usage of any given node in a
@@ -214,3 +218,57 @@ func makeCheckClusterHighHAAssets(haAssetsThreshold int) checkFunc {
214218
return Pass, nil
215219
}
216220
}
221+
222+
func checkClusterNamesForWhitespace(reader *archive.Reader, examples *ExamplesCollection) (Outcome, error) {
223+
224+
for _, clusterName := range reader.GetClusterNames() {
225+
if strings.ContainsFunc(clusterName, unicode.IsSpace) {
226+
examples.add("Cluster: %s", clusterName)
227+
}
228+
}
229+
230+
if examples.Count() > 0 {
231+
logCritical("Found %d clusters with names containing whitespace", examples.Count())
232+
return Fail, nil
233+
}
234+
235+
return Pass, nil
236+
}
237+
238+
func checkLeafnodeServerNamesForWhitespace(r *archive.Reader, examples *ExamplesCollection) (Outcome, error) {
239+
240+
for _, clusterName := range r.GetClusterNames() {
241+
clusterTag := archive.TagCluster(clusterName)
242+
243+
leafnodesWithWhitespace := map[string]struct{}{}
244+
245+
for _, serverName := range r.GetClusterServerNames(clusterName) {
246+
serverTag := archive.TagServer(serverName)
247+
248+
var serverLeafz server.Leafz
249+
err := r.Load(&serverLeafz, clusterTag, serverTag, archive.TagServerLeafs())
250+
if err != nil {
251+
logWarning("Artifact 'LEAFZ' is missing for server %s", serverName)
252+
continue
253+
}
254+
255+
for _, leaf := range serverLeafz.Leafs {
256+
// check if leafnode name contains whitespace
257+
if strings.ContainsFunc(leaf.Name, unicode.IsSpace) {
258+
leafnodesWithWhitespace[leaf.Name] = struct{}{}
259+
}
260+
}
261+
}
262+
263+
if len(leafnodesWithWhitespace) > 0 {
264+
examples.add("Cluster %s: %v", clusterName, maps.Keys(leafnodesWithWhitespace))
265+
}
266+
}
267+
268+
if examples.Count() > 0 {
269+
logCritical("Found %d clusters with leafnode names containing whitespace", examples.Count())
270+
return Fail, nil
271+
}
272+
273+
return Pass, nil
274+
}

internal/audit/server_checks.go

+33
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ package audit
1616
import (
1717
"errors"
1818
"fmt"
19+
"strings"
20+
"unicode"
21+
1922
"github.com/dustin/go-humanize"
2023
"github.com/nats-io/nats-server/v2/server"
2124
"github.com/nats-io/natscli/internal/archive"
@@ -230,3 +233,33 @@ func makeCheckServerResourceLimits(memoryUsageThreshold, storeUsageThreshold flo
230233
return Pass, nil
231234
}
232235
}
236+
237+
func checkJetStreamDomainsForWhitespace(r *archive.Reader, examples *ExamplesCollection) (Outcome, error) {
238+
239+
for _, clusterName := range r.GetClusterNames() {
240+
clusterTag := archive.TagCluster(clusterName)
241+
242+
for _, serverName := range r.GetClusterServerNames(clusterName) {
243+
serverTag := archive.TagServer(serverName)
244+
245+
var serverJsz server.JSInfo
246+
err := r.Load(&serverJsz, clusterTag, serverTag, archive.TagServerJetStream())
247+
if err != nil {
248+
logWarning("Artifact 'JSZ' is missing for server %s", serverName)
249+
continue
250+
}
251+
252+
// check if jetstream domain contains whitespace
253+
if strings.ContainsFunc(serverJsz.Config.Domain, unicode.IsSpace) {
254+
examples.add("Cluster %s Server %s Domain %s", clusterName, serverName, serverJsz.Config.Domain)
255+
}
256+
}
257+
}
258+
259+
if examples.Count() > 0 {
260+
logCritical("Found %d servers with JetStream domains containing whitespace", examples.Count())
261+
return Fail, nil
262+
}
263+
264+
return Pass, nil
265+
}

0 commit comments

Comments
 (0)