Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ignoring updates to networking resources #210

Merged
merged 5 commits into from
Jun 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ Table of Contents
* [Use NodePort](#use-nodeport)
* [Network on OpenShift](#network-on-openshift)
* [Network on Kubernetes 1.14+](#network-on-kubernetes-114)
* [NGINX Ingress troubleshooting](#nginx-ingress-troubleshooting)
* [NGINX Ingress troubleshooting](#nginx-ingress-troubleshooting)
* [Ignoring external changes to Ingress/Route resources](#ignoring-external-changes-to-ingressroute-resources)
* [TLS/SSL](#tlsssl)
* [Annotations and Labels](#annotations-and-labels)
* [Persistence](#persistence)
* [Extra volumes](#extra-volumes)
* [Minikube](#minikube)
* [Extra volumes](#extra-volumes)
* [Minikube](#minikube)
* [Service Account](#service-account)
* [Control Random Admin Password Generation](#control-random-admin-password-generation)
* [Red Hat Certified Images](#red-hat-certified-images)
Expand Down Expand Up @@ -321,7 +322,7 @@ $ kubectl get deploy/ingress-nginx-controller -o yaml -n kube-system | grep "\--

Now you would need to edit the config map:

`$ kubectl edit configmaps nginx-load-balancer-conf -n kube-system `
`$ kubectl edit configmaps nginx-load-balancer-conf -n kube-system `

In the root of the opened yaml file add:

Expand All @@ -332,6 +333,26 @@ data:

**Note**: If you want to have no limit for the data packet you can specify the `proxy-body-size: 0m`

### Ignoring external changes to Ingress/Route resources

Route and Ingress resources are highly configurable, and often the need to change them arises. For example, further
configuration can be performed by webhooks, but these changes get undone by the Operator as soon as it detects them.

Starting at version 0.6.0 you may specify that the Operator should ignore external changes made to Ingress and Route
resources. This is controlled by the `spec.networking.ignoreUpdates` boolean field in the Nexus resource. It defaults to
`false`, meaning the Operator will change the Ingress/Route specification to match its state as defined by this
resource. Set to `true` in order to prevent the Operator from undoing external changes in the resources' configuration.

```yaml
apiVersion: apps.m88i.io/v1alpha1
kind: Nexus
metadata:
name: nexus3
spec:
networking:
ignoreUpdates: true
```

### TLS/SSL

For details about TLS configuration check out
Expand Down
6 changes: 6 additions & 0 deletions api/v1alpha1/nexus_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ type NexusPersistence struct {
// ExtraVolumes which should be mounted when deploying Nexus.
// Updating this may lead to temporary unavailability while the new deployment with new volumes rolls out.
// +optional
// +listType=atomic
ExtraVolumes []NexusVolume `json:"extraVolumes,omitempty"`
}

Expand Down Expand Up @@ -169,6 +170,11 @@ type NexusNetworking struct {
// TLS/SSL-related configuration
// +optional
TLS NexusNetworkingTLS `json:"tls,omitempty"`
// IgnoreUpdates controls whether the Operator monitors and undoes external changes to the Ingress/Route resources.
// Defaults to `false`, meaning the Operator will change the Ingress/Route specification to match its state as
// defined by this resource.
// Set to `true` in order to prevent the Operator from undoing external changes in the resources' configuration.
IgnoreUpdates bool `json:"ignoreUpdates,omitempty"`
}

// NexusProbe describes a health check to be performed against a container to determine whether it is
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions bundle/manifests/apps.m88i.io_nexus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ spec:
host:
description: Host where the Nexus service is exposed. This attribute is required if the service is exposed via Ingress.
type: string
ignoreUpdates:
description: IgnoreUpdates controls whether the Operator monitors and undoes external changes to the Ingress/Route resources. Defaults to `false`, meaning the Operator will change the Ingress/Route specification to match its state as defined by this resource. Set to `true` in order to prevent the Operator from undoing external changes in the resources' configuration.
type: boolean
labels:
additionalProperties:
type: string
Expand Down Expand Up @@ -1058,6 +1061,7 @@ spec:
- name
type: object
type: array
x-kubernetes-list-type: atomic
persistent:
description: Flag to indicate if this instance installation will be persistent or not. If set to true a PVC is created for it.
type: boolean
Expand Down
9 changes: 9 additions & 0 deletions config/crd/bases/apps.m88i.io_nexus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ spec:
description: Host where the Nexus service is exposed. This attribute
is required if the service is exposed via Ingress.
type: string
ignoreUpdates:
description: IgnoreUpdates controls whether the Operator monitors
and undoes external changes to the Ingress/Route resources. Defaults
to `false`, meaning the Operator will change the Ingress/Route
specification to match its state as defined by this resource.
Set to `true` in order to prevent the Operator from undoing external
changes in the resources' configuration.
type: boolean
labels:
additionalProperties:
type: string
Expand Down Expand Up @@ -1664,6 +1672,7 @@ spec:
- name
type: object
type: array
x-kubernetes-list-type: atomic
persistent:
description: Flag to indicate if this instance installation will
be persistent or not. If set to true a PVC is created for it.
Expand Down
40 changes: 26 additions & 14 deletions controllers/nexus/resource/networking/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,14 @@ const (
resUnavailableFormat = "%s are not available in this cluster" // resource type
)

var (
legacyIngressType = reflect.TypeOf(&networkingv1beta1.Ingress{})
ingressType = reflect.TypeOf(&networkingv1.Ingress{})
)

// Manager is responsible for creating networking resources, fetching deployed ones and comparing them
// Use with zero values will result in a panic. Use the NewManager function to get a properly initialized manager
type Manager struct {
nexus *v1alpha1.Nexus
client client.Client
log logger.Logger
managedObjectsRef map[string]resource.KubernetesResource
nexus *v1alpha1.Nexus
client client.Client
log logger.Logger
managedObjectsRef map[string]resource.KubernetesResource
shouldIgnoreUpdates bool

routeAvailable, ingressAvailable, legacyIngressAvailable bool
}
Expand Down Expand Up @@ -91,6 +87,8 @@ func NewManager(nexus *v1alpha1.Nexus, client client.Client) (*Manager, error) {
mgr.managedObjectsRef[kind.RouteKind] = &routev1.Route{}
}

mgr.shouldIgnoreUpdates = nexus.Spec.Networking.IgnoreUpdates

return mgr, nil
}

Expand Down Expand Up @@ -132,7 +130,7 @@ func (m *Manager) createRoute() *routev1.Route {
}

func (m *Manager) createIngress() resource.KubernetesResource {
// we're only here if either ingress is available, no need to check legacy is
// we're only here if either ingress is available, no need to check if legacy is
if !m.ingressAvailable {
builder := newLegacyIngressBuilder(m.nexus)
if len(m.nexus.Spec.Networking.TLS.SecretName) > 0 {
Expand All @@ -155,10 +153,15 @@ func (m *Manager) GetDeployedResources() ([]resource.KubernetesResource, error)
// GetCustomComparator returns the custom comp function used to compare a networking resource.
// Returns nil if there is none
func (m *Manager) GetCustomComparator(t reflect.Type) func(deployed resource.KubernetesResource, requested resource.KubernetesResource) bool {
if m.shouldIgnoreUpdates {
m.log.Debug("Nexus configured to ignore Networking updates, won't compare current state and desired state for Ingress/Route")
return framework.AlwaysTrueComparator()
}

switch t {
case legacyIngressType:
case reflect.TypeOf(&networkingv1beta1.Ingress{}):
return legacyIngressEqual
case ingressType:
case reflect.TypeOf(&networkingv1.Ingress{}):
return ingressEqual
default:
return nil
Expand All @@ -168,9 +171,18 @@ func (m *Manager) GetCustomComparator(t reflect.Type) func(deployed resource.Kub
// GetCustomComparators returns all custom comp functions in a map indexed by the resource type
// Returns nil if there are none
func (m *Manager) GetCustomComparators() map[reflect.Type]func(deployed resource.KubernetesResource, requested resource.KubernetesResource) bool {
if m.shouldIgnoreUpdates {
m.log.Debug("Nexus configured to ignore Networking updates, won't compare current state and desired state for Ingress/Route")
return map[reflect.Type]func(deployed resource.KubernetesResource, requested resource.KubernetesResource) bool{
reflect.TypeOf(networkingv1beta1.Ingress{}): framework.AlwaysTrueComparator(),
reflect.TypeOf(networkingv1.Ingress{}): framework.AlwaysTrueComparator(),
reflect.TypeOf(routev1.Route{}): framework.AlwaysTrueComparator(),
}
}

return map[reflect.Type]func(deployed resource.KubernetesResource, requested resource.KubernetesResource) bool{
legacyIngressType: legacyIngressEqual,
ingressType: ingressEqual,
reflect.TypeOf(networkingv1beta1.Ingress{}): legacyIngressEqual,
reflect.TypeOf(networkingv1.Ingress{}): ingressEqual,
}
}

Expand Down
26 changes: 22 additions & 4 deletions controllers/nexus/resource/networking/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,6 @@ func TestManager_GetDeployedResources(t *testing.T) {
}

func TestManager_GetCustomComparator(t *testing.T) {
// the nexus and the client should have no effect on the
// comparator functions offered by the manager
mgr := &Manager{}

// there is no custom comparator function for routes
Expand All @@ -286,16 +284,36 @@ func TestManager_GetCustomComparator(t *testing.T) {
assert.NotNil(t, ingressComp)
}

func TestManager_GetCustomComparator_shouldIgnoreUpdates(t *testing.T) {
// the custom comparator for all types when ignoring updates is the alwaysTrueComparator
mgr := &Manager{shouldIgnoreUpdates: true, log: logger.GetLogger("test")}

routeComp := mgr.GetCustomComparator(reflect.TypeOf(&routev1.Route{}))
assert.NotNil(t, routeComp)
// there is a custom comparator function for v1beta1 ingresses
legacyIngressComp := mgr.GetCustomComparator(reflect.TypeOf(&networkingv1beta1.Ingress{}))
assert.NotNil(t, legacyIngressComp)
// there is a custom comparator function for v1 ingresses
ingressComp := mgr.GetCustomComparator(reflect.TypeOf(&networkingv1.Ingress{}))
assert.NotNil(t, ingressComp)
}

func TestManager_GetCustomComparators(t *testing.T) {
// the nexus and the client should have no effect on the
// comparator functions offered by the manager
mgr := &Manager{}

// there are two custom comparators (v1 and v1beta1 ingresses)
comparators := mgr.GetCustomComparators()
assert.Len(t, comparators, 2)
}

func TestManager_GetCustomComparators_shouldIgnoreUpdates(t *testing.T) {
mgr := &Manager{shouldIgnoreUpdates: true, log: logger.GetLogger("test")}

// legacy ingress, ingress and route need alwaysTrueComparator when ignoring updates
comparators := mgr.GetCustomComparators()
assert.Len(t, comparators, 3)
}

func Test_legacyIngressEqual(t *testing.T) {
// base ingress which will be used in all comparisons
baseIngress := &networkingv1beta1.Ingress{
Expand Down
9 changes: 9 additions & 0 deletions nexus-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ spec:
description: Host where the Nexus service is exposed. This attribute
is required if the service is exposed via Ingress.
type: string
ignoreUpdates:
description: IgnoreUpdates controls whether the Operator monitors
and undoes external changes to the Ingress/Route resources. Defaults
to `false`, meaning the Operator will change the Ingress/Route
specification to match its state as defined by this resource.
Set to `true` in order to prevent the Operator from undoing external
changes in the resources' configuration.
type: boolean
labels:
additionalProperties:
type: string
Expand Down Expand Up @@ -1669,6 +1677,7 @@ spec:
- name
type: object
type: array
x-kubernetes-list-type: atomic
persistent:
description: Flag to indicate if this instance installation will
be persistent or not. If set to true a PVC is created for it.
Expand Down