Skip to content

Commit

Permalink
Separate properties.go into separate files (#3777)
Browse files Browse the repository at this point in the history
  • Loading branch information
0sewa0 authored Sep 12, 2024
1 parent 7e5c18e commit 70613e3
Show file tree
Hide file tree
Showing 10 changed files with 831 additions and 819 deletions.
121 changes: 121 additions & 0 deletions pkg/api/v1beta3/dynakube/activegate_props.go
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
}
63 changes: 63 additions & 0 deletions pkg/api/v1beta3/dynakube/activegate_props_test.go
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())
})
}
129 changes: 129 additions & 0 deletions pkg/api/v1beta3/dynakube/dynakube_props.go
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())
}
Loading

0 comments on commit 70613e3

Please sign in to comment.