Skip to content

Commit

Permalink
Merge pull request #150 from vareti/normalize-log-levels
Browse files Browse the repository at this point in the history
Bug 1878007: Add Controller to Normalize the Operator Log Level Values
  • Loading branch information
openshift-merge-robot committed Oct 29, 2020
2 parents 9733d3f + aba01f0 commit 4800f81
Show file tree
Hide file tree
Showing 11 changed files with 385 additions and 55 deletions.
6 changes: 3 additions & 3 deletions go.mod
Expand Up @@ -6,10 +6,10 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
github.com/go-bindata/go-bindata v3.1.2+incompatible
github.com/openshift/api v0.0.0-20200518100801-1de8998c0357
github.com/openshift/api v0.0.0-20200521101457-60c476765272
github.com/openshift/build-machinery-go v0.0.0-20200512074546-3744767c4131
github.com/openshift/client-go v0.0.0-20200422192633-6f6c07fc2a70
github.com/openshift/library-go v0.0.0-20200512120242-21a1ff978534
github.com/openshift/client-go v0.0.0-20200521150516-05eb9880269c
github.com/openshift/library-go v0.0.0-20200924151131-575c4875cdbe
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0
Expand Down
52 changes: 17 additions & 35 deletions go.sum
Expand Up @@ -283,21 +283,16 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20191031171055-b133feaeeb2e/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/openshift/api v0.0.0-20200326152221-912866ddb162/go.mod h1:RKMJ5CBnljLfnej+BJ/xnOWc3kZDvJUaIAEq2oKSPtE=
github.com/openshift/api v0.0.0-20200424083944-0422dc17083e/go.mod h1:VnbEzX8SAaRj7Yfl836NykdQIlbEjfL6/CD+AaJQg5Q=
github.com/openshift/api v0.0.0-20200518100801-1de8998c0357 h1:L4tcPIM8YmhM/DW6WrN1zBzu6eLGVYMqb6sr3nfBp8g=
github.com/openshift/api v0.0.0-20200518100801-1de8998c0357/go.mod h1:VnbEzX8SAaRj7Yfl836NykdQIlbEjfL6/CD+AaJQg5Q=
github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc=
github.com/openshift/api v0.0.0-20200521101457-60c476765272 h1:tYm+7yLrK+Ivi5hESBUTIt8+4ejbVux9kdscALiu57g=
github.com/openshift/api v0.0.0-20200521101457-60c476765272/go.mod h1:TkhafijfTiRi1Q3120/ZSE4oIWKQ4DGRh3byPywv4Mw=
github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc h1:Bu1p7+ItPqhJhmMve7sVluKCYV+o+x1Ede0WY2/BI8Q=
github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc=
github.com/openshift/build-machinery-go v0.0.0-20200512074546-3744767c4131 h1:JW0jMasT83C7ZYEYXpCH7bfwqE/QqyOJwGB7u6N3/X0=
github.com/openshift/build-machinery-go v0.0.0-20200512074546-3744767c4131/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0 h1:kMiuiZXH1GdfbiMwsuAQOqGaMxlo9NCUk0wT4XAdfNM=
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4LClRO+fg5MF/P6QxjMCb1C9f7Oh4RKepftDnEJE=
github.com/openshift/client-go v0.0.0-20200422192633-6f6c07fc2a70 h1:LvJxSt/lnLTBbKJC5DfWM9ZvT9Jk0nQa+xPozSJtkqc=
github.com/openshift/client-go v0.0.0-20200422192633-6f6c07fc2a70/go.mod h1:HeCrq1LSOBgHAUpINH4IgBLkt2U/NBwE5sq4JJgcl2Y=
github.com/openshift/library-go v0.0.0-20200512120242-21a1ff978534 h1:RhurNEKr5RBIcnddxfoLVuB86TZRdNq8PH51/1ZAxv4=
github.com/openshift/library-go v0.0.0-20200512120242-21a1ff978534/go.mod h1:2kWwXTkpoQJUN3jZ3QW88EIY1hdRMqxgRs2hheEW/pg=
github.com/openshift/client-go v0.0.0-20200521150516-05eb9880269c h1:l7CmbzzkyWl4Y6qHmy6m4FvbH4iLnIXGrXqOfE5IFNA=
github.com/openshift/client-go v0.0.0-20200521150516-05eb9880269c/go.mod h1:kCMeo6IE4o4qvnepM9lgHQ4j/ZFfvY/N/2G/jpJdwm4=
github.com/openshift/library-go v0.0.0-20200924151131-575c4875cdbe h1:vXACAafr96qkuzPncR2JkZK5UPIFtVDAUAGBuil49kw=
github.com/openshift/library-go v0.0.0-20200924151131-575c4875cdbe/go.mod h1:dJqjuQMmC/T1nhi5yGbRf7qGxnO+vRa2j99y6oVYDZQ=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
Expand Down Expand Up @@ -517,32 +512,21 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ=
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
k8s.io/api v0.18.9 h1:7VDtivqwbvLOf8hmXSd/PDSSbpCBq49MELg84EYBYiQ=
k8s.io/api v0.18.9/go.mod h1:9u/h6sUh6FxfErv7QqetX1EB3yBMIYOBXzdcf0Gf0rc=
k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8=
k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE=
k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.2 h1:44CmtbmkzVDAhCpRVSiP2R5PPrC2RtlIv/MoB8xpdRA=
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apiextensions-apiserver v0.18.3 h1:h6oZO+iAgg0HjxmuNnguNdKNB9+wv3O1EBDdDWJViQ0=
k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE=
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.18.9 h1:3ZABKQx3F3xPWlsGhCfUl8W+JXRRblV6Wo2A3zn0pvY=
k8s.io/apimachinery v0.18.9/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
k8s.io/apiserver v0.18.2 h1:fwKxdTWwwYhxvtjo0UUfX+/fsitsNtfErPNegH2x9ic=
k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4=
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
k8s.io/client-go v0.18.2 h1:aLB0iaD4nmwh7arT2wIn+lMnAq7OswjaejkQ8p9bBYE=
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
k8s.io/apiserver v0.18.3 h1:BVjccwKP/kEqY+ResOyWs0EKs7f4XL0d0E5GkU3uiqI=
k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw=
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
k8s.io/client-go v0.18.9 h1:sPHX49yOtUqv1fl49TwV3f8cC0N3etSnwgFGsIsXnZc=
k8s.io/client-go v0.18.9/go.mod h1:UjkEetDmr40P9NX0Ok3Idt08FCf2I4mIHgjFsot77uY=
k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
k8s.io/component-base v0.18.2 h1:SJweNZAGcUvsypLGNPNGeJ9UgPZQ6+bW+gEHe8uyh/Y=
k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k=
k8s.io/component-base v0.18.9 h1:7G0D/PUKrVxyUxjT5HV4aTqYqhPj60erA1ab1JUw7m8=
k8s.io/component-base v0.18.9/go.mod h1:tUo4qZtV8m7t/U+0DgY+fcnn4BFZ480fZdzxOkWH4zk=
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
Expand All @@ -551,10 +535,8 @@ k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUc
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-aggregator v0.18.2 h1:mgsze91nZC27HeJi8bLRyhLINQznEUy4SOTpbOhsZEM=
k8s.io/kube-aggregator v0.18.2/go.mod h1:ijq6FnNUoKinA6kKbkN6svdTacSoQVNtKqmQ1+XJEYQ=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c h1:/KUFqjjqAcY4Us6luF5RDNZ16KJtb49HfR3ZHB9qYXM=
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/kube-aggregator v0.18.3 h1:zAKL1YuI6KULjvsXFQl0W3pQQt73bGXU20+GzYDtdhc=
k8s.io/kube-aggregator v0.18.3/go.mod h1:fux0WabUOggW2yAACL4jQGVd6kv7mSgBnJ3GgCXCris=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
Expand Down
187 changes: 187 additions & 0 deletions pkg/operator/operatorloglevel/loglevel_controller.go
@@ -0,0 +1,187 @@
package operatorloglevel

import (
"context"
"fmt"
"strings"
"time"

operatorv1 "github.com/openshift/api/operator/v1"
"github.com/openshift/library-go/pkg/controller/factory"
"github.com/openshift/library-go/pkg/operator/events"
"github.com/openshift/library-go/pkg/operator/loglevel"
operatorv1helpers "github.com/openshift/library-go/pkg/operator/v1helpers"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/klog"
)

type operatorLogLevelNormalizer struct {
dynamicClient dynamic.Interface
}

// NewLogLevelNormalizer normalizes the log level in operator custom resource
// if it's value differs from supported values
func NewLogLevelNormalizer(dynamicClient dynamic.Interface,
operatorClient operatorv1helpers.OperatorClient,
recorder events.Recorder) factory.Controller {
c := operatorLogLevelNormalizer{
dynamicClient: dynamicClient,
}

return factory.New().
WithSync(c.sync).
WithSyncDegradedOnError(operatorClient).
ResyncEvery(5*time.Minute).
ToController("OperatorLogLevelNormalizer", recorder)
}

// sync runs periodically and makes sure that the log level field values in operator
// spec does not differ from supported values.
func (c *operatorLogLevelNormalizer) sync(ctx context.Context, syncCtx factory.SyncContext) error {
gvrs := []schema.GroupVersionResource{
{
Group: "imageregistry.operator.openshift.io",
Version: "v1",
Resource: "configs",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "configs",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "etcds",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "kubeapiservers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "kubecontrollermanagers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "kubeschedulers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "openshiftapiservers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "cloudcredentials",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "kubestorageversionmigrators",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "authentications",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "openshiftcontrollermanagers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "storages",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "networks",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "consoles",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "csisnapshotcontrollers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "clustercsidrivers",
},
{
Group: "operator.openshift.io",
Version: "v1",
Resource: "servicecas",
},
}

for _, gvr := range gvrs {
customResources, err := c.dynamicClient.Resource(gvr).List(ctx, metav1.ListOptions{})
if err != nil {
klog.V(4).Infof("error trying to list custom resources for %s: %v", gvr.Resource, err)
continue
}

for _, cr := range customResources.Items {
crCopy := cr.DeepCopy()
eventMsgs, needsUpdate := normalizeLogLevelField(crCopy, gvr.Resource)
if needsUpdate {
if _, err := c.dynamicClient.Resource(gvr).Update(ctx, crCopy, metav1.UpdateOptions{}); err != nil {
klog.Warningf("failed to normalize log level to %v for operator %s: %v", operatorv1.Normal, gvr.Resource, err)
continue
}
for _, event := range eventMsgs {
syncCtx.Recorder().Event("OperatorLogLevelChange", event)
}
}
}
}

return nil
}

func normalizeLogLevelField(cr *unstructured.Unstructured,
resourceName string) ([]string, bool) {
needsUpdate := false
eventMsgs := []string{}

for _, logLevelFieldPath := range [][]string{{"spec", "operatorLogLevel"}, {"spec", "logLevel"}} {
// custom resources that do not have log level field are ignored.
currentLogLevel, ok, err := unstructured.NestedString(cr.UnstructuredContent(), logLevelFieldPath...)
if err != nil {
klog.V(4).Infof("failed to find %q in custom resource %s: %v", strings.Join(logLevelFieldPath, "."), resourceName, err)
continue
}
if !ok {
continue
}

if loglevel.ValidLogLevel(operatorv1.LogLevel(currentLogLevel)) {
continue
}

if err := unstructured.SetNestedField(cr.UnstructuredContent(), string(operatorv1.Normal), logLevelFieldPath...); err != nil {
klog.Warningf("failed to set log level to %s in resource %s", operatorv1.Normal, resourceName)
continue
}

eventMsgs = append(eventMsgs, fmt.Sprintf("%q changed from %q to %q", strings.Join(logLevelFieldPath, "."), currentLogLevel, operatorv1.Normal))
needsUpdate = true
}

return eventMsgs, needsUpdate
}

0 comments on commit 4800f81

Please sign in to comment.