This repository has been archived by the owner on Dec 11, 2023. It is now read-only.
/
client.go
173 lines (149 loc) · 5.06 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package dtclient
import (
"crypto/tls"
"crypto/x509"
"errors"
"net/http"
"net/url"
"strings"
"sigs.k8s.io/controller-runtime/pkg/log"
)
// Client is the interface for the Dynatrace REST API client.
type Client interface {
// GetLatestAgentVersion gets the latest agent version for the given OS and installer type.
// Returns the version as received from the server on success.
//
// Returns an error for the following conditions:
// - os or installerType is empty
// - IO error or unexpected response
// - error response from the server (e.g. authentication failure)
// - the agent version is not set or empty
GetLatestAgentVersion(os, installerType string) (string, error)
// GetAgentVersionForIP returns the agent version running on the host with the given IP address.
// Returns the version string formatted as "Major.Minor.Revision.Timestamp" on success.
//
// Returns an error for the following conditions:
// - the IP is empty
// - IO error or unexpected response
// - error response from the server (e.g. authentication failure)
// - a host with the given IP cannot be found
// - the agent version for the host is not set
//
// The list of all hosts with their IP addresses is cached the first time this method is called. Use a new
// client instance to fetch a new list from the server.
GetAgentVersionForIP(ip string) (string, error)
// GetCommunicationHosts returns, on success, the list of communication hosts used for available
// communication endpoints that the Dynatrace OneAgent can use to connect to.
//
// Returns an error if there was also an error response from the server.
GetConnectionInfo() (ConnectionInfo, error)
// GetCommunicationHostForClient returns a CommunicationHost for the client's API URL. Or error, if failed to be parsed.
GetCommunicationHostForClient() (CommunicationHost, error)
// SendEvent posts events to dynatrace API
SendEvent(eventData *EventData) error
// GetEntityIDForIP returns the entity id for a given IP address.
//
// Returns an error in case the lookup failed.
GetEntityIDForIP(ip string) (string, error)
// GetTokenScopes returns the list of scopes assigned to a token if successful.
GetTokenScopes(token string) (TokenScopes, error)
// GetClusterInfo returns the following information about the cluster:
// * Version
GetClusterInfo() (*ClusterInfo, error)
}
// Known OS values.
const (
OsWindows = "windows"
OsUnix = "unix"
OsAix = "aix"
OsSolaris = "solaris"
)
// Known installer types.
const (
InstallerTypeDefault = "default"
InstallerTypeUnattended = "default-unattended"
InstallerTypePaasZip = "paas"
InstallerTypePaasSh = "paas-sh"
)
// Known token scopes
const (
TokenScopeInstallerDownload = "InstallerDownload"
TokenScopeDataExport = "DataExport"
)
// NewClient creates a REST client for the given API base URL and authentication tokens.
// Returns an error if a token or the URL is empty.
//
// The API base URL is different for managed and SaaS environments:
// - SaaS: https://{environment-id}.live.dynatrace.com/api
// - Managed: https://{domain}/e/{environment-id}/api
//
// opts can be used to customize the created client, entries must not be nil.
func NewClient(url, apiToken, paasToken string, opts ...Option) (Client, error) {
if len(url) == 0 {
return nil, errors.New("url is empty")
}
if len(apiToken) == 0 && len(paasToken) == 0 {
return nil, errors.New("tokens are empty")
}
if strings.HasSuffix(url, "/") {
url = url[:len(url)-1]
}
dc := &dynatraceClient{
url: url,
apiToken: apiToken,
paasToken: paasToken,
logger: log.Log.WithName("dynatrace.client"),
hostCache: make(map[string]hostInfo),
httpClient: &http.Client{
Transport: http.DefaultTransport.(*http.Transport).Clone(),
},
}
for _, opt := range opts {
opt(dc)
}
return dc, nil
}
// Option can be passed to NewClient and customizes the created client instance.
type Option func(*dynatraceClient)
// SkipCertificateValidation creates an Option that specifies whether validation of the server's TLS
// certificate should be skipped. The default is false.
func SkipCertificateValidation(skip bool) Option {
return func(c *dynatraceClient) {
if skip {
t := c.httpClient.Transport.(*http.Transport)
if t.TLSClientConfig == nil {
t.TLSClientConfig = &tls.Config{}
}
t.TLSClientConfig.InsecureSkipVerify = true
}
}
}
func Proxy(proxyURL string) Option {
return func(c *dynatraceClient) {
p, err := url.Parse(proxyURL)
if err != nil {
c.logger.Info("Could not parse proxy URL!")
return
}
t := c.httpClient.Transport.(*http.Transport)
t.Proxy = http.ProxyURL(p)
}
}
func Certs(certs []byte) Option {
return func(c *dynatraceClient) {
rootCAs := x509.NewCertPool()
if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
c.logger.Info("Failed to append custom certs!")
}
t := c.httpClient.Transport.(*http.Transport)
if t.TLSClientConfig == nil {
t.TLSClientConfig = &tls.Config{}
}
t.TLSClientConfig.RootCAs = rootCAs
}
}
func NetworkZone(networkZone string) Option {
return func(c *dynatraceClient) {
c.networkZone = networkZone
}
}