Skip to content

Commit

Permalink
Improvements and Kubernetes v1.22 support (#46)
Browse files Browse the repository at this point in the history
* Make golangci.yml effective again

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* internal/utils: remove dead code

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* internal: fix found linter warnings

After making linter configuration effective, linter popped up new
issues. This commit addresses them in a minimal way.

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* Hide goreleaser.yml file

As usually it is hidden.

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* Update Go Kubernetes modules to v1.22.0

As part of #45

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* go.mod: update viper to latest version

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* go.mod: update nri-kubernetes to latest version

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* .github/workflows/push_pr.yml: fix link to Kubernetes releases

Previous link now redirects to new link and old link will be not
available by the end of this year.

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* deploy: make manifests compatible with Kubernetes v1.22+

As part of #45.

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* .github/workflows/push_pr.yml: test against Kubernetes v1.22.X

Closes #45

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* .golangci.yml: increase timeout

Closes #38

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* go.mod: force-update github.com/pkg/sftp to latest version

To fix snyk security scan. Upstream update is pending here:
spf13/afero#312

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* .github/workflows/push_pr.yml: drop support for Kubernetes v1.15

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>

* .github/workflows/push_pr.yml: bump patch versions for Kubernetes

Signed-off-by: Mateusz Gozdek <mgozdek@microsoft.com>
  • Loading branch information
invidian committed Sep 2, 2021
1 parent 841e574 commit acfc9ae
Show file tree
Hide file tree
Showing 14 changed files with 289 additions and 103 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/push_pr.yml
Expand Up @@ -83,11 +83,11 @@ jobs:
e2eTests:
runs-on: ubuntu-20.04
strategy:
max-parallel: 7 # len(k8sVersion) is a good number to have here
max-parallel: 8 # len(k8sVersion) is a good number to have here
matrix:
# Latest patch version can be found in https://github.com/kubernetes/sig-release/blob/master/releases/patch-releases.md
# Latest patch version can be found in https://github.com/kubernetes/website/blob/main/content/en/releases/patch-releases.md
# Some versions might not be available yet in https://storage.googleapis.com/kubernetes-release/release/v1.X.Y/bin/linux/amd64/kubelet
k8sVersion: [ "v1.15.12", "v1.16.15", "v1.17.17", "v1.18.18", "v1.19.10", "v1.20.6", "v1.21.0" ]
k8sVersion: [ "v1.16.15", "v1.17.17", "v1.18.20", "v1.19.14", "v1.20.10", "v1.21.4", "v1.22.0" ]
env:
DOCKER_BUILDKIT: '1' # Setting DOCKER_BUILDKIT=1 ensures TARGETOS and TARGETARCH are populated
steps:
Expand Down
3 changes: 3 additions & 0 deletions golangci.yml → .golangci.yml
@@ -1,3 +1,6 @@
run:
timeout: 5m

linters:
enable:
- govet
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions deploy/gcp.yaml.template
Expand Up @@ -11,7 +11,7 @@ kind: Namespace
metadata:
name: test-ns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: newrelic
Expand All @@ -27,7 +27,7 @@ rules:
- "namespaces"
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: newrelic
Expand Down
4 changes: 2 additions & 2 deletions deploy/minikube.yaml
Expand Up @@ -11,7 +11,7 @@ kind: Namespace
metadata:
name: test-ns
---
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: newrelic
Expand All @@ -27,7 +27,7 @@ rules:
- "namespaces"
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: newrelic
Expand Down
13 changes: 7 additions & 6 deletions go.mod
Expand Up @@ -3,13 +3,14 @@ module github.com/newrelic/nri-discovery-kubernetes
go 1.13

require (
github.com/imdario/mergo v0.3.8 // indirect
github.com/newrelic/nri-kubernetes/v2 v2.5.0
github.com/newrelic/nri-kubernetes/v2 v2.8.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.7.1
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.7.0
k8s.io/api v0.21.1
k8s.io/apimachinery v0.21.1
k8s.io/client-go v0.21.1
k8s.io/api v0.22.0
k8s.io/apimachinery v0.22.0
k8s.io/client-go v0.22.0
)

replace github.com/pkg/sftp => github.com/pkg/sftp v1.13.2
275 changes: 217 additions & 58 deletions go.sum

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions internal/config/config.go
Expand Up @@ -8,23 +8,29 @@ import (
)

const (
// Host is a Kubelet host flag name.
Host = "host"

// DefaultHost is default address where discovery will look for Kubelet API.
DefaultHost = "localhost"

// DefaultPort is default port user for Kubelet API.
DefaultPort = 10255

namespaces = "namespaces"
port = "port"
Host = "host"
insecure = "insecure"
timeout = "timeout"
tls = "tls"
envPrefix = "NRIA"

DefaultHost = "localhost"
DefaultPort = 10255
)

var (
_ = flag.String(namespaces, "", "(optional, default '') Comma separated list of namespaces to discover pods on")
_ = flag.Bool(insecure, false, `(optional, default false, deprecated) Use insecure (non-ssl) connection.
For backwards compatibility this flag takes precedence over 'tls')`)
)

var (
_ = flag.Int(timeout, 5000, "(optional, default 5000) timeout in ms")
_ = flag.Bool(tls, false, "(optional, default false) Use secure (tls) connection")
Expand Down Expand Up @@ -64,6 +70,7 @@ func (c *Config) IsAutoConfig() bool {
return !IsFlagPassed(Host) && !IsFlagPassed(port) && !IsFlagPassed(tls)
}

// NewConfig generates Config from flags.
func NewConfig(version string) Config {
flag.Parse()

Expand Down
1 change: 1 addition & 0 deletions internal/discovery/consts.go
@@ -1,5 +1,6 @@
package discovery

// Property represents a discovery field.
type Property = string

const (
Expand Down
4 changes: 3 additions & 1 deletion internal/discovery/discoverer.go
Expand Up @@ -15,7 +15,9 @@ type Replacement struct {
}

type (
VariablesMap map[string]interface{}
// VariablesMap is used to store discovery properties.
VariablesMap map[string]interface{}
// AnnotationsMap is used to discovered annotations.
AnnotationsMap = VariablesMap
)

Expand Down
10 changes: 5 additions & 5 deletions internal/discovery/discoverer_test.go
Expand Up @@ -184,20 +184,20 @@ func fakeKubelet() kubernetes.Kubelet {
Items: []corev1.Pod{pod1, pod2},
}

client := fakeHttpClient(podList)
client := fakeHTTPClient(podList)
k, _ := kubernetes.NewKubeletWithClient(client)
return k
}

func fakeHttpClient(pods corev1.PodList) http.HttpClient {
return &FakeHttpClient{pods: pods}
func fakeHTTPClient(pods corev1.PodList) http.Client {
return &FakeHTTPClient{pods: pods}
}

type FakeHttpClient struct {
type FakeHTTPClient struct {
pods corev1.PodList
}

func (k *FakeHttpClient) Get(path string) ([]byte, error) {
func (k *FakeHTTPClient) Get(path string) ([]byte, error) {
return json.Marshal(k.pods)
}

Expand Down
22 changes: 17 additions & 5 deletions internal/http/client.go
Expand Up @@ -13,7 +13,8 @@ import (
"github.com/sirupsen/logrus"
)

type HttpClient interface {
// Client represents functionality of simple HTTP client.
type Client interface {
Get(path string) ([]byte, error)
}

Expand All @@ -30,7 +31,12 @@ func (c *httpClient) Get(path string) ([]byte, error) {
return nil, err
}

defer resp.Body.Close()
defer func() {
if err := resp.Body.Close(); err != nil {
logrus.WithError(err).Warn("closing response body")
}
}()

buff, _ := ioutil.ReadAll(resp.Body)

if resp.StatusCode != http.StatusOK {
Expand All @@ -40,7 +46,8 @@ func (c *httpClient) Get(path string) ([]byte, error) {
return buff, nil
}

func NewClient(url url.URL, tr http.RoundTripper) HttpClient {
// NewClient constructs new simple HTTP client with given base URL.
func NewClient(url url.URL, tr http.RoundTripper) Client {
return &httpClient{
http: http.Client{
Transport: tr,
Expand All @@ -55,7 +62,7 @@ type kubeletClient struct {
}

// NewKubeletClient creates a new kubeletClient instance.
func NewKubeletClient(nodeName string, timeout time.Duration) (HttpClient, error) {
func NewKubeletClient(nodeName string, timeout time.Duration) (Client, error) {
logger := logrus.New()
logger.SetOutput(os.Stderr)

Expand All @@ -80,7 +87,12 @@ func (kc *kubeletClient) Get(path string) ([]byte, error) {
return nil, err
}

defer resp.Body.Close()
defer func() {
if err := resp.Body.Close(); err != nil {
logrus.WithError(err).Warn("closing response body")
}
}()

buff, _ := ioutil.ReadAll(resp.Body)

if resp.StatusCode != http.StatusOK {
Expand Down
25 changes: 16 additions & 9 deletions internal/kubernetes/kubelet.go
Expand Up @@ -25,11 +25,15 @@ const (
)

type (
PortsMap map[string]int32
LabelsMap map[string]string
// PortsMap stores container ports indexed by name.
PortsMap map[string]int32
// LabelsMap stores Pod labels.
LabelsMap map[string]string
// AnnotationsMap stores Pod annotations.
AnnotationsMap map[string]string
)

// ContainerInfo represents discovery-specific format for found Pods via Kubelet API.
type ContainerInfo struct {
Name string
ID string
Expand All @@ -46,12 +50,13 @@ type ContainerInfo struct {
Cluster string
}

// Kubelet defines what functionality kubelet client provides.
type Kubelet interface {
FindContainers(namespaces []string) ([]ContainerInfo, error)
}

type kubelet struct {
client http.HttpClient
client http.Client
NodeName string
ClusterName string
}
Expand Down Expand Up @@ -153,6 +158,7 @@ func getClusterName() string {
return clusterName
}

// NewKubelet validates and constructs Kubelet client.
func NewKubelet(host string, port int, useTLS bool, autoConfig bool, timeout time.Duration) (Kubelet, error) {
restConfig, err := rest.InClusterConfig()
// not inside the cluster?
Expand Down Expand Up @@ -187,7 +193,7 @@ func NewKubelet(host string, port int, useTLS bool, autoConfig bool, timeout tim
kubeletHost = nodeName
}

hostUrl := makeUrl(kubeletHost, port, useTLS)
hostURL := makeURL(kubeletHost, port, useTLS)

// Allow kubelet to use self-signed serving certificate.
restConfig.Insecure = true
Expand All @@ -203,7 +209,7 @@ func NewKubelet(host string, port int, useTLS bool, autoConfig bool, timeout tim
return nil, fmt.Errorf("creating HTTP transport config from kubeconfig: %w", err)
}

httpClient := http.NewClient(hostUrl, tr)
httpClient := http.NewClient(hostURL, tr)

kubelet := &kubelet{
client: httpClient,
Expand All @@ -214,22 +220,23 @@ func NewKubelet(host string, port int, useTLS bool, autoConfig bool, timeout tim
return kubelet, nil
}

func NewKubeletWithClient(httpClient http.HttpClient) (Kubelet, error) {
// NewKubeletWithClient constructs Kubelet client with given HTTP client.
func NewKubeletWithClient(httpClient http.Client) (Kubelet, error) {
k := &kubelet{
client: httpClient,
}

return k, nil
}

func makeUrl(host string, port int, useTLS bool) url.URL {
func makeURL(host string, port int, useTLS bool) url.URL {
scheme := "http"
if useTLS {
scheme = "https"
}
kubeletUrl := url.URL{
kubeletURL := url.URL{
Scheme: scheme,
Host: host + ":" + strconv.Itoa(port),
}
return kubeletUrl
return kubeletURL
}
10 changes: 2 additions & 8 deletions internal/utils/utils.go
Expand Up @@ -4,6 +4,7 @@ import (
"os"
)

// Contains checks if given value is included in given slice.
func Contains(set []string, str string) bool {
// a map may be faster
for _, s := range set {
Expand All @@ -14,17 +15,10 @@ func Contains(set []string, str string) bool {
return false
}

// HomeDir returns platform-specific path to user's home directory.
func HomeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h
}
return os.Getenv("USERPROFILE") // windows
}

func Hostname() string {
hostname, err := os.Hostname()
if err != nil {
return ""
}
return hostname
}

0 comments on commit acfc9ae

Please sign in to comment.