Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Release 0.4.1 (#138)
Browse files Browse the repository at this point in the history
* Create appropiate Istio objects for HTTP and IP communication endpoints (#134)

* Create appropiate Istio objects for HTTP and IP communication endpoints

* Add tests for ServiceEntry and VirtualService objects generation

* use istio clientset instead of byte array to create vs and se objects

* edit and fix istio unit tests to use client set instead of byte array

* edit and fix istio unit tests in helper.go

* Code cleanup and formatting

* Handle scenario when Istio is installed after the Operator is started (#137)

* Don't update CR when no OneAgent pods are currently running

* Log appropiate message in case Istio was installed after the Operator current instance started

* add a section for known limitations

* fix font size for known limitation section

* check for gvk before looping over comm hosts

* change for configuration with/without name is queried via client

* edit documentation for known limitaiton

* Add CSV manifests for v0.4.1 (#135)

* Add CSV manifests for v0.4.0

* change csv to reflect version 0.4.1

* change package.yaml to reflect version 0.4.1

* change createdAt timestamp for olm csv

* update version, readme and manifests

* resolve version.go

* format import order

* fix deployment url in openshift instructions
  • Loading branch information
namratachaudhary authored Sep 18, 2019
1 parent 6ac3f27 commit d1bd15b
Show file tree
Hide file tree
Showing 13 changed files with 920 additions and 141 deletions.
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Depending of the version of the Dynatrace OneAgent Operator, it supports the fol
| Dynatrace OneAgent Operator version | Kubernetes | OpenShift Container Platform |
| ----------------------------------- | ---------- | ---------------------------- |
| master | 1.11+ | 3.11+ |
| v0.4.0 | 1.11+ | 3.11+ |
| v0.4.1 | 1.11+ | 3.11+ |
| v0.3.1 | 1.11-1.15 | 3.11+ |
| v0.2.1 | 1.9-1.15 | 3.9+ |

Expand All @@ -44,14 +44,14 @@ Create neccessary objects and observe its logs:
#### Kubernetes
```sh
$ kubectl create namespace dynatrace
$ kubectl apply -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.0/deploy/kubernetes.yaml
$ kubectl apply -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.1/deploy/kubernetes.yaml
$ kubectl -n dynatrace logs -f deployment/dynatrace-oneagent-operator
```

#### OpenShift
```sh
$ oc adm new-project --node-selector="" dynatrace
$ oc apply -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.0/deploy/openshift.yaml
$ oc apply -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.1/deploy/openshift.yaml
$ oc -n dynatrace logs -f deployment/dynatrace-oneagent-operator
```

Expand Down Expand Up @@ -110,7 +110,7 @@ spec:
# VirtualService and ServiceEntries objects to allow access to the Dynatrace cluster from the agent.
#enableIstio: false
```
Save the snippet to a file or use [./deploy/cr.yaml](https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.0/deploy/cr.yaml) from this repository and adjust its values accordingly.
Save the snippet to a file or use [./deploy/cr.yaml](https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.1/deploy/cr.yaml) from this repository and adjust its values accordingly.
A secret holding tokens for authenticating to the Dynatrace cluster needs to be created upfront.
Create access tokens of type *Dynatrace API* and *Platform as a Service* and use its values in the following commands respectively.
For assistance please refere to [Create user-generated access tokens](https://www.dynatrace.com/support/help/get-started/introduction/why-do-i-need-an-access-token-and-an-environment-id/#create-user-generated-access-tokens).
Expand Down Expand Up @@ -146,15 +146,18 @@ Remove OneAgent custom resources and clean-up all remaining OneAgent Operator sp
#### Kubernetes
```sh
$ kubectl delete -n dynatrace oneagent --all
$ kubectl delete -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.0/deploy/kubernetes.yaml
$ kubectl delete -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.1/deploy/kubernetes.yaml
```

#### OpenShift
```sh
$ oc delete -n dynatrace oneagent --all
$ oc delete -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.0/deploy/openshift.yaml
$ oc delete -f https://raw.githubusercontent.com/Dynatrace/dynatrace-oneagent-operator/v0.4.1/deploy/openshift.yaml
```

## Known Limitation
The `enableIstio` feature requires to restart the operator if Istio was deployed after deployment of the operator in case istio is installed after deploying the operator.
Background: This happens because the cache maintained by controller-runtime's Kubernetes Client is not dynamic. The bug for same is reported here https://github.com/kubernetes-sigs/controller-runtime/issues/321 and the fix for same is currently a work in progress https://github.com/kubernetes-sigs/controller-runtime/pull/554 .

## Hacking

Expand Down
2 changes: 1 addition & 1 deletion deploy/kubernetes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ spec:
spec:
containers:
- name: dynatrace-oneagent-operator
image: quay.io/dynatrace/dynatrace-oneagent-operator:v0.4.0
image: quay.io/dynatrace/dynatrace-oneagent-operator:v0.4.1
command:
- dynatrace-oneagent-operator
imagePullPolicy: Always
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion deploy/olm/kubernetes/dynatrace.package.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
packageName: oneagent
channels:
- name: alpha
currentCSV: dynatrace-monitoring.v0.3.1
currentCSV: dynatrace-monitoring.v0.4.1

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions deploy/olm/openshift/dynatrace.package.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
packageName: oneagent
packageName: oneagent-certified
channels:
- name: alpha
currentCSV: dynatrace-monitoring.v0.3.1
currentCSV: dynatrace-monitoring.v0.4.1
2 changes: 1 addition & 1 deletion deploy/openshift.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ spec:
spec:
containers:
- name: dynatrace-oneagent-operator
image: registry.connect.redhat.com/dynatrace/dynatrace-oneagent-operator:v0.4.0
image: registry.connect.redhat.com/dynatrace/dynatrace-oneagent-operator:v0.4.1
command:
- dynatrace-oneagent-operator
imagePullPolicy: Always
Expand Down
191 changes: 107 additions & 84 deletions pkg/controller/istio/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package istio
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"net"
"os"
"strconv"
"strings"

istiov1alpha3 "github.com/Dynatrace/dynatrace-oneagent-operator/pkg/apis/networking/istio/v1alpha3"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
istio "istio.io/api/networking/v1alpha3"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -51,107 +56,125 @@ func CheckIstioEnabled(cfg *rest.Config) (bool, error) {
}

// BuildServiceEntry returns an Istio ServiceEntry object for the given communication endpoint.
func BuildServiceEntry(name string, host string, port uint32, protocol string) []byte {
portStr := strconv.Itoa(int(port))
protocolStr := strings.ToUpper(protocol)
func BuildServiceEntry(name, host, protocol string, port uint32) *istiov1alpha3.ServiceEntry {
if net.ParseIP(host) != nil { // It's an IP.
return buildServiceEntryIP(name, host, port)
}

return []byte(`{
"apiVersion": "networking.istio.io/v1alpha3",
"kind": "ServiceEntry",
"metadata": {
"name": "` + name + `",
"namespace": "` + os.Getenv(k8sutil.WatchNamespaceEnvVar) + `"
},
"spec": {
"hosts": [ "` + host + `" ],
"location": "MESH_EXTERNAL",
"ports": [{
"name": "` + protocol + portStr + `",
"number": ` + portStr + `,
"protocol": "` + protocolStr + `"
}],
"resolution": "DNS"
}
}`)
return buildServiceEntryFQDN(name, host, protocol, port)
}

// BuildVirtualService returns an Istio VirtualService object for the given communication endpoint.
func BuildVirtualService(name string, host string, port uint32, protocol string) []byte {
switch protocol {
case "https":
return buildVirtualServiceHTTPS(name, host, port)
case "http":
return buildVirtualServiceHTTP(name, host, port)
func BuildVirtualService(name, host, protocol string, port uint32) *istiov1alpha3.VirtualService {
if net.ParseIP(host) != nil { // It's an IP.
return nil
}

return []byte(`{}`)
return &istiov1alpha3.VirtualService{
ObjectMeta: buildObjectMeta(name),
Spec: buildVirtualServiceSpec(host, protocol, port),
}
}

func buildVirtualServiceHTTPS(name string, host string, port uint32) []byte {
// buildServiceEntryFQDN returns an Istio ServiceEntry object for the given communication endpoint with a FQDN host.
func buildServiceEntryFQDN(name, host, protocol string, port uint32) *istiov1alpha3.ServiceEntry {
portStr := strconv.Itoa(int(port))
protocolStr := strings.ToUpper(protocol)

return []byte(`{
"apiVersion": "networking.istio.io/v1alpha3",
"kind": "VirtualService",
"metadata": {
"name": "` + name + `",
"namespace": "` + os.Getenv(k8sutil.WatchNamespaceEnvVar) + `"
},
"spec": {
"hosts": [ "` + host + `" ],
"tls": [{
"match": [{
"port": ` + portStr + `,
"sni_hosts": [ "` + host + `" ]
}],
"route": [{
"destination": {
"host": "` + host + `",
"port": { "number": ` + portStr + ` }
}
}]
}]
}
}`)
return &istiov1alpha3.ServiceEntry{
ObjectMeta: buildObjectMeta(name),
Spec: istiov1alpha3.ServiceEntrySpec{
ServiceEntry: istio.ServiceEntry{
Hosts: []string{host},
Ports: []*istio.Port{{
Name: protocol + "-" + portStr,
Number: port,
Protocol: protocolStr,
}},
Location: istio.ServiceEntry_MESH_EXTERNAL,
Resolution: istio.ServiceEntry_DNS,
},
},
}
}

func buildVirtualServiceHTTP(name string, host string, port uint32) []byte {
// buildServiceEntryIP returns an Istio ServiceEntry object for the given communication endpoint with IP.
func buildServiceEntryIP(name, host string, port uint32) *istiov1alpha3.ServiceEntry {
portStr := strconv.Itoa(int(port))

return []byte(`{
"apiVersion": "networking.istio.io/v1alpha3",
"kind": "VirtualService",
"metadata": {
"name": "` + name + `",
"namespace": "` + os.Getenv(k8sutil.WatchNamespaceEnvVar) + `"
},
"spec": {
"hosts": [ "` + host + `" ],
"http": [{
"match": [{
"port": ` + portStr + `,
"headers": [{ "Host": "` + host + `" }]
}],
"route": [{
"destination": {
"host": "` + host + `",
"port": { "number": ` + portStr + ` }
}
}]
}]
}
}`)
return &istiov1alpha3.ServiceEntry{
ObjectMeta: buildObjectMeta(name),
Spec: istiov1alpha3.ServiceEntrySpec{
ServiceEntry: istio.ServiceEntry{
Hosts: []string{"ignored.subdomain"},
Addresses: []string{host + "/32"},
Ports: []*istio.Port{{
Name: "TCP-" + portStr,
Number: port,
Protocol: "TCP",
}},
Location: istio.ServiceEntry_MESH_EXTERNAL,
Resolution: istio.ServiceEntry_NONE,
},
},
}
}

// BuildNameForEndpoint returns a name to be used as a base to identify Istio objects.
func BuildNameForEndpoint(name string, host string, port uint32) string {
portStr := strconv.Itoa(int(port))
src := make([]byte, len(name)+len(host)+len(portStr))
src = strconv.AppendQuote(src, name)
src = strconv.AppendQuote(src, host)
src = strconv.AppendQuote(src, portStr)
func BuildNameForEndpoint(name string, protocol string, host string, port uint32) string {
sum := sha256.Sum256([]byte(fmt.Sprintf("%s-%s-%s-%d", name, protocol, host, port)))
return hex.EncodeToString(sum[:])
}

sum := sha256.Sum256(src)
func buildVirtualServiceSpec(host, protocol string, port uint32) istiov1alpha3.VirtualServiceSpec {
virtualServiceSpec := istiov1alpha3.VirtualServiceSpec{}
virtualServiceSpec.Hosts = []string{host}
switch protocol {
case "https":
virtualServiceSpec.Tls = buildVirtualServiceTLSRoute(host, port)
case "http":
virtualServiceSpec.Http = buildVirtualServiceHttpRoute(port, host)
}

return hex.EncodeToString(sum[:])
return virtualServiceSpec
}

func buildVirtualServiceTLSRoute(host string, port uint32) []*istio.TLSRoute {
return []*istio.TLSRoute{{
Match: []*istio.TLSMatchAttributes{{
SniHosts: []string{host},
Port: port,
}},
Route: []*istio.RouteDestination{{
Destination: &istio.Destination{
Host: host,
Port: &istio.PortSelector{
Port: &istio.PortSelector_Number{Number: port},
},
},
}},
}}
}

func buildVirtualServiceHttpRoute(port uint32, host string) []*istio.HTTPRoute {
return []*istio.HTTPRoute{{
Match: []*istio.HTTPMatchRequest{{
Port: port,
}},
Route: []*istio.HTTPRouteDestination{{
Destination: &istio.Destination{
Host: host,
Port: &istio.PortSelector{
Port: &istio.PortSelector_Number{Number: port},
},
},
}},
}}
}

func buildObjectMeta(name string) v1.ObjectMeta {
return v1.ObjectMeta{
Name: name,
Namespace: os.Getenv(k8sutil.WatchNamespaceEnvVar),
}
}
Loading

0 comments on commit d1bd15b

Please sign in to comment.