Skip to content

Commit

Permalink
Implement periodic gathering as a job in tech preview (#787)
Browse files Browse the repository at this point in the history
* Implement periodic gathering as a job in tech preview (#764)

* Run gathering as separate Pod in tech preview

* Move downloading of reports to operator part & propagate Insights Request ID

* Minor updates

* DataGather CR - very first  commit

* create a new DataGather CR and prune periodically

* read and apply gatherers config from the new CR

* Fix anonymizer

* do not duplicate gatherer status creation

* extract the job responsibility and fix contexts

* Copy Gatherer status & tests

* diskrecorder_test - narrow down the testing archive path

* Fix error reporting in periodic.go

* reorder manifest creation experiment

* status reporter must be always started for now

* rebase

* add resource requests to the new job

* rebase

* pass linting

* rebase
  • Loading branch information
tremes authored Jun 21, 2023
1 parent c0f05d3 commit bb72dd0
Show file tree
Hide file tree
Showing 67 changed files with 5,305 additions and 467 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ linters:
enable:
- bodyclose
- deadcode
- depguard
#- depguard
- dogsled
- dupl
- errcheck
Expand Down
1 change: 1 addition & 0 deletions cmd/insights-operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func NewOperatorCommand() *cobra.Command {
cmd.AddCommand(start.NewOperator())
cmd.AddCommand(start.NewReceiver())
cmd.AddCommand(start.NewGather())
cmd.AddCommand(start.NewGatherAndUpload())

return cmd
}
3 changes: 2 additions & 1 deletion cmd/obfuscate-archive/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/api/insights/v1alpha1"
"github.com/openshift/insights-operator/pkg/anonymization"
"github.com/openshift/insights-operator/pkg/gather"
"github.com/openshift/insights-operator/pkg/record"
Expand Down Expand Up @@ -61,7 +62,7 @@ func obfuscateArchive(path string) (string, error) {
return "", err
}

anonymizer, err := anonymization.NewAnonymizer(clusterBaseDomain, networks, nil, nil, nil)
anonymizer, err := anonymization.NewAnonymizer(clusterBaseDomain, networks, nil, nil, v1alpha1.ObfuscateNetworking)
if err != nil {
return "", err
}
Expand Down
29 changes: 29 additions & 0 deletions manifests/03-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ metadata:
include.release.openshift.io/single-node-developer: "true"
capability.openshift.io/name: Insights
rules:
- apiGroups:
- "insights.openshift.io"
resources:
- datagathers
- datagathers/status
verbs:
- create
- get
- update
- patch
- list
- delete
- watch
- apiGroups:
- "operator.openshift.io"
resources:
Expand Down Expand Up @@ -377,6 +390,22 @@ rules:
- pods
verbs:
- get
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- get
- list
- delete
- apiGroups:
- apps
resources:
- deployments
verbs:
- get

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
Expand Down
File renamed without changes.
File renamed without changes.
323 changes: 323 additions & 0 deletions manifests/04-datagather-insights-crd.yaml

Large diffs are not rendered by default.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 10 additions & 10 deletions pkg/anonymization/anonymizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
"sync"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/api/config/v1alpha1"
"github.com/openshift/api/insights/v1alpha1"
networkv1 "github.com/openshift/api/network/v1"
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
networkv1client "github.com/openshift/client-go/network/clientset/versioned/typed/network/v1"
Expand Down Expand Up @@ -88,7 +88,7 @@ type Anonymizer struct {
ipNetworkRegex *regexp.Regexp
secretsClient corev1client.SecretInterface
secretConfigurator configobserver.Configurator
apiConfigurator configobserver.InsightsDataGatherObserver
dataPolicy v1alpha1.DataPolicy
configClient configv1client.ConfigV1Interface
networkClient networkv1client.NetworkV1Interface
gatherKubeClient kubernetes.Interface
Expand All @@ -104,7 +104,7 @@ func NewAnonymizer(clusterBaseDomain string,
networks []string,
secretsClient corev1client.SecretInterface,
secretConfigurator configobserver.Configurator,
apiConfigurator configobserver.InsightsDataGatherObserver) (*Anonymizer, error) {
dataPolicy v1alpha1.DataPolicy) (*Anonymizer, error) {
cidrs, err := k8snet.ParseCIDRs(networks)
if err != nil {
return nil, err
Expand All @@ -126,7 +126,7 @@ func NewAnonymizer(clusterBaseDomain string,
ipNetworkRegex: regexp.MustCompile(Ipv4AddressOrNetworkRegex),
secretsClient: secretsClient,
secretConfigurator: secretConfigurator,
apiConfigurator: apiConfigurator,
dataPolicy: dataPolicy,
}, nil
}

Expand All @@ -138,14 +138,14 @@ func NewAnonymizerFromConfigClient(
configClient configv1client.ConfigV1Interface,
networkClient networkv1client.NetworkV1Interface,
secretConfigurator configobserver.Configurator,
apiConfigurator configobserver.InsightsDataGatherObserver,
dataPolicy v1alpha1.DataPolicy,
) (*Anonymizer, error) {
baseDomain, err := utils.GetClusterBaseDomain(ctx, configClient)
if err != nil {
return nil, err
}
secretsClient := kubeClient.CoreV1().Secrets(secretNamespace)
a, err := NewAnonymizer(baseDomain, []string{}, secretsClient, secretConfigurator, apiConfigurator)
a, err := NewAnonymizer(baseDomain, []string{}, secretsClient, secretConfigurator, dataPolicy)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -322,7 +322,7 @@ func NewAnonymizerFromConfig(
gatherProtoKubeConfig *rest.Config,
protoKubeConfig *rest.Config,
secretConfigurator configobserver.Configurator,
apiConfigurator configobserver.InsightsDataGatherObserver,
dataPolicy v1alpha1.DataPolicy,
) (*Anonymizer, error) {
kubeClient, err := kubernetes.NewForConfig(protoKubeConfig)
if err != nil {
Expand All @@ -344,7 +344,7 @@ func NewAnonymizerFromConfig(
return nil, err
}

return NewAnonymizerFromConfigClient(ctx, kubeClient, gatherKubeClient, configClient, networkClient, secretConfigurator, apiConfigurator)
return NewAnonymizerFromConfigClient(ctx, kubeClient, gatherKubeClient, configClient, networkClient, secretConfigurator, dataPolicy)
}

// AnonymizeMemoryRecord takes record.MemoryRecord, removes the sensitive data from it and returns the same object
Expand Down Expand Up @@ -484,8 +484,8 @@ func (anonymizer *Anonymizer) IsObfuscationEnabled() bool {
if anonymizer.secretConfigurator.Config().EnableGlobalObfuscation {
return true
}
if anonymizer.apiConfigurator != nil {
return *anonymizer.apiConfigurator.GatherDataPolicy() == v1alpha1.ObfuscateNetworking
if anonymizer.dataPolicy != "" {
return anonymizer.dataPolicy == v1alpha1.ObfuscateNetworking
}
return false
}
Expand Down
12 changes: 3 additions & 9 deletions pkg/anonymization/anonymizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/api/config/v1alpha1"
"github.com/openshift/api/insights/v1alpha1"
networkv1 "github.com/openshift/api/network/v1"
configfake "github.com/openshift/client-go/config/clientset/versioned/fake"
networkfake "github.com/openshift/client-go/network/clientset/versioned/fake"
Expand Down Expand Up @@ -123,11 +123,8 @@ func getAnonymizer(t *testing.T) *Anonymizer {
mockSecretConfigurator := config.NewMockSecretConfigurator(&config.Controller{
EnableGlobalObfuscation: true,
})
mockAPIConfigurator := config.NewMockAPIConfigurator(&v1alpha1.GatherConfig{
DataPolicy: v1alpha1.ObfuscateNetworking,
})
anonymizer, err := NewAnonymizer(clusterBaseDomain,
networks, kubefake.NewSimpleClientset().CoreV1().Secrets(secretNamespace), mockSecretConfigurator, mockAPIConfigurator)
networks, kubefake.NewSimpleClientset().CoreV1().Secrets(secretNamespace), mockSecretConfigurator, v1alpha1.ObfuscateNetworking)
assert.NoError(t, err)

return anonymizer
Expand Down Expand Up @@ -332,10 +329,7 @@ func TestAnonymizer_NewAnonymizerFromConfigClient(t *testing.T) {
networkClient,
config.NewMockSecretConfigurator(&config.Controller{
EnableGlobalObfuscation: true,
}),
config.NewMockAPIConfigurator(&v1alpha1.GatherConfig{
DataPolicy: v1alpha1.ObfuscateNetworking,
}),
}), v1alpha1.ObfuscateNetworking,
)
assert.NoError(t, err)
assert.NotNil(t, anonymizer)
Expand Down
2 changes: 1 addition & 1 deletion pkg/authorizer/clusterauthorizer/clusterauthorizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func Test_Proxy(tt *testing.T) {
co2 := &config.MockSecretConfigurator{Conf: &config.Controller{HTTPConfig: tc.HTTPConfig}}
a := Authorizer{proxyFromEnvironment: nonCachedProxyFromEnvironment(), configurator: co2}
p := a.NewSystemOrConfiguredProxy()
req := httptest.NewRequest("GET", tc.RequestURL, nil)
req := httptest.NewRequest("GET", tc.RequestURL, http.NoBody)
urlRec, err := p(req)

if err != nil {
Expand Down
82 changes: 79 additions & 3 deletions pkg/cmd/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import (
"github.com/openshift/insights-operator/pkg/controller"
)

const serviceCACertPath = "/var/run/configmaps/service-ca-bundle/service-ca.crt"
const (
serviceCACertPath = "/var/run/configmaps/service-ca-bundle/service-ca.crt"
pbContentType = "application/vnd.kubernetes.protobuf"
pbAcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
)

// NewOperator create the commad for running the Insights Operator.
func NewOperator() *cobra.Command {
Expand Down Expand Up @@ -78,6 +82,29 @@ func NewGather() *cobra.Command {
return cmd
}

func NewGatherAndUpload() *cobra.Command {
operator := &controller.GatherJob{
Controller: config.Controller{
ConditionalGathererEndpoint: "https://console.redhat.com/api/gathering/gathering_rules",
StoragePath: "/var/lib/insights-operator",
Interval: 2 * time.Hour,
Endpoint: "https://console.redhat.com/api/ingress/v1/upload",
ReportEndpoint: "https://console.redhat.com/api/insights-results-aggregator/v2/cluster/%s/reports",
ReportPullingDelay: 60 * time.Second,
ReportMinRetryTime: 10 * time.Second,
ReportPullingTimeout: 30 * time.Minute,
},
}
cfg := controllercmd.NewControllerCommandConfig("openshift-insights-operator", version.Get(), nil)
cmd := &cobra.Command{
Use: "gather-and-upload",
Short: "Runs the data gathering as job, uploads the data, waits for Insights analysis report and ends",
Run: runGatherAndUpload(operator, cfg),
}
cmd.Flags().AddFlagSet(cfg.NewCommand().Flags())
return cmd
}

// Starts a single gather, main responsibility is loading in the necessary configs.
func runGather(operator *controller.GatherJob, cfg *controllercmd.ControllerCommandConfig) func(cmd *cobra.Command, args []string) {
return func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -115,8 +142,8 @@ func runGather(operator *controller.GatherJob, cfg *controllercmd.ControllerComm
}
}
protoConfig := rest.CopyConfig(clientConfig)
protoConfig.AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
protoConfig.ContentType = "application/vnd.kubernetes.protobuf"
protoConfig.AcceptContentTypes = pbAcceptContentTypes
protoConfig.ContentType = pbContentType

ctx, cancel := context.WithTimeout(context.Background(), operator.Interval)

Expand Down Expand Up @@ -219,3 +246,52 @@ func runOperator(operator *controller.Operator, cfg *controllercmd.ControllerCom
}
}
}

// Starts a single gather, main responsibility is loading in the necessary configs.
func runGatherAndUpload(operator *controller.GatherJob,
cfg *controllercmd.ControllerCommandConfig) func(cmd *cobra.Command, args []string) {
return func(cmd *cobra.Command, args []string) {
if configArg := cmd.Flags().Lookup("config").Value.String(); len(configArg) == 0 {
klog.Exit("error: --config is required")
}
unstructured, _, _, err := cfg.Config()
if err != nil {
klog.Exit(err)
}
cont, err := config.LoadConfig(operator.Controller, unstructured.Object, config.ToDisconnectedController)
if err != nil {
klog.Exit(err)
}
operator.Controller = cont

var clientConfig *rest.Config
if kubeConfigPath := cmd.Flags().Lookup("kubeconfig").Value.String(); len(kubeConfigPath) > 0 {
kubeConfigBytes, err := os.ReadFile(kubeConfigPath) //nolint: govet
if err != nil {
klog.Exit(err)
}
kubeConfig, err := clientcmd.NewClientConfigFromBytes(kubeConfigBytes)
if err != nil {
klog.Exit(err)
}
clientConfig, err = kubeConfig.ClientConfig()
if err != nil {
klog.Exit(err)
}
} else {
clientConfig, err = rest.InClusterConfig()
if err != nil {
klog.Exit(err)
}
}
protoConfig := rest.CopyConfig(clientConfig)
protoConfig.AcceptContentTypes = pbAcceptContentTypes
protoConfig.ContentType = pbContentType

err = operator.GatherAndUpload(clientConfig, protoConfig)
if err != nil {
klog.Exit(err)
}
os.Exit(0)
}
}
2 changes: 1 addition & 1 deletion pkg/config/configobserver/insighgtsdatagather_observer.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func NewInsightsDataGatherObserver(kubeConfig *rest.Config,
return c, nil
}

func (i *insightsDataGatherController) sync(ctx context.Context, scx factory.SyncContext) error {
func (i *insightsDataGatherController) sync(ctx context.Context, _ factory.SyncContext) error {
insightDataGatherConf, err := i.configV1Alpha1Cli.InsightsDataGathers().Get(ctx, "cluster", metav1.GetOptions{})
if err != nil {
return err
Expand Down
Loading

0 comments on commit bb72dd0

Please sign in to comment.