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

Sync with internal repo #107

Merged
merged 5 commits into from
Nov 26, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ COPY . ./
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} GO111MODULE=on go build -mod vendor -a -o dist/onic ./main.go

# For Open source
FROM oraclelinux:7-slim
FROM oraclelinux:8-slim

LABEL author="OKE Foundations Team"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,18 @@ spec:
defaultMode: 420
secretName: oci-native-ingress-controller-tls
securityContext:
{}
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: oci-native-ingress-controller
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
image: "ghcr.io/oracle/oci-native-ingress-controller:v1.3.9"
imagePullPolicy: Always
args:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ rules:
- apiGroups: [""]
resources: [pods/status]
verbs: [patch]
- apiGroups: [""]
resources: [serviceaccounts]
verbs: [list, watch]
---
# Source: oci-native-ingress-controller/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
14 changes: 9 additions & 5 deletions helm/oci-native-ingress-controller/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,18 @@ serviceAccount:

podAnnotations: {}

podSecurityContext: {}
# fsGroup: 2000
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault

securityContext:
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
allowPrivilegeEscalation: false
runAsUser: 1000
capabilities:
drop:
- ALL

rbac:
create: true
Expand Down
2 changes: 2 additions & 0 deletions pkg/controllers/ingress/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ func GetSSLConfigForBackendSet(namespace string, artifactType string, artifact s
if *caBundle.Name != newCertificateName {
klog.Infof("Ca bundle for backend set %s needs update. Old name %s, New name %s", *bs.Name, *caBundle.Name, newCertificateName)
createCaBundle = true
} else {
caBundleId = caBundle.Id
}
} else {
createCaBundle = true
Expand Down
24 changes: 22 additions & 2 deletions pkg/controllers/ingressclass/ingressclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,13 @@ func (c *Controller) createLoadBalancer(ctx context.Context, ic *networkingv1.In
return nil, err
}

defaultTags := getImplicitDefaultTagsForNewLoadBalancer(lb.DefinedTags, definedTags)
klog.Infof("Back-filling default tags %+v in LB %s for IC %s", defaultTags, *lb.Id, ic.Name)
err = updateImplicitDefaultTagsAnnotation(wrapperClient.GetK8Client(), ic, defaultTags)
if err != nil {
return nil, fmt.Errorf("unable to update implicit-default-tags for IC %s: %w", ic.Name, err)
}

return lb, nil
}

Expand Down Expand Up @@ -392,21 +399,34 @@ func (c *Controller) checkForIngressClassParameterUpdates(ctx context.Context, i

// check LoadBalancerName, Defined and Freeform tags
displayName := util.GetIngressClassLoadBalancerName(ic, icp)
definedTags, err := util.GetIngressClassDefinedTags(ic)
implicitDefaultTags, err := util.GetIngressClassImplicitDefaultTags(ic)
if err != nil {
return err
}

definedTags, updatedImplicitDefaultTags, err := getUpdatedDefinedAndImplicitDefaultTags(lb.DefinedTags, ic)
if err != nil {
return err
}

freeformTags, err := util.GetIngressClassFreeformTags(ic)
if err != nil {
return err
}

if *lb.DisplayName != displayName || !reflect.DeepEqual(lb.DefinedTags, definedTags) || !reflect.DeepEqual(lb.FreeformTags, freeformTags) {
if *lb.DisplayName != displayName || !isDefinedTagsEqual(lb.DefinedTags, definedTags) || !reflect.DeepEqual(lb.FreeformTags, freeformTags) {
_, err = wrapperClient.GetLbClient().UpdateLoadBalancer(context.Background(), *lb.Id, displayName, definedTags, freeformTags)
if err != nil {
return err
}
}

if !isDefinedTagsEqual(implicitDefaultTags, updatedImplicitDefaultTags) {
klog.Infof("Updating implicit default tags %+v in LB %s for IC %s", updatedImplicitDefaultTags, *lb.Id, ic.Name)
err = updateImplicitDefaultTagsAnnotation(wrapperClient.GetK8Client(), ic, updatedImplicitDefaultTags)
if err != nil {
return err
}
}

// refresh lb, etag information after last call
Expand Down
175 changes: 175 additions & 0 deletions pkg/controllers/ingressclass/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
*
* * OCI Native Ingress Controller
* *
* * Copyright (c) 2024 Oracle America, Inc. and its affiliates.
* * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*
*/

package ingressclass

import (
"encoding/json"
"github.com/oracle/oci-native-ingress-controller/pkg/util"
networkingv1 "k8s.io/api/networking/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"reflect"
"strings"
)

var (
tagVariables = []string{
"${iam.principal.name}",
"${iam.principal.type}",
"${oci.datetime}",
}
)

func isDefinedTagsEqual(dt1, dt2 util.DefinedTagsType) bool {
return reflect.DeepEqual(getLowerCaseDefinedTags(dt1), getLowerCaseDefinedTags(dt2))
}

func getImplicitDefaultTagsForNewLoadBalancer(actualDefinedTags, suppliedDefinedTags util.DefinedTagsType) util.DefinedTagsType {
defaultTags := util.DefinedTagsType{}
lowerCaseSuppliedDefinedTags := getLowerCaseDefinedTags(suppliedDefinedTags)

klog.Infof("Calculating implicit default tags where actualTags: %+v, suppliedTags: %+v",
actualDefinedTags, suppliedDefinedTags)

for namespace, _ := range actualDefinedTags {
for key, value := range actualDefinedTags[namespace] {
if !containsDefinedTagIgnoreCase(lowerCaseSuppliedDefinedTags, namespace, key) {
insertDefinedTag(defaultTags, namespace, key, value)
}
}
}

return defaultTags
}

func getUpdatedDefinedAndImplicitDefaultTags(actualTags util.DefinedTagsType,
ic *networkingv1.IngressClass) (util.DefinedTagsType, util.DefinedTagsType, error) {
updatedDefinedTags := util.DefinedTagsType{}
updatedDefaultTags := util.DefinedTagsType{}

definedTags, err := util.GetIngressClassDefinedTags(ic)
if err != nil {
return nil, nil, err
}

defaultTags, err := util.GetIngressClassImplicitDefaultTags(ic)
if err != nil {
return nil, nil, err
}

klog.Infof("Calculating defined/default tags where actualTags: %+v, suppliedDefinedTags: %+v, implicitDefaultTags: %+v",
actualTags, definedTags, defaultTags)

// Preserve default tags if they are present on LB and not overriden in supplied tags
lcDefinedTags := getLowerCaseDefinedTags(definedTags)
lcDefaultTags := getLowerCaseDefinedTags(defaultTags)
for namespace, _ := range actualTags {
for key, value := range actualTags[namespace] {
if !containsDefinedTagIgnoreCase(lcDefinedTags, namespace, key) &&
containsDefinedTagIgnoreCase(lcDefaultTags, namespace, key) {
insertDefinedTag(updatedDefinedTags, namespace, key, value)
insertDefinedTag(updatedDefaultTags, namespace, key, value)
}
}
}

// Add supplied defined tags
// We use only lower-case (namespace, key) pairs to avoid case-related conflicts
// If the supplied tag value has a Tag Variable, and the tag is already present on LB we will not try to update it
lcActualTags := getLowerCaseDefinedTags(actualTags)
lcUpdatedDefinedTags := getLowerCaseDefinedTags(updatedDefinedTags)
for namespace, _ := range lcDefinedTags {
for key, value := range lcDefinedTags[namespace] {
if definedTagValueHasTagVariable(value) && containsDefinedTagIgnoreCase(lcActualTags, namespace, key) {
klog.Infof("Supplied value of Tag %s.%s has tag-variable(s) and is already present on LB, will not be updated",
namespace, key)
insertDefinedTag(lcUpdatedDefinedTags, namespace, key, lcActualTags[namespace][key])
} else {
insertDefinedTag(lcUpdatedDefinedTags, namespace, key, value)
}
}
}

klog.Infof("Calculated defined/default tags for IngressClass %s: definedTags: %+v, implicitDefaultTags: %+v",
ic.Name, lcUpdatedDefinedTags, updatedDefaultTags)
return lcUpdatedDefinedTags, updatedDefaultTags, nil
}

func updateImplicitDefaultTagsAnnotation(client kubernetes.Interface, ic *networkingv1.IngressClass,
defaultTags util.DefinedTagsType) error {
defaultTagsBytes, err := json.Marshal(defaultTags)
if err != nil {
return err
}

patchError, notComplete := util.PatchIngressClassWithAnnotation(client, ic,
util.IngressClassImplicitDefaultTagsAnnotation, string(defaultTagsBytes))
if notComplete {
return patchError
}

return nil
}

func getLowerCaseDefinedTags(tags util.DefinedTagsType) util.DefinedTagsType {
lowerCaseTags := util.DefinedTagsType{}

for k, _ := range tags {
lowerCaseTags[strings.ToLower(k)] = map[string]interface{}{}
for ik, iv := range tags[k] {
lowerCaseTags[strings.ToLower(k)][strings.ToLower(ik)] = iv
}
}

return lowerCaseTags
}

// Checks if (namespace, key) pair exists in a lower-cased definedTags map, ignore case of (namespace, key)
func containsDefinedTagIgnoreCase(lowerCaseTags util.DefinedTagsType, namespace string, key string) bool {
if lowerCaseTags == nil {
return false
}

containsNamespace := false
containsKey := false

_, containsNamespace = lowerCaseTags[strings.ToLower(namespace)]
if containsNamespace {
_, containsKey = lowerCaseTags[strings.ToLower(namespace)][strings.ToLower(key)]
}

return containsNamespace && containsKey
}

func insertDefinedTag(definedTags util.DefinedTagsType, namespace string, key string, value interface{}) {
if definedTags == nil {
return
}

_, ok := definedTags[namespace]
if !ok {
definedTags[namespace] = map[string]interface{}{}
}

definedTags[namespace][key] = value
}

func definedTagValueHasTagVariable(value interface{}) bool {
stringValue, ok := value.(string)
if ok {
for _, tagVar := range tagVariables {
if strings.Contains(stringValue, tagVar) {
return true
}
}
}

return false
}
Loading
Loading