Skip to content
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
214 changes: 214 additions & 0 deletions deploy/crds/enterprise.splunk.com_monitoringconsoles_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,84 @@ spec:
type: array
type: object
type: object
appRepo:
description: Splunk Enterprise App repository. Specifies remote App
location and scope for Splunk App management
properties:
appSources:
description: List of App sources on remote storage
items:
description: AppSourceSpec defines list of App package (*.spl,
*.tgz) locations on remote volumes
properties:
location:
description: Location relative to the volume path
type: string
name:
description: Logical name for the set of apps placed in
this location. Logical name must be unique to the appRepo
type: string
scope:
description: 'Scope of the App deployment: cluster, clusterWithPreConfig,
local. Scope determines whether the App(s) is/are installed
locally or cluster-wide'
type: string
volumeName:
description: Remote Storage Volume name
type: string
type: object
type: array
appsRepoPollIntervalSeconds:
description: Interval in seconds to check the Remote Storage for
App changes. The default value for this config is 1 hour(3600
sec), minimum value is 1 minute(60sec) and maximum value is
1 day(86400 sec). We assign the value based on following conditions
- 1. If no value or 0 is specified then it will be defaulted
to 1 hour. 2. If anything less than min is specified then
we set it to 1 min. 3. If anything more than the max value
is specified then we set it to 1 day.
format: int64
type: integer
defaults:
description: Defines the default configuration settings for App
sources
properties:
scope:
description: 'Scope of the App deployment: cluster, clusterWithPreConfig,
local. Scope determines whether the App(s) is/are installed
locally or cluster-wide'
type: string
volumeName:
description: Remote Storage Volume name
type: string
type: object
volumes:
description: List of remote storage volumes
items:
description: VolumeSpec defines remote volume config
properties:
endpoint:
description: Remote volume URI
type: string
name:
description: Remote volume name
type: string
path:
description: Remote volume path
type: string
provider:
description: 'App Package Remote Store provider. Supported
values: aws, minio'
type: string
secretRef:
description: Secret object name
type: string
storageType:
description: 'Remote Storage type. Supported values: s3'
type: string
type: object
type: array
type: object
clusterMasterRef:
description: ClusterMasterRef refers to a Splunk Enterprise indexer
cluster managed by the operator within Kubernetes
Expand Down Expand Up @@ -2481,6 +2559,142 @@ spec:
status:
description: MonitoringConsoleStatus defines the observed state of MonitoringConsole
properties:
appContext:
description: App Framework status
properties:
appRepo:
description: List of App package (*.spl, *.tgz) locations on remote
volume
properties:
appSources:
description: List of App sources on remote storage
items:
description: AppSourceSpec defines list of App package (*.spl,
*.tgz) locations on remote volumes
properties:
location:
description: Location relative to the volume path
type: string
name:
description: Logical name for the set of apps placed
in this location. Logical name must be unique to the
appRepo
type: string
scope:
description: 'Scope of the App deployment: cluster,
clusterWithPreConfig, local. Scope determines whether
the App(s) is/are installed locally or cluster-wide'
type: string
volumeName:
description: Remote Storage Volume name
type: string
type: object
type: array
appsRepoPollIntervalSeconds:
description: Interval in seconds to check the Remote Storage
for App changes. The default value for this config is 1
hour(3600 sec), minimum value is 1 minute(60sec) and maximum
value is 1 day(86400 sec). We assign the value based on
following conditions - 1. If no value or 0 is specified
then it will be defaulted to 1 hour. 2. If anything less
than min is specified then we set it to 1 min. 3. If
anything more than the max value is specified then we set
it to 1 day.
format: int64
type: integer
defaults:
description: Defines the default configuration settings for
App sources
properties:
scope:
description: 'Scope of the App deployment: cluster, clusterWithPreConfig,
local. Scope determines whether the App(s) is/are installed
locally or cluster-wide'
type: string
volumeName:
description: Remote Storage Volume name
type: string
type: object
volumes:
description: List of remote storage volumes
items:
description: VolumeSpec defines remote volume config
properties:
endpoint:
description: Remote volume URI
type: string
name:
description: Remote volume name
type: string
path:
description: Remote volume path
type: string
provider:
description: 'App Package Remote Store provider. Supported
values: aws, minio'
type: string
secretRef:
description: Secret object name
type: string
storageType:
description: 'Remote Storage type. Supported values:
s3'
type: string
type: object
type: array
type: object
appSrcDeployStatus:
additionalProperties:
description: AppSrcDeployInfo represents deployment info for
list of Apps
properties:
appDeploymentInfo:
items:
description: AppDeploymentInfo represents a single App
deployment information
properties:
Size:
format: int64
type: integer
appName:
type: string
deployStatus:
description: AppDeploymentStatus represents the status
of an App on the Pod
type: integer
lastModifiedTime:
type: string
objectHash:
type: string
repoState:
description: AppRepoState represent the App state
on remote store
type: integer
type: object
type: array
type: object
description: Represents the Apps deployment status
type: object
appsRepoStatusPollIntervalSeconds:
description: Interval in seconds to check the Remote Storage for
App changes This is introduced here so that we dont do spec
validation in every reconcile just because the spec and status
are different.
format: int64
type: integer
isDeploymentInProgress:
description: IsDeploymentInProgress indicates if the Apps deployment
is in progress
type: boolean
lastAppInfoCheckTime:
description: This is set to the time when we get the list of apps
from remote storage.
format: int64
type: integer
version:
description: App Framework version info for future use
type: integer
type: object
bundlePushInfo:
description: Bundle push status tracker
properties:
Expand Down
6 changes: 6 additions & 0 deletions pkg/apis/enterprise/v2/monitoringconsole_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import (
// MonitoringConsoleSpec defines the desired state of MonitoringConsole
type MonitoringConsoleSpec struct {
CommonSplunkSpec `json:",inline"`

// Splunk Enterprise App repository. Specifies remote App location and scope for Splunk App management
AppFrameworkConfig AppFrameworkSpec `json:"appRepo,omitempty"`
}

// MonitoringConsoleStatus defines the observed state of MonitoringConsole
Expand All @@ -45,6 +48,9 @@ type MonitoringConsoleStatus struct {

// Resource Revision tracker
ResourceRevMap map[string]string `json:"resourceRevMap"`

// App Framework status
AppContext AppDeploymentContext `json:"appContext,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/enterprise/v2/zz_generated.deepcopy.go

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

13 changes: 4 additions & 9 deletions pkg/splunk/enterprise/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,7 @@ func getSplunkStatefulSet(client splcommon.ControllerClient, cr splcommon.MetaOb
func getAppListingConfigMap(client splcommon.ControllerClient, cr splcommon.MetaObject, instanceType InstanceType) *corev1.ConfigMap {
var configMap *corev1.ConfigMap

// ToDo: Exclude MC, once it's own CR is available
if instanceType != SplunkIndexer && instanceType != SplunkSearchHead && instanceType != SplunkMonitoringConsole {
if instanceType != SplunkIndexer && instanceType != SplunkSearchHead {
appsConfigMapName := GetSplunkAppsConfigMapName(cr.GetName(), cr.GetObjectKind().GroupVersionKind().Kind)
namespacedName := types.NamespacedName{Namespace: cr.GetNamespace(), Name: appsConfigMapName}
configMap, _ = splctrl.GetConfigMap(client, namespacedName)
Expand Down Expand Up @@ -610,7 +609,7 @@ func updateSplunkPodTemplateWithConfig(client splcommon.ControllerClient, podTem
// Always sort the slice, so that map entries are ordered, to avoid pod resets
sort.Strings(appListingFiles)

if instanceType == SplunkDeployer || instanceType == SplunkClusterMaster || instanceType == SplunkStandalone || instanceType == SplunkLicenseMaster {
if instanceType != SplunkIndexer && instanceType != SplunkSearchHead {
additionalDelayForAppInstallation = int32(maxSplunkAppsInstallationDelaySecs)
}
}
Expand All @@ -620,12 +619,8 @@ func updateSplunkPodTemplateWithConfig(client splcommon.ControllerClient, podTem

// prepare defaults variable
splunkDefaults := "/mnt/splunk-secrets/default.yml"
// Check for apps defaults and add it to only the standalone or deployer/cm instances
if spec.DefaultsURLApps != "" &&
(instanceType == SplunkDeployer ||
instanceType == SplunkStandalone ||
instanceType == SplunkClusterMaster ||
instanceType == SplunkLicenseMaster) {
// Check for apps defaults and add it to only the standalone or deployer/cm/mc instances
if spec.DefaultsURLApps != "" && instanceType != SplunkIndexer && instanceType != SplunkSearchHead {
splunkDefaults = fmt.Sprintf("%s,%s", spec.DefaultsURLApps, splunkDefaults)
}
if spec.DefaultsURL != "" {
Expand Down
42 changes: 37 additions & 5 deletions pkg/splunk/enterprise/monitoringconsole.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,36 @@ func ApplyMonitoringConsole(client splcommon.ControllerClient, cr *enterpriseApi
Requeue: true,
RequeueAfter: time.Second * 5,
}

scopedLog := log.WithName("ApplyMonitoringConsole").WithValues("name", cr.GetName(), "namespace", cr.GetNamespace())
if cr.Status.ResourceRevMap == nil {
cr.Status.ResourceRevMap = make(map[string]string)
}

// validate and updates defaults for CR
err := validateMonitoringConsoleSpec(&cr.Spec)
err := validateMonitoringConsoleSpec(cr)
if err != nil {
return result, err
}

// updates status after function completes
cr.Status.Phase = splcommon.PhaseError

// If the app framework is configured then do following things -
// 1. Initialize the S3Clients based on providers
// 2. Check the status of apps on remote storage.
if len(cr.Spec.AppFrameworkConfig.AppSources) != 0 {
err := initAndCheckAppInfoStatus(client, cr, &cr.Spec.AppFrameworkConfig, &cr.Status.AppContext)
if err != nil {
return result, err
}
}

cr.Status.Selector = fmt.Sprintf("app.kubernetes.io/instance=splunk-%s-monitoring-console", cr.GetName())
defer func() {
client.Status().Update(context.TODO(), cr)
if err != nil {
scopedLog.Error(err, "Status update failed")
}
}()

// create or update general config resources
Expand Down Expand Up @@ -104,6 +117,16 @@ func ApplyMonitoringConsole(client splcommon.ControllerClient, cr *enterpriseApi

// no need to requeue if everything is ready
if cr.Status.Phase == splcommon.PhaseReady {
if cr.Status.AppContext.AppsSrcDeployStatus != nil {
markAppsStatusToComplete(client, cr, &cr.Spec.AppFrameworkConfig, cr.Status.AppContext.AppsSrcDeployStatus)
}

// Requeue the reconcile after polling interval if we had set the lastAppInfoCheckTime.
if cr.Status.AppContext.LastAppInfoCheckTime != 0 {
result.RequeueAfter = GetNextRequeueTime(cr.Status.AppContext.AppsRepoStatusPollInterval, cr.Status.AppContext.LastAppInfoCheckTime)
} else {
result.Requeue = false
}
result.Requeue = false
}
return result, nil
Expand Down Expand Up @@ -136,12 +159,21 @@ func getMonitoringConsoleStatefulSet(client splcommon.ControllerClient, cr *ente
return nil, err
}
ss.Spec.Template.ObjectMeta.Annotations[monitoringConsoleConfigRev] = monitoringConsoleConfigMap.ResourceVersion

// Setup App framework init containers
setupAppInitContainers(client, cr, &ss.Spec.Template, &cr.Spec.AppFrameworkConfig)
return ss, nil
}

// validateMonitoringConsoleSpec checks validity and makes default updates to a MonitoringConsoleSpec, and returns error if something is wrong.
func validateMonitoringConsoleSpec(spec *enterpriseApi.MonitoringConsoleSpec) error {
return validateCommonSplunkSpec(&spec.CommonSplunkSpec)
// validateMonitoringConsoleSpec checks validity and makes default updates to a MonitoringConsole, and returns error if something is wrong.
func validateMonitoringConsoleSpec(cr *enterpriseApi.MonitoringConsole) error {
if !reflect.DeepEqual(cr.Status.AppContext.AppFrameworkConfig, cr.Spec.AppFrameworkConfig) {
err := ValidateAppFrameworkSpec(&cr.Spec.AppFrameworkConfig, &cr.Status.AppContext, true)
if err != nil {
return err
}
}
return validateCommonSplunkSpec(&cr.Spec.CommonSplunkSpec)
}

//ApplyMonitoringConsoleEnvConfigMap creates or updates a Kubernetes ConfigMap for extra env for monitoring console pod
Expand Down
Loading