-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Report FQDN #144
Report FQDN #144
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just leaving a few drive-by comments. Also, don't forget to update the main feature chart thing in the readme.md
.
295121c
to
dc6f651
Compare
@AndersonQ Just to make sure we're on the same page, this PR can still continue even before we make the decision on the default behavior in Beats/Agent. |
Results from when I ran on MacOS 12.6.2 arm64
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that FQDNs are case-insensitive I think it would be helpful for this library to normalize the values to lowercase despite what the OS gives.
2e442ef
to
bb1df24
Compare
/test |
Re-ran tests on MacOS 12.6.2 arm64
|
it does make sense. but then it'd also be true for the hostname and domain, right? For consistency, I think they should be aligned. However it'd be a breaking change for hostname, what I'd say is less than ideal... In that sense, also considering it's just a lib, I'd let this decision for whoever is using it. We returns as we get, the user transforms as they need. What do you think @andrewkroh? |
Alright, current round of CI errors seems unrelated? |
@fearful-symmetry, @andrewkroh do any of you are familiar with these tests "failing"? The culprit is
|
That's fine. Either when we use this in Beats / Agent or when we create the mappings for this field we should ensure that the value is normalized. |
Some of the FQDN tests are failing on ubuntu under both CGO_ENABLED=0 and CGO_ENABLED=1. See the "Tests" tab: |
f970dae
to
15c572b
Compare
} | ||
|
||
func domainname() (string, error) { | ||
return "", nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use sysctl to fetch kern.nisdomainname
here? That looks like it returns the same thing in my testing. Then you would not need a CGO and non-CGO implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is already the no Cgo implementation. I'm already using Cgo for the getdomainname
syscall.
sysctl
is an external application, right? I'm avoiding invoking any external application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I wasn't clear. We can invoke the sysctl
syscall without needing CGO. Then we can have a single implementation that works for all darwin builds. There should be some examples already in the codebase (if not see the os.Hostname()
implementation in the stdlib for darwin).
return "", err | ||
} | ||
|
||
if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I run hostname -f
on my machine it doesn't add .local
?
% hostname
mac16-m1
% hostname -f
mac16-m1
% hostname -d
mac16-m1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you sure you haven't set your domain name to "" somehow?
I'm assuming it's your Elastic laptop, thus with Elastic Shield installed. Am I correct?
Have you used the tool in Elastic shield to rename the laptop? That would explain this behaviour
) | ||
|
||
func fqdn() (string, error) { | ||
hostname, err := os.Hostname() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I use sudo scutil --set HostName foo.engineering.example.com
. Then hostname returns:
% sudo scutil --set HostName foo.engineering.example.com
% hostname -f
foo.engineering.example.com
% hostname -s
foo
% hostname -d
engineering.example.com
But go-sysinfo returns:
"name": "foo.engineering.example.com",
"domain": "",
"fqdn": "foo.engineering.example.com.local",
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It gets even more confusing if the machine has a NIS domain set AND the HostName is fully-qualified. I think we need to be clearify what we are reporting. Do we want to report the NIS domain or do we want to report domain suffix that is part of the machine's fully-qualified DNS name (man hostname
has some details).
sudo sysctl kern.nisdomainname=nis.domain
"name": "foo.engineering.example.com",
"domain": "nis.domain",
"fqdn": "foo.engineering.example.com.nis.domain",
return "", nil | ||
} | ||
|
||
func domainname() (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the NIS domain can be read from /proc/sys/kernel/domainname
. Then you wouldn't need separate CGO and non-CGO implementations. And probably the docker based integration testing could be removed since you could simulate various hostname and domainname via the filesystem (probably like newLinuxSystem("testdata/my_test_proc")
).
https://www.kernel.org/doc/html/latest/admin-guide/sysctl/kernel.html#domainname-hostname
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the same question. I was alluding to this in my other comment at #144 (comment). With this comment I was mainly focused on the code as it was without debating DNS vs NIS. I haven't looked at the latest changes to see how this has evolved, but I still think we need to clear on what we are reporting.
providers/shared/fqdn.go
Outdated
fqdn, err := fqdnFromEtcHosts(hostname) | ||
if err != nil { | ||
errs = fmt.Errorf("could not get FQDN, all methods failed: %w", err) | ||
} | ||
if fqdn != "" { | ||
return fqdn, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm missing something. Why parse /etc/hosts
? The net.LookupCNAME
, net.LookuIP
and net.LookupAddr
will use /etc/hosts
if the resolver on the system uses that file for name resolution. Is there a specific use case this is addressing? If so I really think we need it described in the docstring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the recommendation I found on man hostname
:
The recommended method of setting the FQDN is to make the hostname be an alias for the fully qualified name using /etc/hosts, DNS, or NIS.
And I didn't find on net
, net.LookupCNAME/IP/Addr
docs saying explicitly they use etc/hosts
.
On Unix systems, the resolver has two options for resolving names. It can use a pure Go resolver that sends DNS requests directly to the servers listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C library routines such as getaddrinfo and getnameinfo.
By default the pure Go resolver is used [...]
But if you're sure it's redundant I can remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep they go through '/etc/hosts' the pure go one use readHost where the testHookHostsPath
is /etc/hosts
and the cgo implementations all use the libc resolver which will use /etc/hosts
if your system is setup to do that, and if it isn't setup that way you don't want to parse /etc/hosts
anyway.
Co-authored-by: Lee E Hinman <[email protected]>
Co-authored-by: Lee E Hinman <[email protected]>
Co-authored-by: Lee E Hinman <[email protected]>
howett.net/plist v0.0.0-20181124034731-591f970eefbb | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.0 // indirect | ||
github.com/pkg/errors v0.8.1 // indirect | ||
github.com/Microsoft/go-winio v0.6.0 // indirect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems off, so many new imports?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are indirect, I believe most come from test dependencies, most likely github.com/docker/docker
. I'm using it to be able to do a integration test for the FQDN.
Here is why go-winio
is needed
# github.com/Microsoft/go-winio
github.com/elastic/go-sysinfo/providers/linux
github.com/elastic/go-sysinfo/providers/linux.test
github.com/docker/docker/client
github.com/docker/go-connections/sockets
github.com/Microsoft/go-winio
# v0.6.0
(main module does not need module v0.6.0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
besides the only direct dependency added was github.com/docker/docker
providers/shared/fqdn.go
Outdated
return "" | ||
} | ||
|
||
fileds := strings.FieldsFunc(line, func(r rune) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/fileds/fields
providers/shared/fqdn.go
Outdated
// fields[0] is the ip address | ||
cannonical, aliases := fileds[1], fileds[1:] | ||
|
||
// TODO: confirm: a name should not repeat on different addresses. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adressed or issue please
providers/windows/host_windows.go
Outdated
"but data size should fit into buffer") | ||
} else { | ||
// Grow the buffer and try again. | ||
// Should we limit its growth? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but then what would be the limit?
size
is the needed size for a buffer to fit the FQDN. The unix implementation does not limit the size, so I'd say it should be fine. it hardly wouldn't fit into memory, if it don't, I'd say windows is on a lot more trouble than us.
@AndersonQ would it also be possible to update the description with the algorithm you used when default values were used, etc.. |
@jlind23 done |
@michalpristas, @andrewkroh, @leehinman, @fearful-symmetry I updated the PR, it's ready for final review. I still need to add the changes to the changelog/readme though |
|
||
info := host.Info() | ||
data, _ := json.MarshalIndent(info, "", " ") | ||
t.Logf(string(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this test? Doesn't seem to be doing much beyond logging the result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it does not. I just followed the pattern that was already in place for linux.
t.Fatalf("environment variable %s not set, please set a Go version", | ||
envKey) | ||
} | ||
image := "golang:" + goversion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extremely pedantic question: What, exactly, are we trying to test with the containers? Just how this will behave in a containerized environment in general? If we wanted to test this under different OS-specific conditions, we might want to target containers built around centos, Feodra, ubuntu, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes that is correct. I haven't found any testing checking hostname info. That was the easiest way I found to set up an environment I can control hostname and domain to test. It isn't comprehensive, but it's more that there was before.
providers/shared/fqdn.go
Outdated
fqdn, err := fqdnFromEtcHosts(hostname) | ||
if err != nil { | ||
errs = fmt.Errorf("could not get FQDN, all methods failed: %w", err) | ||
} | ||
if fqdn != "" { | ||
return fqdn, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep they go through '/etc/hosts' the pure go one use readHost where the testHookHostsPath
is /etc/hosts
and the cgo implementations all use the libc resolver which will use /etc/hosts
if your system is setup to do that, and if it isn't setup that way you don't want to parse /etc/hosts
anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR adds FQDN to
types.HostInfo
and expands thelinux
,darwin
andwindows
providers to retrieve and populate the newly added fields.The FQDN is obtained by:
net.LookupCNAME
for hostnamenet.LookupIP
for hostnamenet.LookupAddr
for the obateined IPComputerNamePhysicalDnsFullyQualified
How to test:
Integration tests:
There are integration tests for linux, which requires docker, to run them use the build tag
integration
. TheTestHost_FQDN
automatically starts docker containers and runs the tests.Manually:
Run the test
TestHost
for the desired provider,linux
,windows
ordarwin
:On docker:
The
TestHost
test only prints the information collected, you need to check it for correctness.look for
full output
Tested on:
Linux
Mac
Windows
Aixcloses Report FQDN on HostInfo #149
Relates to Report host name as FQDN on all platforms beats#1070