-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate properties.go into separate files (#3777)
- Loading branch information
Showing
10 changed files
with
831 additions
and
819 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package dynakube | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/Dynatrace/dynatrace-operator/pkg/api" | ||
"github.com/Dynatrace/dynatrace-operator/pkg/util/dtversion" | ||
) | ||
|
||
const ( | ||
ActiveGateTenantSecretSuffix = "-activegate-tenant-secret" | ||
ActiveGateConnectionInfoConfigMapSuffix = "-activegate-connection-info" | ||
AuthTokenSecretSuffix = "-activegate-authtoken-secret" | ||
DefaultActiveGateImageRegistrySubPath = "/linux/activegate" | ||
) | ||
|
||
// NeedsActiveGate returns true when a feature requires ActiveGate instances. | ||
func (dk *DynaKube) NeedsActiveGate() bool { | ||
return dk.ActiveGateMode() | ||
} | ||
|
||
func (dk *DynaKube) ActiveGateMode() bool { | ||
return len(dk.Spec.ActiveGate.Capabilities) > 0 || dk.IsExtensionsEnabled() | ||
} | ||
|
||
func (dk *DynaKube) IsActiveGateMode(mode CapabilityDisplayName) bool { | ||
for _, capability := range dk.Spec.ActiveGate.Capabilities { | ||
if capability == mode { | ||
return true | ||
} | ||
} | ||
|
||
return false | ||
} | ||
|
||
func (dk *DynaKube) ActiveGateServiceAccountOwner() string { | ||
if dk.IsKubernetesMonitoringActiveGateEnabled() { | ||
return string(KubeMonCapability.DeepCopy().DisplayName) | ||
} else { | ||
return "activegate" | ||
} | ||
} | ||
|
||
func (dk *DynaKube) ActiveGateServiceAccountName() string { | ||
return "dynatrace-" + dk.ActiveGateServiceAccountOwner() | ||
} | ||
|
||
func (dk *DynaKube) IsKubernetesMonitoringActiveGateEnabled() bool { | ||
return dk.IsActiveGateMode(KubeMonCapability.DisplayName) | ||
} | ||
|
||
func (dk *DynaKube) IsRoutingActiveGateEnabled() bool { | ||
return dk.IsActiveGateMode(RoutingCapability.DisplayName) | ||
} | ||
|
||
func (dk *DynaKube) IsApiActiveGateEnabled() bool { | ||
return dk.IsActiveGateMode(DynatraceApiCapability.DisplayName) | ||
} | ||
|
||
func (dk *DynaKube) IsMetricsIngestActiveGateEnabled() bool { | ||
return dk.IsActiveGateMode(MetricsIngestCapability.DisplayName) | ||
} | ||
|
||
func (dk *DynaKube) NeedsActiveGateService() bool { | ||
return dk.IsRoutingActiveGateEnabled() || | ||
dk.IsApiActiveGateEnabled() || | ||
dk.IsMetricsIngestActiveGateEnabled() || | ||
dk.IsExtensionsEnabled() | ||
} | ||
|
||
func (dk *DynaKube) HasActiveGateCaCert() bool { | ||
return dk.ActiveGateMode() && dk.Spec.ActiveGate.TlsSecretName != "" | ||
} | ||
|
||
// ActivegateTenantSecret returns the name of the secret containing tenant UUID, token and communication endpoints for ActiveGate. | ||
func (dk *DynaKube) ActivegateTenantSecret() string { | ||
return dk.Name + ActiveGateTenantSecretSuffix | ||
} | ||
|
||
// ActiveGateAuthTokenSecret returns the name of the secret containing the ActiveGateAuthToken, which is mounted to the AGs. | ||
func (dk *DynaKube) ActiveGateAuthTokenSecret() string { | ||
return dk.Name + AuthTokenSecretSuffix | ||
} | ||
|
||
func (dk *DynaKube) ActiveGateConnectionInfoConfigMapName() string { | ||
return dk.Name + ActiveGateConnectionInfoConfigMapSuffix | ||
} | ||
|
||
// ActiveGateImage provides the image reference set in Status for the ActiveGate. | ||
// Format: repo@sha256:digest. | ||
func (dk *DynaKube) ActiveGateImage() string { | ||
return dk.Status.ActiveGate.ImageID | ||
} | ||
|
||
// ActiveGateVersion provides version set in Status for the ActiveGate. | ||
func (dk *DynaKube) ActiveGateVersion() string { | ||
return dk.Status.ActiveGate.Version | ||
} | ||
|
||
// DefaultActiveGateImage provides the image reference for the ActiveGate from tenant registry. | ||
// Format: repo:tag. | ||
func (dk *DynaKube) DefaultActiveGateImage(version string) string { | ||
apiUrlHost := dk.ApiUrlHost() | ||
if apiUrlHost == "" { | ||
return "" | ||
} | ||
|
||
truncatedVersion := dtversion.ToImageTag(version) | ||
tag := truncatedVersion | ||
|
||
if !strings.Contains(tag, api.RawTag) { | ||
tag += "-" + api.RawTag | ||
} | ||
|
||
return apiUrlHost + DefaultActiveGateImageRegistrySubPath + ":" + tag | ||
} | ||
|
||
// CustomActiveGateImage provides the image reference for the ActiveGate provided in the Spec. | ||
func (dk *DynaKube) CustomActiveGateImage() string { | ||
return dk.Spec.ActiveGate.Image | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
Copyright 2021 Dynatrace LLC. | ||
Licensed 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 dynakube | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestDefaultActiveGateImage(t *testing.T) { | ||
t.Run(`ActiveGateImage with no API URL`, func(t *testing.T) { | ||
dk := DynaKube{} | ||
assert.Equal(t, "", dk.DefaultActiveGateImage("")) | ||
}) | ||
|
||
t.Run(`ActiveGateImage adds raw postfix`, func(t *testing.T) { | ||
dk := DynaKube{Spec: DynaKubeSpec{APIURL: testAPIURL}} | ||
assert.Equal(t, "test-endpoint/linux/activegate:1.234.5-raw", dk.DefaultActiveGateImage("1.234.5")) | ||
}) | ||
|
||
t.Run("ActiveGateImage doesn't add 'raw' postfix if present", func(t *testing.T) { | ||
dk := DynaKube{Spec: DynaKubeSpec{APIURL: testAPIURL}} | ||
assert.Equal(t, "test-endpoint/linux/activegate:1.234.5-raw", dk.DefaultActiveGateImage("1.234.5-raw")) | ||
}) | ||
|
||
t.Run(`ActiveGateImage truncates build date`, func(t *testing.T) { | ||
version := "1.239.14.20220325-164521" | ||
expectedImage := "test-endpoint/linux/activegate:1.239.14-raw" | ||
dk := DynaKube{Spec: DynaKubeSpec{APIURL: testAPIURL}} | ||
|
||
assert.Equal(t, expectedImage, dk.DefaultActiveGateImage(version)) | ||
}) | ||
} | ||
|
||
func TestCustomActiveGateImage(t *testing.T) { | ||
t.Run(`ActiveGateImage with custom image`, func(t *testing.T) { | ||
customImg := "registry/my/activegate:latest" | ||
dk := DynaKube{Spec: DynaKubeSpec{ActiveGate: ActiveGateSpec{CapabilityProperties: CapabilityProperties{ | ||
Image: customImg, | ||
}}}} | ||
assert.Equal(t, customImg, dk.CustomActiveGateImage()) | ||
}) | ||
|
||
t.Run(`ActiveGateImage with no custom image`, func(t *testing.T) { | ||
dk := DynaKube{Spec: DynaKubeSpec{ActiveGate: ActiveGateSpec{CapabilityProperties: CapabilityProperties{}}}} | ||
assert.Equal(t, "", dk.CustomActiveGateImage()) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package dynakube | ||
|
||
import ( | ||
"net/url" | ||
"strings" | ||
"time" | ||
|
||
"github.com/Dynatrace/dynatrace-operator/pkg/util/timeprovider" | ||
"github.com/pkg/errors" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
const ( | ||
// PullSecretSuffix is the suffix appended to the DynaKube name to n. | ||
PullSecretSuffix = "-pull-secret" | ||
) | ||
|
||
// ApiUrl is a getter for dk.Spec.APIURL. | ||
func (dk *DynaKube) ApiUrl() string { | ||
return dk.Spec.APIURL | ||
} | ||
|
||
func (dk *DynaKube) Conditions() *[]metav1.Condition { return &dk.Status.Conditions } | ||
|
||
// ApiUrlHost returns the host of dk.Spec.APIURL | ||
// E.g. if the APIURL is set to "https://my-tenant.dynatrace.com/api", it returns "my-tenant.dynatrace.com" | ||
// If the URL cannot be parsed, it returns an empty string. | ||
func (dk *DynaKube) ApiUrlHost() string { | ||
parsedUrl, err := url.Parse(dk.ApiUrl()) | ||
if err != nil { | ||
return "" | ||
} | ||
|
||
return parsedUrl.Host | ||
} | ||
|
||
// PullSecretName returns the name of the pull secret to be used for immutable images. | ||
func (dk *DynaKube) PullSecretName() string { | ||
if dk.Spec.CustomPullSecret != "" { | ||
return dk.Spec.CustomPullSecret | ||
} | ||
|
||
return dk.Name + PullSecretSuffix | ||
} | ||
|
||
// PullSecretsNames returns the names of the pull secrets to be used for immutable images. | ||
func (dk *DynaKube) PullSecretNames() []string { | ||
names := []string{ | ||
dk.Name + PullSecretSuffix, | ||
} | ||
if dk.Spec.CustomPullSecret != "" { | ||
names = append(names, dk.Spec.CustomPullSecret) | ||
} | ||
|
||
return names | ||
} | ||
|
||
func (dk *DynaKube) ImagePullSecretReferences() []corev1.LocalObjectReference { | ||
imagePullSecrets := make([]corev1.LocalObjectReference, 0) | ||
for _, pullSecretName := range dk.PullSecretNames() { | ||
imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{ | ||
Name: pullSecretName, | ||
}) | ||
} | ||
|
||
return imagePullSecrets | ||
} | ||
|
||
// Tokens returns the name of the Secret to be used for tokens. | ||
func (dk *DynaKube) Tokens() string { | ||
if tkns := dk.Spec.Tokens; tkns != "" { | ||
return tkns | ||
} | ||
|
||
return dk.Name | ||
} | ||
|
||
func (dk *DynaKube) TenantUUIDFromApiUrl() (string, error) { | ||
return tenantUUID(dk.ApiUrl()) | ||
} | ||
|
||
func runeIs(wanted rune) func(rune) bool { | ||
return func(actual rune) bool { | ||
return actual == wanted | ||
} | ||
} | ||
|
||
func tenantUUID(apiUrl string) (string, error) { | ||
parsedUrl, err := url.Parse(apiUrl) | ||
if err != nil { | ||
return "", errors.WithMessagef(err, "problem parsing tenant id from url %s", apiUrl) | ||
} | ||
|
||
// Path = "/e/<token>/api" -> ["e", "<tenant>", "api"] | ||
subPaths := strings.FieldsFunc(parsedUrl.Path, runeIs('/')) | ||
if len(subPaths) >= 3 && subPaths[0] == "e" && subPaths[2] == "api" { | ||
return subPaths[1], nil | ||
} | ||
|
||
hostnameWithDomains := strings.FieldsFunc(parsedUrl.Hostname(), runeIs('.')) | ||
if len(hostnameWithDomains) >= 1 { | ||
return hostnameWithDomains[0], nil | ||
} | ||
|
||
return "", errors.Errorf("problem getting tenant id from API URL '%s'", apiUrl) | ||
} | ||
|
||
func (dk *DynaKube) TenantUUIDFromConnectionInfoStatus() (string, error) { | ||
if dk.Status.OneAgent.ConnectionInfoStatus.TenantUUID != "" { | ||
return dk.Status.OneAgent.ConnectionInfoStatus.TenantUUID, nil | ||
} else if dk.Status.ActiveGate.ConnectionInfoStatus.TenantUUID != "" { | ||
return dk.Status.ActiveGate.ConnectionInfoStatus.TenantUUID, nil | ||
} | ||
|
||
return "", errors.New("tenant UUID not available") | ||
} | ||
|
||
func (dk *DynaKube) ApiRequestThreshold() time.Duration { | ||
if dk.Spec.DynatraceApiRequestThreshold < 0 { | ||
dk.Spec.DynatraceApiRequestThreshold = DefaultMinRequestThresholdMinutes | ||
} | ||
|
||
return time.Duration(dk.Spec.DynatraceApiRequestThreshold) * time.Minute | ||
} | ||
|
||
func (dk *DynaKube) IsTokenScopeVerificationAllowed(timeProvider *timeprovider.Provider) bool { | ||
return timeProvider.IsOutdated(&dk.Status.DynatraceApi.LastTokenScopeRequest, dk.ApiRequestThreshold()) | ||
} |
Oops, something went wrong.