From 6ed87cafa2439050cdd3529a834e01df30f0a000 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 22 Aug 2024 12:05:15 +0200 Subject: [PATCH] allow to choose hostname and FQDN to be lowercased or not providers.LowercaseHostname and providers.SetLowerHostname allow to control hostname case sensitivity This addresses the behavior change introduced in v1.11.0 and reverted in v1.14.1. By default, hostnames are not lowercased. --- .changelog/236.txt | 3 +++ providers/aix/host_aix_ppc64.go | 6 ++++++ providers/darwin/host_darwin.go | 6 ++++++ providers/doc.go | 30 +++++++++++++++++++++++++++ providers/linux/host_linux.go | 9 +++++++- providers/lowerhostname.go | 34 +++++++++++++++++++++++++++++++ providers/shared/fqdn.go | 6 ++++++ providers/shared/fqdn_test.go | 23 +++++++++++++++++---- providers/windows/host_windows.go | 7 ++++++- 9 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 .changelog/236.txt create mode 100644 providers/doc.go create mode 100644 providers/lowerhostname.go diff --git a/.changelog/236.txt b/.changelog/236.txt new file mode 100644 index 0000000..9d4ece1 --- /dev/null +++ b/.changelog/236.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +Allow to choose hostname and FQDN to be lowercased or not +``` diff --git a/providers/aix/host_aix_ppc64.go b/providers/aix/host_aix_ppc64.go index 9af09e5..9be0b04 100644 --- a/providers/aix/host_aix_ppc64.go +++ b/providers/aix/host_aix_ppc64.go @@ -34,9 +34,11 @@ import ( "errors" "fmt" "os" + "strings" "time" "github.com/elastic/go-sysinfo/internal/registry" + "github.com/elastic/go-sysinfo/providers" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" ) @@ -190,6 +192,10 @@ func (r *reader) hostname(h *host) { if r.addErr(err) { return } + + if providers.LowercaseHostname() { + v = strings.ToLower(v) + } h.info.Hostname = v } diff --git a/providers/darwin/host_darwin.go b/providers/darwin/host_darwin.go index 8b53eee..b3259b3 100644 --- a/providers/darwin/host_darwin.go +++ b/providers/darwin/host_darwin.go @@ -24,9 +24,11 @@ import ( "errors" "fmt" "os" + "strings" "time" "github.com/elastic/go-sysinfo/internal/registry" + "github.com/elastic/go-sysinfo/providers" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" ) @@ -225,6 +227,10 @@ func (r *reader) hostname(h *host) { if r.addErr(err) { return } + + if providers.LowercaseHostname() { + v = strings.ToLower(v) + } h.info.Hostname = v } diff --git a/providers/doc.go b/providers/doc.go new file mode 100644 index 0000000..9ec0afe --- /dev/null +++ b/providers/doc.go @@ -0,0 +1,30 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// Package providers +// +// # Hostname Behavior +// +// Starting from version v1.11.0, the host provider started automatically +// lowercasing hostnames. This behavior was reverted in v1.14.1. +// +// To provide flexibility and allow users to control this behavior, the +// `LowercaseHostname` and `SetLowerHostname` functions were added. +// +// By default, hostnames are not lowercased. If you require hostnames to be +// lowercased, explicitly set this using `SetLowerHostname(true)`. +package providers diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 24e72d0..152b77c 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -23,11 +23,13 @@ import ( "fmt" "os" "path/filepath" + "strings" "time" "github.com/prometheus/procfs" "github.com/elastic/go-sysinfo/internal/registry" + "github.com/elastic/go-sysinfo/providers" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" ) @@ -176,7 +178,8 @@ func newHost(fs procFS) (*host, error) { } type reader struct { - errs []error + errs []error + lowerHostname bool } func (r *reader) addErr(err error) bool { @@ -233,6 +236,10 @@ func (r *reader) hostname(h *host) { if r.addErr(err) { return } + + if providers.LowercaseHostname() { + v = strings.ToLower(v) + } h.info.Hostname = v } diff --git a/providers/lowerhostname.go b/providers/lowerhostname.go new file mode 100644 index 0000000..6612b10 --- /dev/null +++ b/providers/lowerhostname.go @@ -0,0 +1,34 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package providers + +import "sync/atomic" + +var lowerHostname atomic.Bool + +// LowercaseHostname returns if the hostname should be lowercased or not. +func LowercaseHostname() bool { + return lowerHostname.Load() +} + +// SetLowerHostname instruct the host provider to lowercase the hostname. +// The LowercaseHostname and SetLowerHostname exist as a fix to allow the user +// to choose or not this behaviour introduced on v1.11.0 and reverted on v1.14.1. +func SetLowerHostname(lower bool) { + lowerHostname.Store(lower) +} diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index b8bb455..e257999 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -25,6 +25,8 @@ import ( "net" "os" "strings" + + "github.com/elastic/go-sysinfo/providers" ) // FQDNWithContext attempts to lookup the host's fully-qualified domain name and returns it. @@ -67,6 +69,10 @@ func fqdn(ctx context.Context, hostname string) (string, error) { if cname != "" { cname = strings.TrimSuffix(cname, ".") + if providers.LowercaseHostname() { + return strings.ToLower(cname), nil + } + // Go might lowercase the cname "for convenience". Therefore, if cname // is the same as hostname, return hostname as is. // See https://github.com/golang/go/blob/go1.22.5/src/net/hosts.go#L38 diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index ffddd5a..c5ac4a0 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -26,14 +26,22 @@ import ( "time" "github.com/stretchr/testify/require" + + "github.com/elastic/go-sysinfo/providers" ) func TestFQDN(t *testing.T) { + lowercaseHostname := providers.LowercaseHostname() + defer func() { + providers.SetLowerHostname(lowercaseHostname) + }() + tests := map[string]struct { - osHostname string - expectedFQDN string - expectedErrRegex string - timeout time.Duration + lowercaseHostname bool + osHostname string + expectedFQDN string + expectedErrRegex string + timeout time.Duration }{ // This test case depends on network, particularly DNS, // being available. If it starts to fail often enough @@ -59,6 +67,12 @@ func TestFQDN(t *testing.T) { expectedFQDN: "eLaSTic.co", expectedErrRegex: "", }, + "long_mixed_case_hostname_lowercaseHostname": { + lowercaseHostname: true, + osHostname: "eLaSTic.co", + expectedFQDN: "elastic.co", + expectedErrRegex: "", + }, "nonexistent_timeout": { osHostname: "foobarbaz", expectedFQDN: "", @@ -77,6 +91,7 @@ func TestFQDN(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() + providers.SetLowerHostname(test.lowercaseHostname) actualFQDN, err := fqdn(ctx, test.osHostname) require.Equal(t, test.expectedFQDN, actualFQDN) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index ed94881..c90bced 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -28,9 +28,10 @@ import ( stdwindows "golang.org/x/sys/windows" - windows "github.com/elastic/go-windows" + "github.com/elastic/go-windows" "github.com/elastic/go-sysinfo/internal/registry" + "github.com/elastic/go-sysinfo/providers" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" ) @@ -161,6 +162,10 @@ func (r *reader) hostname(h *host) { if r.addErr(err) { return } + + if providers.LowercaseHostname() { + v = strings.ToLower(v) + } h.info.Hostname = v }