diff --git a/.github/action/operator-sdk/Dockerfile b/.github/action/operator-sdk/Dockerfile deleted file mode 100644 index 8ac18d3a..00000000 --- a/.github/action/operator-sdk/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -FROM golang:1.15.1-alpine3.12 - -LABEL "com.github.actions.name"="operator-sdk" -LABEL "com.github.actions.description"="operator-sdk image builder" -LABEL "com.github.actions.icon"="layers" -LABEL "com.github.actions.color"="red" - -ENV RELEASE_VERSION=v1.3.0 -ENV OPERATOR_COURIER_VERSION=2.1.10 - -RUN apk update \ - && apk upgrade \ - && apk add --no-cache bash curl git openssh make mercurial openrc docker python3 git py-pip gcc \ - && pip3 install --upgrade pip setuptools - -RUN pip3 install operator-courier==${OPERATOR_COURIER_VERSION} - -RUN curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu \ - && chmod +x operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu \ - && cp operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu /usr/local/bin/operator-sdk \ - && rm operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu - -COPY entrypoint.sh /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] diff --git a/.github/action/operator-sdk/entrypoint.sh b/.github/action/operator-sdk/entrypoint.sh deleted file mode 100755 index 7c32514e..00000000 --- a/.github/action/operator-sdk/entrypoint.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -eu - -declare -r project_root="/go/src/github.com/${GITHUB_REPOSITORY}" -declare -r repo_root="$(dirname $project_root)" - -mkdir -p "${repo_root}" -ln -s "$GITHUB_WORKSPACE" "${project_root}" -cd "${project_root}" - -"$@" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 43206401..ff408704 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -40,13 +40,12 @@ jobs: - name: Run Gosec Security Scanner run: | export PATH=$PATH:$(go env GOPATH)/bin - go get github.com/securego/gosec/cmd/gosec - go install github.com/securego/gosec/cmd/gosec - gosec ./... + go install github.com/securego/gosec/v2/cmd/gosec@latest + gosec -exclude-dir images/logscale-dummy -exclude-generated ./... - name: Run Staticcheck uses: dominikh/staticcheck-action@v1.3.1 with: - version: "2023.1.7" + version: "2024.1.1" install-go: false - name: operator image run: make docker-build-operator IMG=humio/humio-operator:${{ github.sha }} diff --git a/Dockerfile b/Dockerfile index 7e93313f..67867099 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN go mod download COPY main.go main.go COPY api/ api/ COPY controllers/ controllers/ -COPY pkg/ pkg/ +COPY internal/ internal/ # Build RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldflags="-s -w -X 'main.version=$RELEASE_VERSION' -X 'main.commit=$RELEASE_COMMIT' -X 'main.date=$RELEASE_DATE'" -a -o manager main.go diff --git a/Makefile b/Makefile index c108e389..5339a6e3 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +SCHEMA_CLUSTER?=${HUMIO_ENDPOINT} +SCHEMA_CLUSTER_API_TOKEN?=${HUMIO_TOKEN} # Image URL to use all building/pushing image targets IMG ?= humio/humio-operator:latest @@ -39,7 +41,12 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases hack/gen-crds.sh # NOTE: This line was custom added for the humio-operator project. +update-schema: + go run github.com/suessflorian/gqlfetch/gqlfetch@607d6757018016bba0ba7fd1cb9fed6aefa853b5 --endpoint ${SCHEMA_CLUSTER}/graphql --header "Authorization=Bearer ${SCHEMA_CLUSTER_API_TOKEN}" > internal/api/humiographql/schema/_schema.graphql + printf "# Fetched from version %s" $$(curl --silent --location '${SCHEMA_CLUSTER}/api/v1/status' | jq -r ".version") >> internal/api/humiographql/schema/_schema.graphql + generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. + go generate ./... $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." fmt: ## Run go fmt against code. diff --git a/api/v1alpha1/humioaggregatealert_types.go b/api/v1alpha1/humioaggregatealert_types.go index a86cca8f..72e2a4f2 100644 --- a/api/v1alpha1/humioaggregatealert_types.go +++ b/api/v1alpha1/humioaggregatealert_types.go @@ -60,7 +60,7 @@ type HumioAggregateAlertSpec struct { // ThrottleTimeSeconds is the throttle time in seconds. An aggregate alert is triggered at most once per the throttle time ThrottleTimeSeconds int `json:"throttleTimeSeconds,omitempty"` // ThrottleField is the field on which to throttle - ThrottleField string `json:"throttleField,omitempty"` + ThrottleField *string `json:"throttleField,omitempty"` // Aggregate Alert trigger mode TriggerMode string `json:"triggerMode,omitempty"` // Enabled will set the AggregateAlert to enabled when set to true diff --git a/api/v1alpha1/humioalert_types.go b/api/v1alpha1/humioalert_types.go index 4a17bef1..2dec50bd 100644 --- a/api/v1alpha1/humioalert_types.go +++ b/api/v1alpha1/humioalert_types.go @@ -63,6 +63,7 @@ type HumioAlertSpec struct { //+required ViewName string `json:"viewName"` // Query defines the desired state of the Humio query + //+required Query HumioQuery `json:"query"` // Description is the description of the Alert //+optional @@ -70,7 +71,7 @@ type HumioAlertSpec struct { // ThrottleTimeMillis is the throttle time in milliseconds. An Alert is triggered at most once per the throttle time ThrottleTimeMillis int `json:"throttleTimeMillis,omitempty"` // ThrottleField is the field on which to throttle - ThrottleField string `json:"throttleField,omitempty"` + ThrottleField *string `json:"throttleField,omitempty"` // Silenced will set the Alert to enabled when set to false Silenced bool `json:"silenced,omitempty"` // Actions is the list of Humio Actions by name that will be triggered by this Alert diff --git a/api/v1alpha1/humiofilteralert_types.go b/api/v1alpha1/humiofilteralert_types.go index 2a6be80e..35057ad5 100644 --- a/api/v1alpha1/humiofilteralert_types.go +++ b/api/v1alpha1/humiofilteralert_types.go @@ -54,9 +54,13 @@ type HumioFilterAlertSpec struct { //+optional Description string `json:"description,omitempty"` // ThrottleTimeSeconds is the throttle time in seconds. A filter alert is triggered at most once per the throttle time + //+kubebuilder:validation:Minimum=60 + //+required ThrottleTimeSeconds int `json:"throttleTimeSeconds,omitempty"` // ThrottleField is the field on which to throttle - ThrottleField string `json:"throttleField,omitempty"` + //+kubebuilder:validation:MinLength=1 + //+required + ThrottleField *string `json:"throttleField,omitempty"` // Enabled will set the FilterAlert to enabled when set to true Enabled bool `json:"enabled,omitempty"` // Actions is the list of Humio Actions by name that will be triggered by this filter alert diff --git a/api/v1alpha1/humioingesttoken_types.go b/api/v1alpha1/humioingesttoken_types.go index eac33094..85b03b7d 100644 --- a/api/v1alpha1/humioingesttoken_types.go +++ b/api/v1alpha1/humioingesttoken_types.go @@ -47,7 +47,7 @@ type HumioIngestTokenSpec struct { // ParserName is the name of the parser which will be assigned to the ingest token. //+kubebuilder:validation:MinLength=1 //+required - ParserName string `json:"parserName,omitempty"` + ParserName *string `json:"parserName,omitempty"` // RepositoryName is the name of the Humio repository under which the ingest token will be created //+kubebuilder:validation:MinLength=1 //+required diff --git a/api/v1alpha1/humiorepository_types.go b/api/v1alpha1/humiorepository_types.go index 83668b81..3d3fadeb 100644 --- a/api/v1alpha1/humiorepository_types.go +++ b/api/v1alpha1/humiorepository_types.go @@ -35,9 +35,15 @@ const ( type HumioRetention struct { // perhaps we should migrate to resource.Quantity? the Humio API needs float64, but that is not supported here, see more here: // https://github.com/kubernetes-sigs/controller-tools/issues/245 - IngestSizeInGB int32 `json:"ingestSizeInGB,omitempty"` - StorageSizeInGB int32 `json:"storageSizeInGB,omitempty"` - TimeInDays int32 `json:"timeInDays,omitempty"` + //+kubebuilder:validation:Minimum=1 + //+optional + IngestSizeInGB *int32 `json:"ingestSizeInGB,omitempty"` + //+kubebuilder:validation:Minimum=1 + //+optional + StorageSizeInGB *int32 `json:"storageSizeInGB,omitempty"` + //+kubebuilder:validation:Minimum=1 + //+optional + TimeInDays *int32 `json:"timeInDays,omitempty"` } // HumioRepositorySpec defines the desired state of HumioRepository diff --git a/api/v1alpha1/humioview_types.go b/api/v1alpha1/humioview_types.go index dfd31695..2e989bbc 100644 --- a/api/v1alpha1/humioview_types.go +++ b/api/v1alpha1/humioview_types.go @@ -17,7 +17,7 @@ limitations under the License. package v1alpha1 import ( - humioapi "github.com/humio/cli/api" + "github.com/humio/humio-operator/internal/api/humiographql" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -97,13 +97,14 @@ func init() { SchemeBuilder.Register(&HumioView{}, &HumioViewList{}) } -func (hv *HumioView) GetViewConnections() []humioapi.ViewConnection { - viewConnections := make([]humioapi.ViewConnection, 0) - +func (hv *HumioView) GetViewConnections() []humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection { + viewConnections := make([]humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection, 0) for _, connection := range hv.Spec.Connections { - viewConnections = append(viewConnections, humioapi.ViewConnection{ - RepoName: connection.RepositoryName, - Filter: connection.Filter, + viewConnections = append(viewConnections, humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection{ + Repository: humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository{ + Name: connection.RepositoryName, + }, + Filter: connection.Filter, }) } return viewConnections diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index d7cef1c9..140c1df8 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -398,6 +398,11 @@ func (in *HumioAggregateAlertList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioAggregateAlertSpec) DeepCopyInto(out *HumioAggregateAlertSpec) { *out = *in + if in.ThrottleField != nil { + in, out := &in.ThrottleField, &out.ThrottleField + *out = new(string) + **out = **in + } if in.Actions != nil { in, out := &in.Actions, &out.Actions *out = make([]string, len(*in)) @@ -498,6 +503,11 @@ func (in *HumioAlertList) DeepCopyObject() runtime.Object { func (in *HumioAlertSpec) DeepCopyInto(out *HumioAlertSpec) { *out = *in in.Query.DeepCopyInto(&out.Query) + if in.ThrottleField != nil { + in, out := &in.ThrottleField, &out.ThrottleField + *out = new(string) + **out = **in + } if in.Actions != nil { in, out := &in.Actions, &out.Actions *out = make([]string, len(*in)) @@ -1024,6 +1034,11 @@ func (in *HumioFilterAlertList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioFilterAlertSpec) DeepCopyInto(out *HumioFilterAlertSpec) { *out = *in + if in.ThrottleField != nil { + in, out := &in.ThrottleField, &out.ThrottleField + *out = new(string) + **out = **in + } if in.Actions != nil { in, out := &in.Actions, &out.Actions *out = make([]string, len(*in)) @@ -1203,6 +1218,11 @@ func (in *HumioIngestTokenList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioIngestTokenSpec) DeepCopyInto(out *HumioIngestTokenSpec) { *out = *in + if in.ParserName != nil { + in, out := &in.ParserName, &out.ParserName + *out = new(string) + **out = **in + } if in.TokenSecretLabels != nil { in, out := &in.TokenSecretLabels, &out.TokenSecretLabels *out = make(map[string]string, len(*in)) @@ -1711,7 +1731,7 @@ func (in *HumioRepositoryList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioRepositorySpec) DeepCopyInto(out *HumioRepositorySpec) { *out = *in - out.Retention = in.Retention + in.Retention.DeepCopyInto(&out.Retention) if in.AutomaticSearch != nil { in, out := &in.AutomaticSearch, &out.AutomaticSearch *out = new(bool) @@ -1747,6 +1767,21 @@ func (in *HumioRepositoryStatus) DeepCopy() *HumioRepositoryStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HumioRetention) DeepCopyInto(out *HumioRetention) { *out = *in + if in.IngestSizeInGB != nil { + in, out := &in.IngestSizeInGB, &out.IngestSizeInGB + *out = new(int32) + **out = **in + } + if in.StorageSizeInGB != nil { + in, out := &in.StorageSizeInGB, &out.StorageSizeInGB + *out = new(int32) + **out = **in + } + if in.TimeInDays != nil { + in, out := &in.TimeInDays, &out.TimeInDays + *out = new(int32) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HumioRetention. diff --git a/charts/humio-operator/crds/core.humio.com_humiofilteralerts.yaml b/charts/humio-operator/crds/core.humio.com_humiofilteralerts.yaml index f58442d2..36ee4e87 100644 --- a/charts/humio-operator/crds/core.humio.com_humiofilteralerts.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiofilteralerts.yaml @@ -83,10 +83,12 @@ spec: type: string throttleField: description: ThrottleField is the field on which to throttle + minLength: 1 type: string throttleTimeSeconds: description: ThrottleTimeSeconds is the throttle time in seconds. A filter alert is triggered at most once per the throttle time + minimum: 60 type: integer viewName: description: ViewName is the name of the Humio View under which the diff --git a/charts/humio-operator/crds/core.humio.com_humiorepositories.yaml b/charts/humio-operator/crds/core.humio.com_humiorepositories.yaml index 6ef145db..7c7f4374 100644 --- a/charts/humio-operator/crds/core.humio.com_humiorepositories.yaml +++ b/charts/humio-operator/crds/core.humio.com_humiorepositories.yaml @@ -87,12 +87,15 @@ spec: perhaps we should migrate to resource.Quantity? the Humio API needs float64, but that is not supported here, see more here: https://github.com/kubernetes-sigs/controller-tools/issues/245 format: int32 + minimum: 1 type: integer storageSizeInGB: format: int32 + minimum: 1 type: integer timeInDays: format: int32 + minimum: 1 type: integer type: object required: diff --git a/config/crd/bases/core.humio.com_humiofilteralerts.yaml b/config/crd/bases/core.humio.com_humiofilteralerts.yaml index f58442d2..36ee4e87 100644 --- a/config/crd/bases/core.humio.com_humiofilteralerts.yaml +++ b/config/crd/bases/core.humio.com_humiofilteralerts.yaml @@ -83,10 +83,12 @@ spec: type: string throttleField: description: ThrottleField is the field on which to throttle + minLength: 1 type: string throttleTimeSeconds: description: ThrottleTimeSeconds is the throttle time in seconds. A filter alert is triggered at most once per the throttle time + minimum: 60 type: integer viewName: description: ViewName is the name of the Humio View under which the diff --git a/config/crd/bases/core.humio.com_humiorepositories.yaml b/config/crd/bases/core.humio.com_humiorepositories.yaml index 6ef145db..7c7f4374 100644 --- a/config/crd/bases/core.humio.com_humiorepositories.yaml +++ b/config/crd/bases/core.humio.com_humiorepositories.yaml @@ -87,12 +87,15 @@ spec: perhaps we should migrate to resource.Quantity? the Humio API needs float64, but that is not supported here, see more here: https://github.com/kubernetes-sigs/controller-tools/issues/245 format: int32 + minimum: 1 type: integer storageSizeInGB: format: int32 + minimum: 1 type: integer timeInDays: format: int32 + minimum: 1 type: integer type: object required: diff --git a/controllers/humioaction_controller.go b/controllers/humioaction_controller.go index 796a6268..740524e9 100644 --- a/controllers/humioaction_controller.go +++ b/controllers/humioaction_controller.go @@ -20,15 +20,17 @@ import ( "context" "errors" "fmt" + "strings" "time" "github.com/go-logr/logr" "github.com/google/go-cmp/cmp" - humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - "github.com/humio/humio-operator/pkg/kubernetes" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -81,6 +83,7 @@ func (r *HumioActionReconciler) Reconcile(ctx context.Context, req ctrl.Request) } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) err = r.resolveSecrets(ctx, ha) if err != nil { @@ -97,7 +100,7 @@ func (r *HumioActionReconciler) Reconcile(ctx context.Context, req ctrl.Request) } defer func(ctx context.Context, humioClient humio.Client, ha *humiov1alpha1.HumioAction) { - _, err := r.HumioClient.GetAction(cluster.Config(), req, ha) + _, err := r.HumioClient.GetAction(ctx, humioHttpClient, req, ha) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioActionStateNotFound, ha) return @@ -109,31 +112,33 @@ func (r *HumioActionReconciler) Reconcile(ctx context.Context, req ctrl.Request) _ = r.setState(ctx, humiov1alpha1.HumioActionStateExists, ha) }(ctx, r.HumioClient, ha) - return r.reconcileHumioAction(ctx, cluster.Config(), ha, req) + return r.reconcileHumioAction(ctx, humioHttpClient, ha, req) } -func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, config *humioapi.Config, ha *humiov1alpha1.HumioAction, req ctrl.Request) (reconcile.Result, error) { +func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, client *humioapi.Client, ha *humiov1alpha1.HumioAction, req ctrl.Request) (reconcile.Result, error) { // Delete r.Log.Info("Checking if Action is marked to be deleted") - isMarkedForDeletion := ha.GetDeletionTimestamp() != nil - if isMarkedForDeletion { + if ha.GetDeletionTimestamp() != nil { r.Log.Info("Action marked to be deleted") if helpers.ContainsElement(ha.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetAction(ctx, client, req, ha) + if errors.As(err, &humioapi.EntityNotFound{}) { + ha.SetFinalizers(helpers.RemoveElement(ha.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, ha) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting Action") - if err := r.HumioClient.DeleteAction(config, req, ha); err != nil { + if err := r.HumioClient.DeleteAction(ctx, client, req, ha); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete Action returned error") } - - r.Log.Info("Action Deleted. Removing finalizer") - ha.SetFinalizers(helpers.RemoveElement(ha.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, ha) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -153,17 +158,19 @@ func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, config r.Log.Info("Checking if action needs to be created") // Add Action - curAction, err := r.HumioClient.GetAction(config, req, ha) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("Action doesn't exist. Now adding action") - addedAction, err := r.HumioClient.AddAction(config, req, ha) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create action") - } - r.Log.Info("Created action", "Action", ha.Spec.Name, "ID", addedAction.ID) - return reconcile.Result{Requeue: true}, nil - } + curAction, err := r.HumioClient.GetAction(ctx, client, req, ha) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("Action doesn't exist. Now adding action") + addErr := r.HumioClient.AddAction(ctx, client, req, ha) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create action") + } + r.Log.Info("Created action", + "Action", ha.Spec.Name, + ) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if action exists") } @@ -173,17 +180,18 @@ func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, config if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not parse expected action") } - sanitizeAction(curAction) - sanitizeAction(expectedAction) - if !cmp.Equal(*curAction, *expectedAction) { - r.Log.Info("Action differs, triggering update", "actionDiff", cmp.Diff(*curAction, *expectedAction)) - action, err := r.HumioClient.UpdateAction(config, req, ha) + + if asExpected, diff := actionAlreadyAsExpected(expectedAction, curAction); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + err = r.HumioClient.UpdateAction(ctx, client, req, ha) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not update action") } - if action != nil { - r.Log.Info(fmt.Sprintf("Updated action %q", ha.Spec.Name), "newAction", fmt.Sprintf("%#+v", action)) - } + r.Log.Info("Updated action", + "Action", ha.Spec.Name, + ) } r.Log.Info("done reconciling, will requeue after 15 seconds") @@ -307,6 +315,167 @@ func (r *HumioActionReconciler) logErrorAndReturn(err error, msg string) error { return fmt.Errorf("%s: %w", msg, err) } -func sanitizeAction(action *humioapi.Action) { - action.ID = "" +// actionAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func actionAlreadyAsExpected(expectedAction humiographql.ActionDetails, currentAction humiographql.ActionDetails) (bool, string) { + var diffs []string + + switch e := (expectedAction).(type) { + case *humiographql.ActionDetailsEmailAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsEmailAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetRecipients(), e.GetRecipients()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.recipients=%q", e, diff)) + } + if diff := cmp.Diff(c.GetSubjectTemplate(), e.GetSubjectTemplate()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.subjectTemplate()=%q", e, diff)) + } + if diff := cmp.Diff(c.GetEmailBodyTemplate(), e.GetEmailBodyTemplate()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.bodyTemplate=%q", e, diff)) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsHumioRepoAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsHumioRepoAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetIngestToken(), e.GetIngestToken()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.ingestToken=%q", e, "")) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsOpsGenieAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsOpsGenieAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetApiUrl(), e.GetApiUrl()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.apiUrl=%q", e, diff)) + } + if diff := cmp.Diff(c.GetGenieKey(), e.GetGenieKey()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.genieKey=%q", e, "")) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsPagerDutyAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsPagerDutyAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetRoutingKey(), e.GetRoutingKey()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.apiUrl=%q", e, "")) + } + if diff := cmp.Diff(c.GetSeverity(), e.GetSeverity()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.genieKey=%q", e, diff)) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsSlackAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsSlackAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetFields(), e.GetFields()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.fields=%q", e, diff)) + } + if diff := cmp.Diff(c.GetUrl(), e.GetUrl()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.url=%q", e, "")) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsSlackPostMessageAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsSlackPostMessageAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetApiToken(), e.GetApiToken()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.apiToken=%q", e, "")) + } + if diff := cmp.Diff(c.GetChannels(), e.GetChannels()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.channels=%q", e, diff)) + } + if diff := cmp.Diff(c.GetFields(), e.GetFields()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.fields=%q", e, diff)) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsVictorOpsAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsVictorOpsAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetMessageType(), e.GetMessageType()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.messageType=%q", e, diff)) + } + if diff := cmp.Diff(c.GetNotifyUrl(), e.GetNotifyUrl()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.notifyUrl=%q", e, "")) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + case *humiographql.ActionDetailsWebhookAction: + switch c := (currentAction).(type) { + case *humiographql.ActionDetailsWebhookAction: + if diff := cmp.Diff(c.GetName(), e.GetName()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.name=%q", e, diff)) + } + if diff := cmp.Diff(c.GetWebhookBodyTemplate(), e.GetWebhookBodyTemplate()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.bodyTemplate=%q", e, diff)) + } + if diff := cmp.Diff(c.GetHeaders(), e.GetHeaders()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.headers=%q", e, "")) + } + if diff := cmp.Diff(c.GetMethod(), e.GetMethod()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.method=%q", e, diff)) + } + if diff := cmp.Diff(c.GetUrl(), e.GetUrl()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.url=%q", e, "")) + } + if diff := cmp.Diff(c.GetIgnoreSSL(), e.GetIgnoreSSL()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.ignoreSSL=%q", e, diff)) + } + if diff := cmp.Diff(c.GetUseProxy(), e.GetUseProxy()); diff != "" { + diffs = append(diffs, fmt.Sprintf("%T.useProxy=%q", e, diff)) + } + default: + diffs = append(diffs, fmt.Sprintf("expected type %T but current is %T", e, c)) + } + } + + return len(diffs) == 0, strings.Join(diffs, ", ") } diff --git a/controllers/humioaggregatealert_controller.go b/controllers/humioaggregatealert_controller.go index d654fe21..94cc6b8a 100644 --- a/controllers/humioaggregatealert_controller.go +++ b/controllers/humioaggregatealert_controller.go @@ -20,20 +20,23 @@ import ( "context" "errors" "fmt" - "reflect" + "sort" + "strings" "time" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/go-logr/logr" - humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - "github.com/humio/humio-operator/pkg/kubernetes" ) // HumioAggregateAlertReconciler reconciles a HumioAggregateAlert object @@ -57,7 +60,7 @@ func (r *HumioAggregateAlertReconciler) Reconcile(ctx context.Context, req ctrl. } r.Log = r.BaseLogger.WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name, "Request.Type", helpers.GetTypeName(r), "Reconcile.ID", kubernetes.RandomString()) - r.Log.Info("Reconciling HummioAggregateAlert") + r.Log.Info("Reconciling HumioAggregateAlert") haa := &humiov1alpha1.HumioAggregateAlert{} err := r.Get(ctx, req.NamespacedName, haa) @@ -82,9 +85,10 @@ func (r *HumioAggregateAlertReconciler) Reconcile(ctx context.Context, req ctrl. } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) defer func(ctx context.Context, HumioClient humio.Client, haa *humiov1alpha1.HumioAggregateAlert) { - curAggregateAlert, err := r.HumioClient.GetAggregateAlert(cluster.Config(), req, haa) + curAggregateAlert, err := r.HumioClient.GetAggregateAlert(ctx, humioHttpClient, req, haa) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioAggregateAlertStateNotFound, haa) return @@ -96,31 +100,34 @@ func (r *HumioAggregateAlertReconciler) Reconcile(ctx context.Context, req ctrl. _ = r.setState(ctx, humiov1alpha1.HumioAggregateAlertStateExists, haa) }(ctx, r.HumioClient, haa) - return r.reconcileHumioAggregateAlert(ctx, cluster.Config(), haa, req) + return r.reconcileHumioAggregateAlert(ctx, humioHttpClient, haa, req) } -func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlert(ctx context.Context, config *humioapi.Config, haa *humiov1alpha1.HumioAggregateAlert, req ctrl.Request) (reconcile.Result, error) { +func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlert(ctx context.Context, client *humioapi.Client, haa *humiov1alpha1.HumioAggregateAlert, req ctrl.Request) (reconcile.Result, error) { // Delete r.Log.Info("Checking if alert is marked to be deleted") isMarkedForDeletion := haa.GetDeletionTimestamp() != nil if isMarkedForDeletion { r.Log.Info("AggregateAlert marked to be deleted") if helpers.ContainsElement(haa.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetAggregateAlert(ctx, client, req, haa) + if errors.As(err, &humioapi.EntityNotFound{}) { + haa.SetFinalizers(helpers.RemoveElement(haa.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, haa) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting aggregate alert") - if err := r.HumioClient.DeleteAggregateAlert(config, req, haa); err != nil { + if err := r.HumioClient.DeleteAggregateAlert(ctx, client, req, haa); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete aggregate alert returned error") } - - r.Log.Info("AggregateAlert Deleted. Removing finalizer") - haa.SetFinalizers(helpers.RemoveElement(haa.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, haa) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -149,38 +156,39 @@ func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlert(ctx context r.Log.Info("Checking if aggregate alert needs to be created") // Add Alert - curAggregateAlert, err := r.HumioClient.GetAggregateAlert(config, req, haa) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("AggregateAlert doesn't exist. Now adding aggregate alert") - addedAggregateAlert, err := r.HumioClient.AddAggregateAlert(config, req, haa) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create aggregate alert") - } - r.Log.Info("Created aggregate alert", "AggregateAlert", haa.Spec.Name, "ID", addedAggregateAlert.ID) - return reconcile.Result{Requeue: true}, nil - } + curAggregateAlert, err := r.HumioClient.GetAggregateAlert(ctx, client, req, haa) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("AggregateAlert doesn't exist. Now adding aggregate alert") + addErr := r.HumioClient.AddAggregateAlert(ctx, client, req, haa) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create aggregate alert") + } + r.Log.Info("Created aggregate alert", + "AggregateAlert", haa.Spec.Name, + ) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if aggregate alert exists") } r.Log.Info("Checking if aggregate alert needs to be updated") // Update - if err := r.HumioClient.ValidateActionsForAggregateAlert(config, req, haa); err != nil { + if err := r.HumioClient.ValidateActionsForAggregateAlert(ctx, client, req, haa); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not validate actions for aggregate alert") } - expectedAggregateAlert := humio.AggregateAlertTransform(haa) - sanitizeAggregateAlert(curAggregateAlert) - if !reflect.DeepEqual(*curAggregateAlert, *expectedAggregateAlert) { - r.Log.Info(fmt.Sprintf("AggregateAlert differs, triggering update, expected %#v, got: %#v", - expectedAggregateAlert, - curAggregateAlert)) - AggregateAlert, err := r.HumioClient.UpdateAggregateAlert(config, req, haa) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not update aggregate alert") - } - if AggregateAlert != nil { - r.Log.Info(fmt.Sprintf("Updated Aggregate Alert %q", AggregateAlert.Name)) + + if asExpected, diff := aggregateAlertAlreadyAsExpected(haa, curAggregateAlert); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + updateErr := r.HumioClient.UpdateAggregateAlert(ctx, client, req, haa) + if updateErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(updateErr, "could not update aggregate alert") } + r.Log.Info("Updated Aggregate Alert", + "AggregateAlert", haa.Spec.Name, + ) } r.Log.Info("done reconciling, will requeue in 15 seconds") @@ -209,6 +217,51 @@ func (r *HumioAggregateAlertReconciler) logErrorAndReturn(err error, msg string) return fmt.Errorf("%s: %w", msg, err) } -func sanitizeAggregateAlert(aggregateAlert *humioapi.AggregateAlert) { - aggregateAlert.RunAsUserID = "" +// aggregateAlertAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func aggregateAlertAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioAggregateAlert, fromGraphQL *humiographql.AggregateAlertDetails) (bool, string) { + var diffs []string + + if diff := cmp.Diff(fromGraphQL.GetDescription(), &fromKubernetesCustomResource.Spec.Description); diff != "" { + diffs = append(diffs, fmt.Sprintf("description=%q", diff)) + } + labelsFromGraphQL := fromGraphQL.GetLabels() + sort.Strings(labelsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Labels) + if diff := cmp.Diff(labelsFromGraphQL, fromKubernetesCustomResource.Spec.Labels); diff != "" { + diffs = append(diffs, fmt.Sprintf("labels=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetThrottleField(), fromKubernetesCustomResource.Spec.ThrottleField); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleField=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetThrottleTimeSeconds(), fromKubernetesCustomResource.Spec.ThrottleTimeSeconds); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleTimeSeconds=%q", diff)) + } + actionsFromGraphQL := humioapi.GetActionNames(fromGraphQL.GetActions()) + sort.Strings(actionsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Actions) + if diff := cmp.Diff(actionsFromGraphQL, fromKubernetesCustomResource.Spec.Actions); diff != "" { + diffs = append(diffs, fmt.Sprintf("actions=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetQueryTimestampType(), humiographql.QueryTimestampType(fromKubernetesCustomResource.Spec.QueryTimestampType)); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryTimestampType=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetQueryString(), fromKubernetesCustomResource.Spec.QueryString); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryString=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetTriggerMode(), humiographql.TriggerMode(fromKubernetesCustomResource.Spec.TriggerMode)); diff != "" { + diffs = append(diffs, fmt.Sprintf("triggerMode=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetSearchIntervalSeconds(), int64(fromKubernetesCustomResource.Spec.SearchIntervalSeconds)); diff != "" { + diffs = append(diffs, fmt.Sprintf("searchIntervalSeconds=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetEnabled(), fromKubernetesCustomResource.Spec.Enabled); diff != "" { + diffs = append(diffs, fmt.Sprintf("enabled=%q", diff)) + } + if !humioapi.QueryOwnershipIsOrganizationOwnership(fromGraphQL.GetQueryOwnership()) { + diffs = append(diffs, fmt.Sprintf("queryOwnership=%+v", fromGraphQL.GetQueryOwnership())) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") } diff --git a/controllers/humioalert_controller.go b/controllers/humioalert_controller.go index 1eded9bf..aeb98d5d 100644 --- a/controllers/humioalert_controller.go +++ b/controllers/humioalert_controller.go @@ -20,14 +20,16 @@ import ( "context" "errors" "fmt" - "reflect" + "sort" + "strings" "time" - "github.com/humio/humio-operator/pkg/kubernetes" - - humioapi "github.com/humio/cli/api" - - "github.com/humio/humio-operator/pkg/helpers" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/go-logr/logr" @@ -36,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) // HumioAlertReconciler reconciles a HumioAlert object @@ -85,9 +86,10 @@ func (r *HumioAlertReconciler) Reconcile(ctx context.Context, req ctrl.Request) } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) defer func(ctx context.Context, humioClient humio.Client, ha *humiov1alpha1.HumioAlert) { - _, err := r.HumioClient.GetAlert(cluster.Config(), req, ha) + _, err := r.HumioClient.GetAlert(ctx, humioHttpClient, req, ha) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioAlertStateNotFound, ha) return @@ -99,31 +101,33 @@ func (r *HumioAlertReconciler) Reconcile(ctx context.Context, req ctrl.Request) _ = r.setState(ctx, humiov1alpha1.HumioAlertStateExists, ha) }(ctx, r.HumioClient, ha) - return r.reconcileHumioAlert(ctx, cluster.Config(), ha, req) + return r.reconcileHumioAlert(ctx, humioHttpClient, ha, req) } -func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, config *humioapi.Config, ha *humiov1alpha1.HumioAlert, req ctrl.Request) (reconcile.Result, error) { +func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, client *humioapi.Client, ha *humiov1alpha1.HumioAlert, req ctrl.Request) (reconcile.Result, error) { // Delete r.Log.Info("Checking if alert is marked to be deleted") - isMarkedForDeletion := ha.GetDeletionTimestamp() != nil - if isMarkedForDeletion { + if ha.GetDeletionTimestamp() != nil { r.Log.Info("Alert marked to be deleted") if helpers.ContainsElement(ha.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetAlert(ctx, client, req, ha) + if errors.As(err, &humioapi.EntityNotFound{}) { + ha.SetFinalizers(helpers.RemoveElement(ha.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, ha) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting alert") - if err := r.HumioClient.DeleteAlert(config, req, ha); err != nil { + if err := r.HumioClient.DeleteAlert(ctx, client, req, ha); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete alert returned error") } - - r.Log.Info("Alert Deleted. Removing finalizer") - ha.SetFinalizers(helpers.RemoveElement(ha.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, ha) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -143,39 +147,35 @@ func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, config * r.Log.Info("Checking if alert needs to be created") // Add Alert - curAlert, err := r.HumioClient.GetAlert(config, req, ha) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("Alert doesn't exist. Now adding alert") - addedAlert, err := r.HumioClient.AddAlert(config, req, ha) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create alert") - } - r.Log.Info("Created alert", "Alert", ha.Spec.Name, "ID", addedAlert.ID) - return reconcile.Result{Requeue: true}, nil - } + curAlert, err := r.HumioClient.GetAlert(ctx, client, req, ha) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("Alert doesn't exist. Now adding alert") + addErr := r.HumioClient.AddAlert(ctx, client, req, ha) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create alert") + } + r.Log.Info("Created alert", + "Alert", ha.Spec.Name, + ) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if alert exists") } r.Log.Info("Checking if alert needs to be updated") - // Update - actionIdMap, err := r.HumioClient.GetActionIDsMapForAlerts(config, req, ha) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not get action id mapping") - } - expectedAlert := humio.AlertTransform(ha, actionIdMap) - sanitizeAlert(curAlert) - if !reflect.DeepEqual(*curAlert, *expectedAlert) { - r.Log.Info(fmt.Sprintf("Alert differs, triggering update, expected %#v, got: %#v", - expectedAlert, - curAlert)) - alert, err := r.HumioClient.UpdateAlert(config, req, ha) + + if asExpected, diff := alertAlreadyAsExpected(ha, curAlert); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + err = r.HumioClient.UpdateAlert(ctx, client, req, ha) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not update alert") } - if alert != nil { - r.Log.Info(fmt.Sprintf("Updated alert %q", alert.Name)) - } + r.Log.Info("Updated Alert", + "Alert", ha.Spec.Name, + ) } r.Log.Info("done reconciling, will requeue after 15 seconds") @@ -203,10 +203,45 @@ func (r *HumioAlertReconciler) logErrorAndReturn(err error, msg string) error { return fmt.Errorf("%s: %w", msg, err) } -func sanitizeAlert(alert *humioapi.Alert) { - alert.TimeOfLastTrigger = 0 - alert.ID = "" - alert.RunAsUserID = "" - alert.QueryOwnershipType = "" - alert.LastError = "" +// alertAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func alertAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioAlert, fromGraphQL *humiographql.AlertDetails) (bool, string) { + var diffs []string + + if diff := cmp.Diff(fromGraphQL.GetDescription(), &fromKubernetesCustomResource.Spec.Description); diff != "" { + diffs = append(diffs, fmt.Sprintf("description=%q", diff)) + } + labelsFromGraphQL := fromGraphQL.GetLabels() + sort.Strings(labelsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Labels) + if diff := cmp.Diff(labelsFromGraphQL, fromKubernetesCustomResource.Spec.Labels); diff != "" { + diffs = append(diffs, fmt.Sprintf("labels=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetThrottleField(), fromKubernetesCustomResource.Spec.ThrottleField); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleField=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetThrottleTimeMillis(), int64(fromKubernetesCustomResource.Spec.ThrottleTimeMillis)); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleTimeMillis=%q", diff)) + } + actionsFromGraphQL := humioapi.GetActionNames(fromGraphQL.GetActionsV2()) + sort.Strings(actionsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Actions) + if diff := cmp.Diff(actionsFromGraphQL, fromKubernetesCustomResource.Spec.Actions); diff != "" { + diffs = append(diffs, fmt.Sprintf("actions=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetQueryString(), fromKubernetesCustomResource.Spec.Query.QueryString); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryString=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetQueryStart(), fromKubernetesCustomResource.Spec.Query.Start); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryString=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetEnabled(), !fromKubernetesCustomResource.Spec.Silenced); diff != "" { + diffs = append(diffs, fmt.Sprintf("enabled=%q", diff)) + } + if !humioapi.QueryOwnershipIsOrganizationOwnership(fromGraphQL.GetQueryOwnership()) { + diffs = append(diffs, fmt.Sprintf("queryOwnership=%+v", fromGraphQL.GetQueryOwnership())) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") } diff --git a/controllers/humiobootstraptoken_controller.go b/controllers/humiobootstraptoken_controller.go index 39c4b7b5..24dddb92 100644 --- a/controllers/humiobootstraptoken_controller.go +++ b/controllers/humiobootstraptoken_controller.go @@ -22,6 +22,8 @@ import ( "strings" "time" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/clientcmd" @@ -32,8 +34,6 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -146,7 +146,7 @@ func (r *HumioBootstrapTokenReconciler) updateStatus(ctx context.Context, hbt *h return r.Client.Status().Update(ctx, hbt) } -func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []string) (string, error) { +func (r *HumioBootstrapTokenReconciler) execCommand(ctx context.Context, pod *corev1.Pod, args []string) (string, error) { configLoader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( clientcmd.NewDefaultClientConfigLoadingRules(), &clientcmd.ConfigOverrides{}, @@ -188,7 +188,7 @@ func (r *HumioBootstrapTokenReconciler) execCommand(pod *corev1.Pod, args []stri return "", err } var stdout, stderr bytes.Buffer - err = exec.StreamWithContext(context.TODO(), remotecommand.StreamOptions{ + err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{ Stdin: nil, Stdout: &stdout, Stderr: &stderr, @@ -353,7 +353,7 @@ func (r *HumioBootstrapTokenReconciler) ensureBootstrapTokenHashedToken(ctx cont } r.Log.Info("execing onetime pod") - output, err := r.execCommand(&foundPod, commandArgs) + output, err := r.execCommand(ctx, &foundPod, commandArgs) if err != nil { return r.logErrorAndReturn(err, "failed to exec pod") } diff --git a/controllers/humiobootstraptoken_pods.go b/controllers/humiobootstraptoken_pods.go index 3e69af9f..f461f632 100644 --- a/controllers/humiobootstraptoken_pods.go +++ b/controllers/humiobootstraptoken_pods.go @@ -1,7 +1,7 @@ package controllers import ( - "github.com/humio/humio-operator/pkg/helpers" + "github.com/humio/humio-operator/internal/helpers" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 2f33d3b6..54b68021 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -18,15 +18,18 @@ package controllers import ( "context" + "errors" "fmt" "reflect" "strings" "time" cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - humioapi "github.com/humio/cli/api" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -36,7 +39,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/go-logr/logr" - "github.com/humio/humio-operator/pkg/humio" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -284,12 +286,13 @@ func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request withMessage(r.logErrorAndReturn(err, "unable to obtain humio client config").Error()). withState(humiov1alpha1.HumioClusterStateConfigError)) } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) // update status with version defer func(ctx context.Context, humioClient humio.Client, hc *humiov1alpha1.HumioCluster) { opts := statusOptions() if hc.Status.State == humiov1alpha1.HumioClusterStateRunning { - status, err := humioClient.Status(cluster.Config(), req) + status, err := humioClient.Status(ctx, humioHttpClient, req) if err != nil { r.Log.Error(err, "unable to get cluster status") return @@ -915,8 +918,8 @@ func (r *HumioClusterReconciler) ensureValidCASecret(ctx context.Context, hc *hu r.Log.Info("persisting new CA certificate") caSecretData := map[string][]byte{ - "tls.crt": ca.Certificate, - "tls.key": ca.Key, + corev1.TLSCertKey: ca.Certificate, + corev1.TLSPrivateKeyKey: ca.Key, } caSecret := kubernetes.ConstructSecret(hc.Name, hc.Namespace, getCASecretName(hc), caSecretData, nil) if err := controllerutil.SetControllerReference(hc, caSecret, r.Scheme()); err != nil { @@ -1261,7 +1264,7 @@ func (r *HumioClusterReconciler) ensureLicenseIsValid(ctx context.Context, hc *h } licenseStr := string(licenseSecret.Data[licenseSecretKeySelector.Key]) - if _, err = humio.ParseLicense(licenseStr); err != nil { + if _, err = humio.GetLicenseUIDFromLicenseString(licenseStr); err != nil { return r.logErrorAndReturn(err, "unable to parse license") } @@ -1273,30 +1276,13 @@ func (r *HumioClusterReconciler) ensureLicenseAndAdminToken(ctx context.Context, r.Log.Info("ensuring license and admin token") // Configure a Humio client without an API token which we can use to check the current license on the cluster - noLicense := humioapi.OnPremLicense{} cluster, err := helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, false) if err != nil { return reconcile.Result{}, err } + clientWithoutAPIToken := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) - existingLicense, err := r.HumioClient.GetLicense(cluster.Config(), req) - if err != nil { - return ctrl.Result{}, fmt.Errorf("failed to get license: %w", err) - } - - // update status with license details - defer func(ctx context.Context, hc *humiov1alpha1.HumioCluster) { - if existingLicense != nil { - licenseStatus := humiov1alpha1.HumioLicenseStatus{ - Type: "onprem", - Expiration: existingLicense.ExpiresAt(), - } - _, _ = r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). - withLicense(licenseStatus)) - } - }(ctx, hc) - - licenseStr, err := r.getLicenseString(ctx, hc) + desiredLicenseString, err := r.getDesiredLicenseString(ctx, hc) if err != nil { _, _ = r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). withMessage(err.Error()). @@ -1305,66 +1291,74 @@ func (r *HumioClusterReconciler) ensureLicenseAndAdminToken(ctx context.Context, } // Confirm we can parse the license provided in the HumioCluster resource - desiredLicense, err := humio.ParseLicense(licenseStr) + desiredLicenseUID, err := humio.GetLicenseUIDFromLicenseString(desiredLicenseString) if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "license was supplied but could not be parsed") + _, _ = r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). + withMessage(err.Error()). + withState(humiov1alpha1.HumioClusterStateConfigError)) + return reconcile.Result{}, err } - // At this point we know a non-empty license has been returned by the Humio API, - // so we can continue to parse the license and issue a license update if needed. - if existingLicense == nil || existingLicense == noLicense { - cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, false) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not install initial license") - } + // Fetch details on currently installed license + licenseUID, licenseExpiry, getErr := r.HumioClient.GetLicenseUIDAndExpiry(ctx, clientWithoutAPIToken, req) + // Install initial license + if getErr != nil { + if errors.As(getErr, &humioapi.EntityNotFound{}) { + if installErr := r.HumioClient.InstallLicense(ctx, clientWithoutAPIToken, req, desiredLicenseString); installErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(installErr, "could not install initial license") + } - if err = r.HumioClient.InstallLicense(cluster.Config(), req, licenseStr); err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not install initial license") + r.Log.Info(fmt.Sprintf("successfully installed initial license: uid=%s expires=%s", + licenseUID, licenseExpiry.String())) + return reconcile.Result{Requeue: true}, nil } - - r.Log.Info(fmt.Sprintf("successfully installed initial license: issued: %s, expires: %s", - desiredLicense.IssuedAt(), desiredLicense.ExpiresAt())) - return reconcile.Result{Requeue: true}, nil + return ctrl.Result{}, fmt.Errorf("failed to get license: %w", getErr) } + // update status with license details + defer func(ctx context.Context, hc *humiov1alpha1.HumioCluster) { + if licenseUID != "" { + licenseStatus := humiov1alpha1.HumioLicenseStatus{ + Type: "onprem", + Expiration: licenseExpiry.String(), + } + _, _ = r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). + withLicense(licenseStatus)) + } + }(ctx, hc) + cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), false, true) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not authenticate with bootstrap token") } + clientWithBootstrapToken := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) - if err = r.ensurePersonalAPITokenForAdminUser(ctx, cluster.Config(), req, hc); err != nil { + if err = r.ensurePersonalAPITokenForAdminUser(ctx, clientWithBootstrapToken, req, hc); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "unable to create permission tokens") } + // Configure a Humio client with an API token which we can use to check the current license on the cluster cluster, err = helpers.NewCluster(ctx, r, hc.Name, "", hc.Namespace, helpers.UseCertManager(), true, false) if err != nil { return reconcile.Result{}, err } + clientWithPersonalAPIToken := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) - if existingLicense.IssuedAt() != desiredLicense.IssuedAt() || - existingLicense.ExpiresAt() != desiredLicense.ExpiresAt() { - r.Log.Info(fmt.Sprintf("updating license because of: existingLicense.IssuedAt(%s) != desiredLicense.IssuedAt(%s) || existingLicense.ExpiresAt(%s) != desiredLicense.ExpiresAt(%s)", existingLicense.IssuedAt(), desiredLicense.IssuedAt(), existingLicense.ExpiresAt(), desiredLicense.ExpiresAt())) - if err = r.HumioClient.InstallLicense(cluster.Config(), req, licenseStr); err != nil { + if licenseUID != desiredLicenseUID { + r.Log.Info(fmt.Sprintf("updating license because of: licenseUID(%s) != desiredLicenseUID(%s)", licenseUID, desiredLicenseUID)) + if err = r.HumioClient.InstallLicense(ctx, clientWithPersonalAPIToken, req, desiredLicenseString); err != nil { return reconcile.Result{}, fmt.Errorf("could not install license: %w", err) } - - r.Log.Info(fmt.Sprintf("successfully installed license: issued: %s, expires: %s", - desiredLicense.IssuedAt(), desiredLicense.ExpiresAt())) - - // refresh the existing license for the status update - existingLicense, err = r.HumioClient.GetLicense(cluster.Config(), req) - if err != nil { - r.Log.Error(err, "failed to get updated license: %w", err) - } - return reconcile.Result{}, nil + r.Log.Info(fmt.Sprintf("successfully installed license: uid=%s", desiredLicenseUID)) + return reconcile.Result{Requeue: true}, nil } return reconcile.Result{}, nil } -func (r *HumioClusterReconciler) ensurePersonalAPITokenForAdminUser(ctx context.Context, config *humioapi.Config, req reconcile.Request, hc *humiov1alpha1.HumioCluster) error { +func (r *HumioClusterReconciler) ensurePersonalAPITokenForAdminUser(ctx context.Context, client *humioapi.Client, req reconcile.Request, hc *humiov1alpha1.HumioCluster) error { r.Log.Info("ensuring permission tokens") - return r.createPersonalAPIToken(ctx, config, req, hc, "admin", "RecoveryRootOrg") + return r.createPersonalAPIToken(ctx, client, req, hc, "admin") } func (r *HumioClusterReconciler) ensureService(ctx context.Context, hc *humiov1alpha1.HumioCluster, hnp *HumioNodePool) error { @@ -2029,8 +2023,11 @@ func (r *HumioClusterReconciler) ingressesMatch(ingress *networkingv1.Ingress, d } } - if !reflect.DeepEqual(ingress.Spec, desiredIngress.Spec) { - r.Log.Info(fmt.Sprintf("ingress specs do not match: got %+v, wanted %+v", ingress.Spec, desiredIngress.Spec)) + ingressDiff := cmp.Diff(ingress.Spec, desiredIngress.Spec) + if ingressDiff != "" { + r.Log.Info("ingress specs do not match", + "diff", ingressDiff, + ) return false } @@ -2164,7 +2161,7 @@ func (r *HumioClusterReconciler) pvcList(ctx context.Context, hnp *HumioNodePool return pvcList, nil } -func (r *HumioClusterReconciler) getLicenseString(ctx context.Context, hc *humiov1alpha1.HumioCluster) (string, error) { +func (r *HumioClusterReconciler) getDesiredLicenseString(ctx context.Context, hc *humiov1alpha1.HumioCluster) (string, error) { licenseSecretKeySelector := licenseSecretKeyRefOrDefault(hc) if licenseSecretKeySelector == nil { return "", fmt.Errorf("no license secret key selector provided") diff --git a/controllers/humiocluster_defaults.go b/controllers/humiocluster_defaults.go index df5bafc6..e72171f6 100644 --- a/controllers/humiocluster_defaults.go +++ b/controllers/humiocluster_defaults.go @@ -22,14 +22,12 @@ import ( "strconv" "strings" - "github.com/humio/humio-operator/pkg/kubernetes" - + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/humio/humio-operator/controllers/versions" - "github.com/humio/humio-operator/pkg/helpers" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" + "github.com/humio/humio-operator/controllers/versions" corev1 "k8s.io/api/core/v1" ) @@ -495,17 +493,6 @@ func (hnp *HumioNodePool) GetCommonClusterLabels() map[string]string { return kubernetes.LabelsForHumio(hnp.clusterName) } -func (hnp *HumioNodePool) GetCASecretName() string { - if hnp.tls != nil && hnp.tls.CASecretName != "" { - return hnp.tls.CASecretName - } - return fmt.Sprintf("%s-ca-keypair", hnp.GetClusterName()) -} - -func (hnp *HumioNodePool) UseExistingCA() bool { - return hnp.tls != nil && hnp.tls.CASecretName != "" -} - func (hnp *HumioNodePool) GetLabelsForSecret(secretName string) map[string]string { labels := hnp.GetCommonClusterLabels() labels[kubernetes.SecretNameLabelName] = secretName diff --git a/controllers/humiocluster_defaults_test.go b/controllers/humiocluster_defaults_test.go index 3e47abe0..d7fe53dc 100644 --- a/controllers/humiocluster_defaults_test.go +++ b/controllers/humiocluster_defaults_test.go @@ -21,8 +21,8 @@ import ( "testing" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" diff --git a/controllers/humiocluster_ingresses.go b/controllers/humiocluster_ingresses.go index d055be26..18406a7a 100644 --- a/controllers/humiocluster_ingresses.go +++ b/controllers/humiocluster_ingresses.go @@ -19,10 +19,9 @@ package controllers import ( "fmt" - "github.com/humio/humio-operator/pkg/helpers" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -133,7 +132,7 @@ func ConstructESIngestIngress(hc *humiov1alpha1.HumioCluster, esHostname string) ) } -func constructIngress(hc *humiov1alpha1.HumioCluster, name string, hostname string, paths []string, port int, secretName string, annotations map[string]string) *networkingv1.Ingress { +func constructIngress(hc *humiov1alpha1.HumioCluster, name string, hostname string, paths []string, port int32, secretName string, annotations map[string]string) *networkingv1.Ingress { var httpIngressPaths []networkingv1.HTTPIngressPath pathTypeImplementationSpecific := networkingv1.PathTypeImplementationSpecific for _, path := range paths { @@ -144,7 +143,7 @@ func constructIngress(hc *humiov1alpha1.HumioCluster, name string, hostname stri Service: &networkingv1.IngressServiceBackend{ Name: (*ConstructService(NewHumioNodeManagerFromHumioCluster(hc))).Name, Port: networkingv1.ServiceBackendPort{ - Number: int32(port), + Number: port, }, }, }, diff --git a/controllers/humiocluster_permission_tokens.go b/controllers/humiocluster_permission_tokens.go index ffd6f19b..4af5d571 100644 --- a/controllers/humiocluster_permission_tokens.go +++ b/controllers/humiocluster_permission_tokens.go @@ -2,11 +2,12 @@ package controllers import ( "context" + "errors" "fmt" - "github.com/humio/humio-operator/pkg/helpers" - - "github.com/humio/humio-operator/pkg/kubernetes" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -16,55 +17,31 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" - humioapi "github.com/humio/cli/api" corev1 "k8s.io/api/core/v1" ) -// extractExistingHumioAdminUserID finds the user ID of the Humio user for the admin account, and returns -// empty string and no error if the user doesn't exist -func (r *HumioClusterReconciler) extractExistingHumioAdminUserID(config *humioapi.Config, req reconcile.Request, username string) (string, error) { - allUsers, err := r.HumioClient.ListAllHumioUsersInCurrentOrganization(config, req) - if err != nil { - // unable to list all users - return "", err - } - for _, user := range allUsers { - if user.Username == username { - return user.Id, nil - } - } - - return "", nil -} - // createAndGetAdminAccountUserID ensures a Humio admin account exists and returns the user ID for it -func (r *HumioClusterReconciler) createAndGetAdminAccountUserID(config *humioapi.Config, req reconcile.Request, username string) (string, error) { +func (r *HumioClusterReconciler) createAndGetAdminAccountUserID(ctx context.Context, client *humioapi.Client, req reconcile.Request, username string) (string, error) { // List all users and grab the user ID for an existing user - userID, err := r.extractExistingHumioAdminUserID(config, req, username) + currentUserID, err := r.HumioClient.GetUserIDForUsername(ctx, client, req, username) if err != nil { - // Error while grabbing the user ID + if errors.As(err, &humioapi.EntityNotFound{}) { + // If we didn't find a user ID, create a user, extract the user ID and return it + newUserID, err := r.HumioClient.AddUserAndGetUserID(ctx, client, req, username, true) + if err != nil { + return "", err + } + if newUserID != "" { + return newUserID, nil + } + } + // Error while grabbing the user return "", err } - if userID != "" { - // If we found a user ID, return it - return userID, nil - } - // If we didn't find a user ID, create a user, extract the user ID and return it - user, err := r.HumioClient.AddUser(config, req, username, true) - if err != nil { - return "", err - } - userID, err = r.extractExistingHumioAdminUserID(config, req, username) - if err != nil { - return "", err - } - if userID != "" { + if currentUserID != "" { // If we found a user ID, return it - return userID, nil - } - if userID != user.ID { - return "", fmt.Errorf("unexpected error. userid %s does not match %s", userID, user.ID) + return currentUserID, nil } // Return error if we didn't find a valid user ID @@ -100,7 +77,8 @@ func (r *HumioClusterReconciler) validateAdminSecretContent(ctx context.Context, } } - _, err = r.HumioClient.GetClusters(cluster.Config(), req) + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) + _, err = r.HumioClient.GetClusters(ctx, humioHttpClient, req) if err != nil { return fmt.Errorf("got err while trying to use apiToken: %w", err) } @@ -154,11 +132,11 @@ func (r *HumioClusterReconciler) ensureAdminSecretContent(ctx context.Context, h return nil } -func (r *HumioClusterReconciler) createPersonalAPIToken(ctx context.Context, config *humioapi.Config, req reconcile.Request, hc *v1alpha1.HumioCluster, username string, organization string) error { +func (r *HumioClusterReconciler) createPersonalAPIToken(ctx context.Context, client *humioapi.Client, req reconcile.Request, hc *v1alpha1.HumioCluster, username string) error { r.Log.Info("ensuring admin user") // Get user ID of admin account - userID, err := r.createAndGetAdminAccountUserID(config, req, username) + userID, err := r.createAndGetAdminAccountUserID(ctx, client, req, username) if err != nil { return fmt.Errorf("got err trying to obtain user ID of admin user: %s", err) } @@ -168,7 +146,7 @@ func (r *HumioClusterReconciler) createPersonalAPIToken(ctx context.Context, con } // Get API token for user ID of admin account - apiToken, err := r.HumioClient.RotateUserApiTokenAndGet(config, req, userID) + apiToken, err := r.HumioClient.RotateUserApiTokenAndGet(ctx, client, req, userID) if err != nil { return r.logErrorAndReturn(err, fmt.Sprintf("failed to rotate api key for userID %s", userID)) } diff --git a/controllers/humiocluster_persistent_volumes.go b/controllers/humiocluster_persistent_volumes.go index 0189945c..9341b49d 100644 --- a/controllers/humiocluster_persistent_volumes.go +++ b/controllers/humiocluster_persistent_volumes.go @@ -21,10 +21,9 @@ import ( "fmt" "time" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/humio/humio-operator/pkg/kubernetes" ) const ( diff --git a/controllers/humiocluster_pod_status.go b/controllers/humiocluster_pod_status.go index 069a7689..ec6d272f 100644 --- a/controllers/humiocluster_pod_status.go +++ b/controllers/humiocluster_pod_status.go @@ -8,7 +8,7 @@ import ( "time" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 6239da2b..68fa9137 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -28,18 +28,17 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "github.com/humio/humio-operator/pkg/helpers" - "k8s.io/apimachinery/pkg/api/resource" "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/kubernetes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/controllers/humiocluster_secrets.go b/controllers/humiocluster_secrets.go index 939f0c8d..74ff7710 100644 --- a/controllers/humiocluster_secrets.go +++ b/controllers/humiocluster_secrets.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" ) diff --git a/controllers/humiocluster_services.go b/controllers/humiocluster_services.go index ccb22d0f..81a3e11d 100644 --- a/controllers/humiocluster_services.go +++ b/controllers/humiocluster_services.go @@ -20,8 +20,8 @@ import ( "fmt" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" diff --git a/controllers/humiocluster_tls.go b/controllers/humiocluster_tls.go index fcb6a673..de4abfe6 100644 --- a/controllers/humiocluster_tls.go +++ b/controllers/humiocluster_tls.go @@ -30,13 +30,14 @@ import ( "strings" "time" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" + corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/client-go/util/retry" cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -66,7 +67,7 @@ func validCASecret(ctx context.Context, k8sclient client.Client, namespace, secr if err != nil { return false, err } - keys := []string{"tls.crt", "tls.key"} + keys := []string{corev1.TLSCertKey, corev1.TLSPrivateKeyKey} for _, key := range keys { _, found := secret.Data[key] if !found { diff --git a/controllers/humiocluster_version.go b/controllers/humiocluster_version.go index 51cfcbc7..4436e24a 100644 --- a/controllers/humiocluster_version.go +++ b/controllers/humiocluster_version.go @@ -8,7 +8,7 @@ import ( ) const ( - HumioVersionMinimumSupported = "1.118.0" + HumioVersionMinimumSupported = "1.130.0" ) type HumioVersion struct { diff --git a/controllers/humioexternalcluster_controller.go b/controllers/humioexternalcluster_controller.go index f7497bcd..7325cac0 100644 --- a/controllers/humioexternalcluster_controller.go +++ b/controllers/humioexternalcluster_controller.go @@ -21,8 +21,9 @@ import ( "fmt" "time" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -31,7 +32,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) // HumioExternalClusterReconciler reconciles a HumioExternalCluster object @@ -85,7 +85,7 @@ func (r *HumioExternalClusterReconciler) Reconcile(ctx context.Context, req ctrl return reconcile.Result{}, r.logErrorAndReturn(fmt.Errorf("unable to obtain humio client config: %w", err), "unable to obtain humio client config") } - err = r.HumioClient.TestAPIToken(cluster.Config(), req) + err = r.HumioClient.TestAPIToken(ctx, cluster.Config(), req) if err != nil { r.Log.Error(err, "unable to test if the API token is works") err = r.Client.Get(ctx, req.NamespacedName, hec) diff --git a/controllers/humiofilteralert_controller.go b/controllers/humiofilteralert_controller.go index 4b202d00..9a9c2121 100644 --- a/controllers/humiofilteralert_controller.go +++ b/controllers/humiofilteralert_controller.go @@ -20,14 +20,16 @@ import ( "context" "errors" "fmt" - "reflect" + "sort" + "strings" "time" - "github.com/humio/humio-operator/pkg/kubernetes" - - humioapi "github.com/humio/cli/api" - - "github.com/humio/humio-operator/pkg/helpers" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/go-logr/logr" @@ -36,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) // HumioFilterAlertReconciler reconciles a HumioFilterAlert object @@ -85,9 +86,10 @@ func (r *HumioFilterAlertReconciler) Reconcile(ctx context.Context, req ctrl.Req } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) defer func(ctx context.Context, humioClient humio.Client, hfa *humiov1alpha1.HumioFilterAlert) { - _, err := r.HumioClient.GetFilterAlert(cluster.Config(), req, hfa) + _, err := r.HumioClient.GetFilterAlert(ctx, humioHttpClient, req, hfa) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioFilterAlertStateNotFound, hfa) return @@ -99,30 +101,33 @@ func (r *HumioFilterAlertReconciler) Reconcile(ctx context.Context, req ctrl.Req _ = r.setState(ctx, humiov1alpha1.HumioFilterAlertStateExists, hfa) }(ctx, r.HumioClient, hfa) - return r.reconcileHumioFilterAlert(ctx, cluster.Config(), hfa, req) + return r.reconcileHumioFilterAlert(ctx, humioHttpClient, hfa, req) } -func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlert(ctx context.Context, config *humioapi.Config, hfa *humiov1alpha1.HumioFilterAlert, req ctrl.Request) (reconcile.Result, error) { +func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlert(ctx context.Context, client *humioapi.Client, hfa *humiov1alpha1.HumioFilterAlert, req ctrl.Request) (reconcile.Result, error) { r.Log.Info("Checking if filter alert is marked to be deleted") isMarkedForDeletion := hfa.GetDeletionTimestamp() != nil if isMarkedForDeletion { r.Log.Info("FilterAlert marked to be deleted") if helpers.ContainsElement(hfa.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetFilterAlert(ctx, client, req, hfa) + if errors.As(err, &humioapi.EntityNotFound{}) { + hfa.SetFinalizers(helpers.RemoveElement(hfa.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, hfa) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting filter alert") - if err := r.HumioClient.DeleteFilterAlert(config, req, hfa); err != nil { + if err := r.HumioClient.DeleteFilterAlert(ctx, client, req, hfa); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete filter alert returned error") } - - r.Log.Info("FilterAlert Deleted. Removing finalizer") - hfa.SetFinalizers(helpers.RemoveElement(hfa.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, hfa) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -150,37 +155,38 @@ func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlert(ctx context.Conte } r.Log.Info("Checking if filter alert needs to be created") - curFilterAlert, err := r.HumioClient.GetFilterAlert(config, req, hfa) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("FilterAlert doesn't exist. Now adding filter alert") - addedFilterAlert, err := r.HumioClient.AddFilterAlert(config, req, hfa) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create filter alert") - } - r.Log.Info("Created filter alert", "FilterAlert", hfa.Spec.Name, "ID", addedFilterAlert.ID) - return reconcile.Result{Requeue: true}, nil - } + curFilterAlert, err := r.HumioClient.GetFilterAlert(ctx, client, req, hfa) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("FilterAlert doesn't exist. Now adding filter alert") + addErr := r.HumioClient.AddFilterAlert(ctx, client, req, hfa) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create filter alert") + } + r.Log.Info("Created filter alert", + "FilterAlert", hfa.Spec.Name, + ) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if alert exists") } r.Log.Info("Checking if filter alert needs to be updated") - if err := r.HumioClient.ValidateActionsForFilterAlert(config, req, hfa); err != nil { + if err := r.HumioClient.ValidateActionsForFilterAlert(ctx, client, req, hfa); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not get action id mapping") } - expectedFilterAlert := humio.FilterAlertTransform(hfa) - sanitizeFilterAlert(curFilterAlert) - if !reflect.DeepEqual(*curFilterAlert, *expectedFilterAlert) { - r.Log.Info(fmt.Sprintf("FilterAlert differs, triggering update, expected %#v, got: %#v", - expectedFilterAlert, - curFilterAlert)) - filterAlert, err := r.HumioClient.UpdateFilterAlert(config, req, hfa) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not update filter alert") - } - if filterAlert != nil { - r.Log.Info(fmt.Sprintf("Updated filter alert %q", filterAlert.Name)) + + if asExpected, diff := filterAlertAlreadyAsExpected(hfa, curFilterAlert); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + updateErr := r.HumioClient.UpdateFilterAlert(ctx, client, req, hfa) + if updateErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(updateErr, "could not update filter alert") } + r.Log.Info("Updated filter alert", + "FilterAlert", hfa.Spec.Name, + ) } r.Log.Info("done reconciling, will requeue after 15 seconds") @@ -208,7 +214,42 @@ func (r *HumioFilterAlertReconciler) logErrorAndReturn(err error, msg string) er return fmt.Errorf("%s: %w", msg, err) } -func sanitizeFilterAlert(filterAlert *humioapi.FilterAlert) { - filterAlert.ID = "" - filterAlert.RunAsUserID = "" +// filterAlertAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func filterAlertAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioFilterAlert, fromGraphQL *humiographql.FilterAlertDetails) (bool, string) { + var diffs []string + + if diff := cmp.Diff(fromGraphQL.GetDescription(), &fromKubernetesCustomResource.Spec.Description); diff != "" { + diffs = append(diffs, fmt.Sprintf("description=%q", diff)) + } + labelsFromGraphQL := fromGraphQL.GetLabels() + sort.Strings(labelsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Labels) + if diff := cmp.Diff(labelsFromGraphQL, fromKubernetesCustomResource.Spec.Labels); diff != "" { + diffs = append(diffs, fmt.Sprintf("labels=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetThrottleField(), fromKubernetesCustomResource.Spec.ThrottleField); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleField=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetThrottleTimeSeconds(), helpers.Int64Ptr(int64(fromKubernetesCustomResource.Spec.ThrottleTimeSeconds))); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleTimeSeconds=%q", diff)) + } + actionsFromGraphQL := humioapi.GetActionNames(fromGraphQL.GetActions()) + sort.Strings(actionsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Actions) + if diff := cmp.Diff(actionsFromGraphQL, fromKubernetesCustomResource.Spec.Actions); diff != "" { + diffs = append(diffs, fmt.Sprintf("actions=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetQueryString(), fromKubernetesCustomResource.Spec.QueryString); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryString=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetEnabled(), fromKubernetesCustomResource.Spec.Enabled); diff != "" { + diffs = append(diffs, fmt.Sprintf("enabled=%q", diff)) + } + if !humioapi.QueryOwnershipIsOrganizationOwnership(fromGraphQL.GetQueryOwnership()) { + diffs = append(diffs, fmt.Sprintf("queryOwnership=%+v", fromGraphQL.GetQueryOwnership())) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") } diff --git a/controllers/humioingesttoken_controller.go b/controllers/humioingesttoken_controller.go index f9bba373..3b3d989f 100644 --- a/controllers/humioingesttoken_controller.go +++ b/controllers/humioingesttoken_controller.go @@ -20,12 +20,16 @@ import ( "context" "errors" "fmt" + "strings" "time" "github.com/go-logr/logr" - humioapi "github.com/humio/cli/api" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" @@ -34,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) const humioFinalizer = "core.humio.com/finalizer" // TODO: Not only used for ingest tokens, but also parsers, repositories and views. @@ -86,6 +89,7 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) r.Log.Info("Checking if ingest token is marked to be deleted") // Check if the HumioIngestToken instance is marked to be deleted, which is @@ -94,23 +98,24 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req if isHumioIngestTokenMarkedToBeDeleted { r.Log.Info("Ingest token marked to be deleted") if helpers.ContainsElement(hit.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetIngestToken(ctx, humioHttpClient, req, hit) + if errors.As(err, &humioapi.EntityNotFound{}) { + hit.SetFinalizers(helpers.RemoveElement(hit.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, hit) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Ingest token contains finalizer so run finalizer method") - if err := r.finalize(ctx, cluster.Config(), req, hit); err != nil { + if err := r.finalize(ctx, humioHttpClient, req, hit); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Finalizer method returned error") } - - // Remove humioFinalizer. Once all finalizers have been - // removed, the object will be deleted. - r.Log.Info("Finalizer done. Removing finalizer") - hit.SetFinalizers(helpers.RemoveElement(hit.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, hit) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -124,7 +129,7 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req } defer func(ctx context.Context, humioClient humio.Client, hit *humiov1alpha1.HumioIngestToken) { - _, err := humioClient.GetIngestToken(cluster.Config(), req, hit) + _, err := humioClient.GetIngestToken(ctx, humioHttpClient, req, hit) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateNotFound, hit) return @@ -138,31 +143,32 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req // Get current ingest token r.Log.Info("get current ingest token") - curToken, err := r.HumioClient.GetIngestToken(cluster.Config(), req, hit) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("ingest token doesn't exist. Now adding ingest token") - // create token - _, err := r.HumioClient.AddIngestToken(cluster.Config(), req, hit) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create ingest token") - } - r.Log.Info("created ingest token") - return reconcile.Result{Requeue: true}, nil - } + curToken, err := r.HumioClient.GetIngestToken(ctx, humioHttpClient, req, hit) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("ingest token doesn't exist. Now adding ingest token") + // create token + addErr := r.HumioClient.AddIngestToken(ctx, humioHttpClient, req, hit) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create ingest token") + } + r.Log.Info("created ingest token") + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if ingest token exists") } - // Trigger update if parser name changed - if curToken.AssignedParser != hit.Spec.ParserName { - r.Log.Info("parser name differs, triggering update", "Expected", hit.Spec.ParserName, "Got", curToken.AssignedParser) - _, updateErr := r.HumioClient.UpdateIngestToken(cluster.Config(), req, hit) - if updateErr != nil { - return reconcile.Result{}, fmt.Errorf("could not update ingest token: %w", updateErr) + if asExpected, diff := ingestTokenAlreadyAsExpected(hit, curToken); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + err = r.HumioClient.UpdateIngestToken(ctx, humioHttpClient, req, hit) + if err != nil { + return reconcile.Result{}, fmt.Errorf("could not update ingest token: %w", err) } } - err = r.ensureTokenSecretExists(ctx, cluster.Config(), req, hit, cluster) + err = r.ensureTokenSecretExists(ctx, humioHttpClient, req, hit, cluster) if err != nil { return reconcile.Result{}, fmt.Errorf("could not ensure token secret exists: %w", err) } @@ -184,7 +190,7 @@ func (r *HumioIngestTokenReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func (r *HumioIngestTokenReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { +func (r *HumioIngestTokenReconciler) finalize(ctx context.Context, client *humioapi.Client, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { _, err := helpers.NewCluster(ctx, r, hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName, hit.Namespace, helpers.UseCertManager(), true, false) if err != nil { if k8serrors.IsNotFound(err) { @@ -193,7 +199,7 @@ func (r *HumioIngestTokenReconciler) finalize(ctx context.Context, config *humio return err } - return r.HumioClient.DeleteIngestToken(config, req, hit) + return r.HumioClient.DeleteIngestToken(ctx, client, req, hit) } func (r *HumioIngestTokenReconciler) addFinalizer(ctx context.Context, hit *humiov1alpha1.HumioIngestToken) error { @@ -208,12 +214,12 @@ func (r *HumioIngestTokenReconciler) addFinalizer(ctx context.Context, hit *humi return nil } -func (r *HumioIngestTokenReconciler) ensureTokenSecretExists(ctx context.Context, config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken, cluster helpers.ClusterInterface) error { +func (r *HumioIngestTokenReconciler) ensureTokenSecretExists(ctx context.Context, client *humioapi.Client, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken, cluster helpers.ClusterInterface) error { if hit.Spec.TokenSecretName == "" { return nil } - ingestToken, err := r.HumioClient.GetIngestToken(config, req, hit) + ingestToken, err := r.HumioClient.GetIngestToken(ctx, client, req, hit) if err != nil { return fmt.Errorf("failed to get ingest token: %w", err) } @@ -260,3 +266,29 @@ func (r *HumioIngestTokenReconciler) logErrorAndReturn(err error, msg string) er r.Log.Error(err, msg) return fmt.Errorf("%s: %w", msg, err) } + +// ingestTokenAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func ingestTokenAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioIngestToken, fromGraphQL *humiographql.IngestTokenDetails) (bool, string) { + var diffs []string + + // Expects a parser assigned, but none found + if fromGraphQL.GetParser() == nil && fromKubernetesCustomResource.Spec.ParserName != nil { + diffs = append(diffs, fmt.Sprintf("shouldAssignParser=%q", *fromKubernetesCustomResource.Spec.ParserName)) + } + + // Expects no parser assigned, but found one + if fromGraphQL.GetParser() != nil && fromKubernetesCustomResource.Spec.ParserName == nil { + diffs = append(diffs, fmt.Sprintf("shouldUnassignParser=%q", fromGraphQL.GetParser().GetName())) + } + + // Parser already assigned, but not the one we expected + if fromGraphQL.GetParser() != nil && fromKubernetesCustomResource.Spec.ParserName != nil { + if diff := cmp.Diff(fromGraphQL.GetParser().GetName(), *fromKubernetesCustomResource.Spec.ParserName); diff != "" { + diffs = append(diffs, fmt.Sprintf("parserName=%q", diff)) + } + } + + return len(diffs) == 0, strings.Join(diffs, ", ") +} diff --git a/controllers/humioparser_controller.go b/controllers/humioparser_controller.go index cc257d5a..35299f10 100644 --- a/controllers/humioparser_controller.go +++ b/controllers/humioparser_controller.go @@ -21,12 +21,15 @@ import ( "errors" "fmt" "sort" + "strings" "time" "github.com/google/go-cmp/cmp" - humioapi "github.com/humio/cli/api" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -35,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) // HumioParserReconciler reconciles a HumioParser object @@ -85,6 +87,7 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) r.Log.Info("Checking if parser is marked to be deleted") // Check if the HumioParser instance is marked to be deleted, which is @@ -93,23 +96,24 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) if isHumioParserMarkedToBeDeleted { r.Log.Info("Parser marked to be deleted") if helpers.ContainsElement(hp.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetParser(ctx, humioHttpClient, req, hp) + if errors.As(err, &humioapi.EntityNotFound{}) { + hp.SetFinalizers(helpers.RemoveElement(hp.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, hp) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Parser contains finalizer so run finalizer method") - if err := r.finalize(ctx, cluster.Config(), req, hp); err != nil { + if err := r.finalize(ctx, humioHttpClient, req, hp); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Finalizer method returned error") } - - // Remove humioFinalizer. Once all finalizers have been - // removed, the object will be deleted. - r.Log.Info("Finalizer done. Removing finalizer") - hp.SetFinalizers(helpers.RemoveElement(hp.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, hp) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -123,7 +127,7 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) } defer func(ctx context.Context, humioClient humio.Client, hp *humiov1alpha1.HumioParser) { - _, err := humioClient.GetParser(cluster.Config(), req, hp) + _, err := humioClient.GetParser(ctx, humioHttpClient, req, hp) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioParserStateNotFound, hp) return @@ -137,48 +141,26 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) // Get current parser r.Log.Info("get current parser") - curParser, err := r.HumioClient.GetParser(cluster.Config(), req, hp) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("parser doesn't exist. Now adding parser") - // create parser - _, err := r.HumioClient.AddParser(cluster.Config(), req, hp) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create parser") - } - r.Log.Info("created parser") - return reconcile.Result{Requeue: true}, nil - } + curParser, err := r.HumioClient.GetParser(ctx, humioHttpClient, req, hp) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("parser doesn't exist. Now adding parser") + // create parser + addErr := r.HumioClient.AddParser(ctx, humioHttpClient, req, hp) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create parser") + } + r.Log.Info("created parser") + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if parser exists") } - currentFieldsToTag := make([]string, len(curParser.FieldsToTag)) - expectedTagFields := make([]string, len(hp.Spec.TagFields)) - curParserTests := make([]string, len(curParser.TestCases)) - expectedTests := make([]string, len(hp.Spec.TestData)) - _ = copy(currentFieldsToTag, curParser.FieldsToTag) - _ = copy(expectedTagFields, hp.Spec.TagFields) - for i := range curParser.TestCases { - curParserTests[i] = curParser.TestCases[i].Event.RawString - } - if hp.Spec.TagFields == nil { - hp.Spec.TagFields = []string{} - } - _ = copy(expectedTests, hp.Spec.TestData) - if hp.Spec.TestData == nil { - hp.Spec.TestData = []string{} - } - sort.Strings(currentFieldsToTag) - sort.Strings(expectedTagFields) - sort.Strings(curParserTests) - sort.Strings(expectedTests) - parserScriptDiff := cmp.Diff(curParser.Script, hp.Spec.ParserScript) - tagFieldsDiff := cmp.Diff(curParser.FieldsToTag, hp.Spec.TagFields) - testDataDiff := cmp.Diff(curParserTests, hp.Spec.TestData) - - if parserScriptDiff != "" || tagFieldsDiff != "" || testDataDiff != "" { - r.Log.Info("parser information differs, triggering update", "parserScriptDiff", parserScriptDiff, "tagFieldsDiff", tagFieldsDiff, "testDataDiff", testDataDiff) - _, err = r.HumioClient.UpdateParser(cluster.Config(), req, hp) + if asExpected, diff := parserAlreadyAsExpected(hp, curParser); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + err = r.HumioClient.UpdateParser(ctx, humioHttpClient, req, hp) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not update parser") } @@ -200,7 +182,7 @@ func (r *HumioParserReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func (r *HumioParserReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { +func (r *HumioParserReconciler) finalize(ctx context.Context, client *humioapi.Client, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { _, err := helpers.NewCluster(ctx, r, hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName, hp.Namespace, helpers.UseCertManager(), true, false) if err != nil { if k8serrors.IsNotFound(err) { @@ -209,7 +191,7 @@ func (r *HumioParserReconciler) finalize(ctx context.Context, config *humioapi.C return err } - return r.HumioClient.DeleteParser(config, req, hp) + return r.HumioClient.DeleteParser(ctx, client, req, hp) } func (r *HumioParserReconciler) addFinalizer(ctx context.Context, hp *humiov1alpha1.HumioParser) error { @@ -237,3 +219,25 @@ func (r *HumioParserReconciler) logErrorAndReturn(err error, msg string) error { r.Log.Error(err, msg) return fmt.Errorf("%s: %w", msg, err) } + +// parserAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func parserAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioParser, fromGraphQL *humiographql.ParserDetails) (bool, string) { + var diffs []string + + if diff := cmp.Diff(fromGraphQL.GetScript(), &fromKubernetesCustomResource.Spec.ParserScript); diff != "" { + diffs = append(diffs, fmt.Sprintf("parserScript=%q", diff)) + } + tagFieldsFromGraphQL := fromGraphQL.GetFieldsToTag() + sort.Strings(tagFieldsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.TagFields) + if diff := cmp.Diff(tagFieldsFromGraphQL, fromKubernetesCustomResource.Spec.TagFields); diff != "" { + diffs = append(diffs, fmt.Sprintf("tagFields=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetTestCases(), humioapi.TestDataToParserDetailsTestCasesParserTestCase(fromKubernetesCustomResource.Spec.TestData)); diff != "" { + diffs = append(diffs, fmt.Sprintf("testData=%q", diff)) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") +} diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index 3d6829bb..e8812fee 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -20,11 +20,15 @@ import ( "context" "errors" "fmt" + "strings" "time" - humioapi "github.com/humio/cli/api" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -33,7 +37,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) // HumioRepositoryReconciler reconciles a HumioRepository object @@ -83,6 +86,7 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) r.Log.Info("Checking if repository is marked to be deleted") // Check if the HumioRepository instance is marked to be deleted, which is @@ -91,23 +95,24 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ if isHumioRepositoryMarkedToBeDeleted { r.Log.Info("Repository marked to be deleted") if helpers.ContainsElement(hr.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetRepository(ctx, humioHttpClient, req, hr) + if errors.As(err, &humioapi.EntityNotFound{}) { + hr.SetFinalizers(helpers.RemoveElement(hr.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, hr) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Repository contains finalizer so run finalizer method") - if err := r.finalize(ctx, cluster.Config(), req, hr); err != nil { + if err := r.finalize(ctx, humioHttpClient, req, hr); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Finalizer method returned error") } - - // Remove humioFinalizer. Once all finalizers have been - // removed, the object will be deleted. - r.Log.Info("Finalizer done. Removing finalizer") - hr.SetFinalizers(helpers.RemoveElement(hr.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, hr) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -121,7 +126,7 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ } defer func(ctx context.Context, humioClient humio.Client, hr *humiov1alpha1.HumioRepository) { - _, err := humioClient.GetRepository(cluster.Config(), req, hr) + _, err := humioClient.GetRepository(ctx, humioHttpClient, req, hr) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioRepositoryStateNotFound, hr) return @@ -135,38 +140,26 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ // Get current repository r.Log.Info("get current repository") - curRepository, err := r.HumioClient.GetRepository(cluster.Config(), req, hr) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("repository doesn't exist. Now adding repository") - // create repository - _, err := r.HumioClient.AddRepository(cluster.Config(), req, hr) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create repository") - } - r.Log.Info("created repository", "RepositoryName", hr.Spec.Name) - return reconcile.Result{Requeue: true}, nil - } + curRepository, err := r.HumioClient.GetRepository(ctx, humioHttpClient, req, hr) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("repository doesn't exist. Now adding repository") + // create repository + addErr := r.HumioClient.AddRepository(ctx, humioHttpClient, req, hr) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create repository") + } + r.Log.Info("created repository", "RepositoryName", hr.Spec.Name) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if repository exists") } - if (curRepository.Description != hr.Spec.Description) || - (curRepository.RetentionDays != float64(hr.Spec.Retention.TimeInDays)) || - (curRepository.IngestRetentionSizeGB != float64(hr.Spec.Retention.IngestSizeInGB)) || - (curRepository.StorageRetentionSizeGB != float64(hr.Spec.Retention.StorageSizeInGB)) || - (curRepository.AutomaticSearch != helpers.BoolTrue(hr.Spec.AutomaticSearch)) { - r.Log.Info(fmt.Sprintf("repository information differs, triggering update, expected %v/%v/%v/%v/%v, got: %v/%v/%v/%v/%v", - hr.Spec.Description, - float64(hr.Spec.Retention.TimeInDays), - float64(hr.Spec.Retention.IngestSizeInGB), - float64(hr.Spec.Retention.StorageSizeInGB), - helpers.BoolTrue(hr.Spec.AutomaticSearch), - curRepository.Description, - curRepository.RetentionDays, - curRepository.IngestRetentionSizeGB, - curRepository.StorageRetentionSizeGB, - curRepository.AutomaticSearch)) - _, err = r.HumioClient.UpdateRepository(cluster.Config(), req, hr) + if asExpected, diff := repositoryAlreadyAsExpected(hr, curRepository); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + err = r.HumioClient.UpdateRepository(ctx, humioHttpClient, req, hr) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not update repository") } @@ -188,7 +181,7 @@ func (r *HumioRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func (r *HumioRepositoryReconciler) finalize(ctx context.Context, config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { +func (r *HumioRepositoryReconciler) finalize(ctx context.Context, client *humioapi.Client, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { _, err := helpers.NewCluster(ctx, r, hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName, hr.Namespace, helpers.UseCertManager(), true, false) if err != nil { if k8serrors.IsNotFound(err) { @@ -197,7 +190,7 @@ func (r *HumioRepositoryReconciler) finalize(ctx context.Context, config *humioa return err } - return r.HumioClient.DeleteRepository(config, req, hr) + return r.HumioClient.DeleteRepository(ctx, client, req, hr) } func (r *HumioRepositoryReconciler) addFinalizer(ctx context.Context, hr *humiov1alpha1.HumioRepository) error { @@ -225,3 +218,28 @@ func (r *HumioRepositoryReconciler) logErrorAndReturn(err error, msg string) err r.Log.Error(err, msg) return fmt.Errorf("%s: %w", msg, err) } + +// repositoryAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func repositoryAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioRepository, fromGraphQL *humiographql.RepositoryDetails) (bool, string) { + var diffs []string + + if diff := cmp.Diff(fromGraphQL.GetDescription(), &fromKubernetesCustomResource.Spec.Description); diff != "" { + diffs = append(diffs, fmt.Sprintf("description=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetTimeBasedRetention(), helpers.Int32PtrToFloat64Ptr(fromKubernetesCustomResource.Spec.Retention.TimeInDays)); diff != "" { + diffs = append(diffs, fmt.Sprintf("timeInDays=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetIngestSizeBasedRetention(), helpers.Int32PtrToFloat64Ptr(fromKubernetesCustomResource.Spec.Retention.IngestSizeInGB)); diff != "" { + diffs = append(diffs, fmt.Sprintf("ingestSizeInGB=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetStorageSizeBasedRetention(), helpers.Int32PtrToFloat64Ptr(fromKubernetesCustomResource.Spec.Retention.StorageSizeInGB)); diff != "" { + diffs = append(diffs, fmt.Sprintf("storageSizeInGB=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetAutomaticSearch(), helpers.BoolTrue(fromKubernetesCustomResource.Spec.AutomaticSearch)); diff != "" { + diffs = append(diffs, fmt.Sprintf("automaticSearch=%q", diff)) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") +} diff --git a/controllers/humioscheduledsearch_controller.go b/controllers/humioscheduledsearch_controller.go index af3b72fc..dd7da65c 100644 --- a/controllers/humioscheduledsearch_controller.go +++ b/controllers/humioscheduledsearch_controller.go @@ -20,14 +20,16 @@ import ( "context" "errors" "fmt" - "reflect" + "sort" + "strings" "time" - "github.com/humio/humio-operator/pkg/kubernetes" - - humioapi "github.com/humio/cli/api" - - "github.com/humio/humio-operator/pkg/helpers" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/go-logr/logr" @@ -36,7 +38,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" ) // HumioScheduledSearchReconciler reconciles a HumioScheduledSearch object @@ -85,9 +86,10 @@ func (r *HumioScheduledSearchReconciler) Reconcile(ctx context.Context, req ctrl } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) defer func(ctx context.Context, humioClient humio.Client, hss *humiov1alpha1.HumioScheduledSearch) { - _, err := r.HumioClient.GetScheduledSearch(cluster.Config(), req, hss) + _, err := r.HumioClient.GetScheduledSearch(ctx, humioHttpClient, req, hss) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateNotFound, hss) return @@ -99,30 +101,33 @@ func (r *HumioScheduledSearchReconciler) Reconcile(ctx context.Context, req ctrl _ = r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateExists, hss) }(ctx, r.HumioClient, hss) - return r.reconcileHumioScheduledSearch(ctx, cluster.Config(), hss, req) + return r.reconcileHumioScheduledSearch(ctx, humioHttpClient, hss, req) } -func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearch(ctx context.Context, config *humioapi.Config, hss *humiov1alpha1.HumioScheduledSearch, req ctrl.Request) (reconcile.Result, error) { +func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearch(ctx context.Context, client *humioapi.Client, hss *humiov1alpha1.HumioScheduledSearch, req ctrl.Request) (reconcile.Result, error) { r.Log.Info("Checking if scheduled search is marked to be deleted") isMarkedForDeletion := hss.GetDeletionTimestamp() != nil if isMarkedForDeletion { r.Log.Info("ScheduledSearch marked to be deleted") if helpers.ContainsElement(hss.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetScheduledSearch(ctx, client, req, hss) + if errors.As(err, &humioapi.EntityNotFound{}) { + hss.SetFinalizers(helpers.RemoveElement(hss.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, hss) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting scheduled search") - if err := r.HumioClient.DeleteScheduledSearch(config, req, hss); err != nil { + if err := r.HumioClient.DeleteScheduledSearch(ctx, client, req, hss); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete scheduled search returned error") } - - r.Log.Info("ScheduledSearch Deleted. Removing finalizer") - hss.SetFinalizers(helpers.RemoveElement(hss.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, hss) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -141,38 +146,36 @@ func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearch(ctx conte } r.Log.Info("Checking if scheduled search needs to be created") - curScheduledSearch, err := r.HumioClient.GetScheduledSearch(config, req, hss) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("ScheduledSearch doesn't exist. Now adding scheduled search") - addedScheduledSearch, err := r.HumioClient.AddScheduledSearch(config, req, hss) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create scheduled search") - } - r.Log.Info("Created scheduled search", "ScheduledSearch", hss.Spec.Name, "ID", addedScheduledSearch.ID) - return reconcile.Result{Requeue: true}, nil - } + curScheduledSearch, err := r.HumioClient.GetScheduledSearch(ctx, client, req, hss) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("ScheduledSearch doesn't exist. Now adding scheduled search") + addErr := r.HumioClient.AddScheduledSearch(ctx, client, req, hss) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create scheduled search") + } + r.Log.Info("Created scheduled search", "ScheduledSearch", hss.Spec.Name) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if scheduled search") } r.Log.Info("Checking if scheduled search needs to be updated") - if err := r.HumioClient.ValidateActionsForScheduledSearch(config, req, hss); err != nil { + if err := r.HumioClient.ValidateActionsForScheduledSearch(ctx, client, req, hss); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not get action id mapping") } - expectedScheduledSearch := humio.ScheduledSearchTransform(hss) - sanitizeScheduledSearch(curScheduledSearch) - if !reflect.DeepEqual(*curScheduledSearch, *expectedScheduledSearch) { - r.Log.Info(fmt.Sprintf("ScheduledSearch differs, triggering update, expected %#v, got: %#v", - expectedScheduledSearch, - curScheduledSearch)) - scheduledSearch, err := r.HumioClient.UpdateScheduledSearch(config, req, hss) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not update scheduled search") - } - if scheduledSearch != nil { - r.Log.Info(fmt.Sprintf("Updated scheduled search %q", scheduledSearch.Name)) + if asExpected, diff := scheduledSearchAlreadyAsExpected(hss, curScheduledSearch); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + updateErr := r.HumioClient.UpdateScheduledSearch(ctx, client, req, hss) + if updateErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(updateErr, "could not update scheduled search") } + r.Log.Info("Updated scheduled search", + "ScheduledSearch", hss.Spec.Name, + ) } r.Log.Info("done reconciling, will requeue after 15 seconds") @@ -200,7 +203,51 @@ func (r *HumioScheduledSearchReconciler) logErrorAndReturn(err error, msg string return fmt.Errorf("%s: %w", msg, err) } -func sanitizeScheduledSearch(scheduledSearch *humioapi.ScheduledSearch) { - scheduledSearch.ID = "" - scheduledSearch.RunAsUserID = "" +// scheduledSearchAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func scheduledSearchAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioScheduledSearch, fromGraphQL *humiographql.ScheduledSearchDetails) (bool, string) { + var diffs []string + + if diff := cmp.Diff(fromGraphQL.GetDescription(), &fromKubernetesCustomResource.Spec.Description); diff != "" { + diffs = append(diffs, fmt.Sprintf("description=%q", diff)) + } + labelsFromGraphQL := fromGraphQL.GetLabels() + sort.Strings(labelsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Labels) + if diff := cmp.Diff(labelsFromGraphQL, fromKubernetesCustomResource.Spec.Labels); diff != "" { + diffs = append(diffs, fmt.Sprintf("labels=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetStart(), fromKubernetesCustomResource.Spec.QueryStart); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleField=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetEnd(), fromKubernetesCustomResource.Spec.QueryEnd); diff != "" { + diffs = append(diffs, fmt.Sprintf("throttleTimeSeconds=%q", diff)) + } + actionsFromGraphQL := humioapi.GetActionNames(fromGraphQL.GetActionsV2()) + sort.Strings(actionsFromGraphQL) + sort.Strings(fromKubernetesCustomResource.Spec.Actions) + if diff := cmp.Diff(actionsFromGraphQL, fromKubernetesCustomResource.Spec.Actions); diff != "" { + diffs = append(diffs, fmt.Sprintf("actions=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetTimeZone(), fromKubernetesCustomResource.Spec.TimeZone); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryTimestampType=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetQueryString(), fromKubernetesCustomResource.Spec.QueryString); diff != "" { + diffs = append(diffs, fmt.Sprintf("queryString=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetSchedule(), fromKubernetesCustomResource.Spec.Schedule); diff != "" { + diffs = append(diffs, fmt.Sprintf("triggerMode=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetBackfillLimit(), fromKubernetesCustomResource.Spec.BackfillLimit); diff != "" { + diffs = append(diffs, fmt.Sprintf("searchIntervalSeconds=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetEnabled(), fromKubernetesCustomResource.Spec.Enabled); diff != "" { + diffs = append(diffs, fmt.Sprintf("enabled=%q", diff)) + } + if !humioapi.QueryOwnershipIsOrganizationOwnership(fromGraphQL.GetQueryOwnership()) { + diffs = append(diffs, fmt.Sprintf("queryOwnership=%+v", fromGraphQL.GetQueryOwnership())) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") } diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index d5a70d29..9665e423 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -21,13 +21,16 @@ import ( "errors" "fmt" "sort" + "strings" "time" "github.com/go-logr/logr" - humioapi "github.com/humio/cli/api" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/google/go-cmp/cmp" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -83,6 +86,7 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } + humioHttpClient := r.HumioClient.GetHumioHttpClient(cluster.Config(), req) // Delete r.Log.Info("Checking if view is marked to be deleted") @@ -90,21 +94,24 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( if isMarkedForDeletion { r.Log.Info("View marked to be deleted") if helpers.ContainsElement(hv.GetFinalizers(), humioFinalizer) { + _, err := r.HumioClient.GetView(ctx, humioHttpClient, req, hv) + if errors.As(err, &humioapi.EntityNotFound{}) { + hv.SetFinalizers(helpers.RemoveElement(hv.GetFinalizers(), humioFinalizer)) + err := r.Update(ctx, hv) + if err != nil { + return reconcile.Result{}, err + } + r.Log.Info("Finalizer removed successfully") + return reconcile.Result{Requeue: true}, nil + } + // Run finalization logic for humioFinalizer. If the // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting View") - if err := r.HumioClient.DeleteView(cluster.Config(), req, hv); err != nil { + if err := r.HumioClient.DeleteView(ctx, humioHttpClient, req, hv); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete view returned error") } - - r.Log.Info("View Deleted. Removing finalizer") - hv.SetFinalizers(helpers.RemoveElement(hv.GetFinalizers(), humioFinalizer)) - err := r.Update(ctx, hv) - if err != nil { - return reconcile.Result{}, err - } - r.Log.Info("Finalizer removed successfully") } return reconcile.Result{}, nil } @@ -120,9 +127,8 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return reconcile.Result{Requeue: true}, nil } - defer func(ctx context.Context, humioClient humio.Client, hv *humiov1alpha1.HumioView) { - _, err := r.HumioClient.GetView(cluster.Config(), req, hv) + _, err := r.HumioClient.GetView(ctx, humioHttpClient, req, hv) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioViewStateNotFound, hv) return @@ -135,34 +141,27 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( }(ctx, r.HumioClient, hv) r.Log.Info("get current view") - curView, err := r.HumioClient.GetView(cluster.Config(), req, hv) - if errors.As(err, &humioapi.EntityNotFound{}) { - r.Log.Info("View doesn't exist. Now adding view") - _, err := r.HumioClient.AddView(cluster.Config(), req, hv) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not create view") - } - r.Log.Info("created view", "ViewName", hv.Spec.Name) - return reconcile.Result{Requeue: true}, nil - } + curView, err := r.HumioClient.GetView(ctx, humioHttpClient, req, hv) if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + r.Log.Info("View doesn't exist. Now adding view") + addErr := r.HumioClient.AddView(ctx, humioHttpClient, req, hv) + if addErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(addErr, "could not create view") + } + r.Log.Info("created view", "ViewName", hv.Spec.Name) + return reconcile.Result{Requeue: true}, nil + } return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if view exists") } - // Update - if viewConnectionsDiffer(curView.Connections, hv.GetViewConnections()) || - curView.Description != hv.Spec.Description || - curView.AutomaticSearch != helpers.BoolTrue(hv.Spec.AutomaticSearch) { - r.Log.Info(fmt.Sprintf("view information differs, triggering update, expected %v/%v/%v, got: %v/%v/%v", - hv.Spec.Connections, - hv.Spec.Description, - helpers.BoolTrue(hv.Spec.AutomaticSearch), - curView.Connections, - curView.Description, - curView.AutomaticSearch)) - _, err := r.HumioClient.UpdateView(cluster.Config(), req, hv) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not update view") + if asExpected, diff := viewAlreadyAsExpected(hv, curView); !asExpected { + r.Log.Info("information differs, triggering update", + "diff", diff, + ) + updateErr := r.HumioClient.UpdateView(ctx, humioHttpClient, req, hv) + if updateErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(updateErr, "could not update view") } } @@ -170,37 +169,6 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return reconcile.Result{RequeueAfter: time.Second * 15}, nil } -// viewConnectionsDiffer returns whether two slices of connections differ. -// Connections are compared by repo name and filter so the ordering is not taken -// into account. -func viewConnectionsDiffer(curConnections, newConnections []humioapi.ViewConnection) bool { - if len(curConnections) != len(newConnections) { - return true - } - // sort the slices to avoid changes to the order of items in the slice to - // trigger an update. Kubernetes does not guarantee that slice items are - // deterministic ordered, so without this we could trigger updates to views - // without any functional changes. As the result of a view update in Humio is - // live queries against it are refreshed it can lead to dashboards and queries - // refreshing all the time. - sortConnections(curConnections) - sortConnections(newConnections) - - for i := range curConnections { - if curConnections[i] != newConnections[i] { - return true - } - } - - return false -} - -func sortConnections(connections []humioapi.ViewConnection) { - sort.SliceStable(connections, func(i, j int) bool { - return connections[i].RepoName > connections[j].RepoName || connections[i].Filter > connections[j].Filter - }) -} - // SetupWithManager sets up the controller with the Manager. func (r *HumioViewReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). @@ -221,3 +189,32 @@ func (r *HumioViewReconciler) logErrorAndReturn(err error, msg string) error { r.Log.Error(err, msg) return fmt.Errorf("%s: %w", msg, err) } + +// viewAlreadyAsExpected compares fromKubernetesCustomResource and fromGraphQL. It returns a boolean indicating +// if the details from GraphQL already matches what is in the desired state of the custom resource. +// If they do not match, a string is returned with details on what the diff is. +func viewAlreadyAsExpected(fromKubernetesCustomResource *humiov1alpha1.HumioView, fromGraphQL *humiographql.GetSearchDomainSearchDomainView) (bool, string) { + var diffs []string + + currentConnections := fromGraphQL.GetConnections() + expectedConnections := fromKubernetesCustomResource.GetViewConnections() + sortConnections(currentConnections) + sortConnections(expectedConnections) + if diff := cmp.Diff(currentConnections, expectedConnections); diff != "" { + diffs = append(diffs, fmt.Sprintf("viewConnections=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetDescription(), &fromKubernetesCustomResource.Spec.Description); diff != "" { + diffs = append(diffs, fmt.Sprintf("description=%q", diff)) + } + if diff := cmp.Diff(fromGraphQL.GetAutomaticSearch(), helpers.BoolTrue(fromKubernetesCustomResource.Spec.AutomaticSearch)); diff != "" { + diffs = append(diffs, fmt.Sprintf("automaticSearch=%q", diff)) + } + + return len(diffs) == 0, strings.Join(diffs, ", ") +} + +func sortConnections(connections []humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection) { + sort.SliceStable(connections, func(i, j int) bool { + return connections[i].Repository.Name > connections[j].Repository.Name || connections[i].Filter > connections[j].Filter + }) +} diff --git a/controllers/humioview_controller_test.go b/controllers/humioview_controller_test.go deleted file mode 100644 index be2803bf..00000000 --- a/controllers/humioview_controller_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package controllers - -import ( - "testing" - - humioapi "github.com/humio/cli/api" -) - -func TestViewConnectionsDiffer(t *testing.T) { - tt := []struct { - name string - current, new []humioapi.ViewConnection - differ bool - }{ - { - name: "nil connections", - current: nil, - new: nil, - differ: false, - }, - { - name: "empty slices", - current: []humioapi.ViewConnection{}, - new: []humioapi.ViewConnection{}, - differ: false, - }, - { - name: "new connection added", - current: []humioapi.ViewConnection{}, - new: []humioapi.ViewConnection{ - { - RepoName: "repo", - Filter: "*", - }, - }, - differ: true, - }, - { - name: "update filter", - current: []humioapi.ViewConnection{ - { - RepoName: "repo", - Filter: "*", - }, - }, - new: []humioapi.ViewConnection{ - { - RepoName: "repo", - Filter: "* more=", - }, - }, - differ: true, - }, - { - name: "remove connection", - current: []humioapi.ViewConnection{ - { - RepoName: "repo", - Filter: "*", - }, - }, - new: []humioapi.ViewConnection{}, - differ: true, - }, - { - name: "reorder connections where name differs", - current: []humioapi.ViewConnection{ - { - RepoName: "repo-a", - Filter: "*", - }, - { - RepoName: "repo-b", - Filter: "*", - }, - }, - new: []humioapi.ViewConnection{ - { - RepoName: "repo-b", - Filter: "*", - }, - { - RepoName: "repo-a", - Filter: "*", - }, - }, - differ: false, - }, - { - name: "reorder connections where filter differs", - current: []humioapi.ViewConnection{ - { - RepoName: "repo", - Filter: "a=*", - }, - { - RepoName: "repo", - Filter: "b=*", - }, - }, - new: []humioapi.ViewConnection{ - { - RepoName: "repo", - Filter: "b=*", - }, - { - RepoName: "repo", - Filter: "a=*", - }, - }, - differ: false, - }, - } - for _, tc := range tt { - t.Run(tc.name, func(t *testing.T) { - result := viewConnectionsDiffer(tc.current, tc.new) - if result != tc.differ { - t.Errorf("viewConnectionsDiffer() got = %v, want %v", result, tc.differ) - } - }) - } -} diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index 415840ae..0bdf530f 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -29,8 +29,8 @@ import ( "github.com/humio/humio-operator/controllers" "github.com/humio/humio-operator/controllers/suite" "github.com/humio/humio-operator/controllers/versions" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" diff --git a/controllers/suite/clusters/suite_test.go b/controllers/suite/clusters/suite_test.go index c791aa09..3bcf6fdb 100644 --- a/controllers/suite/clusters/suite_test.go +++ b/controllers/suite/clusters/suite_test.go @@ -29,11 +29,12 @@ import ( "github.com/humio/humio-operator/controllers" "github.com/humio/humio-operator/controllers/suite" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/rest" - "github.com/humio/humio-operator/pkg/kubernetes" - cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" "github.com/go-logr/logr" "github.com/go-logr/zapr" @@ -44,9 +45,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" diff --git a/controllers/suite/common.go b/controllers/suite/common.go index ee9c4611..207d207d 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -13,9 +13,9 @@ import ( humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/controllers" "github.com/humio/humio-operator/controllers/versions" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" @@ -528,20 +528,23 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) - cluster, err := humioClient.GetClusters(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) + humioHttpClient := humioClient.GetHumioHttpClient(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) + cluster, err := humioClient.GetClusters(ctx, humioHttpClient, reconcile.Request{NamespacedName: key}) if err != nil { return []string{fmt.Sprintf("got err: %s", err)} } - if len(cluster.Nodes) < 1 { + getCluster := cluster.GetCluster() + if len(getCluster.GetNodes()) < 1 { return []string{} } keys := make(map[string]bool) var zoneList []string - for _, node := range cluster.Nodes { - if _, value := keys[node.Zone]; !value { - if node.Zone != "" { - keys[node.Zone] = true - zoneList = append(zoneList, node.Zone) + for _, node := range getCluster.GetNodes() { + zone := node.Zone + if zone != nil { + if _, value := keys[*zone]; !value { + keys[*zone] = true + zoneList = append(zoneList, *zone) } } } @@ -554,17 +557,20 @@ func CreateAndBootstrapCluster(ctx context.Context, k8sClient client.Client, hum Expect(clusterConfig).ToNot(BeNil()) Expect(clusterConfig.Config()).ToNot(BeNil()) - cluster, err := humioClient.GetClusters(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) - if err != nil || len(cluster.Nodes) < 1 { + humioHttpClient := humioClient.GetHumioHttpClient(clusterConfig.Config(), reconcile.Request{NamespacedName: key}) + cluster, err := humioClient.GetClusters(ctx, humioHttpClient, reconcile.Request{NamespacedName: key}) + getCluster := cluster.GetCluster() + if err != nil || len(getCluster.GetNodes()) < 1 { return []string{} } keys := make(map[string]bool) var zoneList []string - for _, node := range cluster.Nodes { - if _, value := keys[node.Zone]; !value { - if node.Zone != "" { - keys[node.Zone] = true - zoneList = append(zoneList, node.Zone) + for _, node := range getCluster.GetNodes() { + zone := node.Zone + if zone != nil { + if _, value := keys[*zone]; !value { + keys[*zone] = true + zoneList = append(zoneList, *zone) } } } diff --git a/controllers/suite/resources/humioresources_controller_test.go b/controllers/suite/resources/humioresources_controller_test.go index 2b199a92..0f8d672b 100644 --- a/controllers/suite/resources/humioresources_controller_test.go +++ b/controllers/suite/resources/humioresources_controller_test.go @@ -21,8 +21,10 @@ import ( "fmt" "net/http" - "github.com/humio/humio-operator/pkg/kubernetes" - + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" @@ -32,13 +34,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/controllers/suite" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" ) +const EmailActionExample string = "example@example.com" + var _ = Describe("Humio Resources Controllers", func() { BeforeEach(func() { // failed test runs that don't clean up leave resources behind. @@ -71,7 +72,7 @@ var _ = Describe("Humio Resources Controllers", func() { Spec: humiov1alpha1.HumioIngestTokenSpec{ ManagedClusterName: clusterKey.Name, Name: key.Name, - ParserName: initialParserName, + ParserName: &initialParserName, RepositoryName: testRepo.Spec.Name, TokenSecretName: "target-secret-1", }, @@ -101,30 +102,33 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(ingestTokenSecret.OwnerReferences).Should(HaveLen(1)) suite.UsingClusterBy(clusterKey.Name, "HumioIngestToken: Checking correct parser assigned to ingest token") - var humioIngestToken *humioapi.IngestToken - Eventually(func() string { - humioIngestToken, err = humioClient.GetIngestToken(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedIngestToken) + var humioIngestToken *humiographql.IngestTokenDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) + Eventually(func() *humiographql.IngestTokenDetailsParser { + humioIngestToken, _ = humioClient.GetIngestToken(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedIngestToken) if humioIngestToken != nil { - return humioIngestToken.AssignedParser + return humioIngestToken.Parser } - return "nil" - }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(initialParserName)) + return nil + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&humiographql.IngestTokenDetailsParser{Name: initialParserName})) suite.UsingClusterBy(clusterKey.Name, "HumioIngestToken: Updating parser for ingest token") updatedParserName := "accesslog" Eventually(func() error { - k8sClient.Get(ctx, key, fetchedIngestToken) - fetchedIngestToken.Spec.ParserName = updatedParserName + if err := k8sClient.Get(ctx, key, fetchedIngestToken); err != nil { + return err + } + fetchedIngestToken.Spec.ParserName = &updatedParserName return k8sClient.Update(ctx, fetchedIngestToken) }, testTimeout, suite.TestInterval).Should(Succeed()) - Eventually(func() string { - humioIngestToken, err = humioClient.GetIngestToken(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedIngestToken) + Eventually(func() *humiographql.IngestTokenDetailsParser { + humioIngestToken, err = humioClient.GetIngestToken(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedIngestToken) if humioIngestToken != nil { - return humioIngestToken.AssignedParser + return humioIngestToken.Parser } - return "nil" - }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedParserName)) + return nil + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&humiographql.IngestTokenDetailsParser{Name: updatedParserName})) suite.UsingClusterBy(clusterKey.Name, "HumioIngestToken: Deleting ingest token secret successfully adds back secret") Expect( @@ -174,7 +178,7 @@ var _ = Describe("Humio Resources Controllers", func() { Spec: humiov1alpha1.HumioIngestTokenSpec{ ManagedClusterName: clusterKey.Name, Name: key.Name, - ParserName: "accesslog", + ParserName: helpers.StringPtr("accesslog"), RepositoryName: testRepo.Spec.Name, }, } @@ -199,7 +203,9 @@ var _ = Describe("Humio Resources Controllers", func() { suite.UsingClusterBy(clusterKey.Name, "HumioIngestToken: Enabling token secret name successfully creates secret") Eventually(func() error { - k8sClient.Get(ctx, key, fetchedIngestToken) + if err := k8sClient.Get(ctx, key, fetchedIngestToken); err != nil { + return err + } fetchedIngestToken.Spec.TokenSecretName = "target-secret-2" fetchedIngestToken.Spec.TokenSecretLabels = map[string]string{ "custom-label": "custom-value", @@ -242,7 +248,7 @@ var _ = Describe("Humio Resources Controllers", func() { Spec: humiov1alpha1.HumioIngestTokenSpec{ ManagedClusterName: "non-existent-managed-cluster", Name: "ingesttokenname", - ParserName: "accesslog", + ParserName: helpers.StringPtr("accesslog"), RepositoryName: testRepo.Spec.Name, TokenSecretName: "thissecretname", }, @@ -276,7 +282,7 @@ var _ = Describe("Humio Resources Controllers", func() { Spec: humiov1alpha1.HumioIngestTokenSpec{ ExternalClusterName: "non-existent-external-cluster", Name: "ingesttokenname", - ParserName: "accesslog", + ParserName: helpers.StringPtr("accesslog"), RepositoryName: testRepo.Spec.Name, TokenSecretName: "thissecretname", }, @@ -318,9 +324,9 @@ var _ = Describe("Humio Resources Controllers", func() { Name: "example-repository", Description: "important description", Retention: humiov1alpha1.HumioRetention{ - TimeInDays: 30, - IngestSizeInGB: 5, - StorageSizeInGB: 1, + TimeInDays: helpers.Int32Ptr(30), + IngestSizeInGB: helpers.Int32Ptr(5), + StorageSizeInGB: helpers.Int32Ptr(1), }, AllowDataDeletion: true, }, @@ -335,76 +341,99 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedRepository.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioRepositoryStateExists)) - var initialRepository *humioapi.Repository + var initialRepository *humiographql.RepositoryDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - initialRepository, err = humioClient.GetRepository(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateRepository) + initialRepository, err = humioClient.GetRepository(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateRepository) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(initialRepository).ToNot(BeNil()) + var retentionInDays, ingestRetentionSizeGB, storageRetentionSizeGB float64 + if toCreateRepository.Spec.Retention.TimeInDays != nil { + retentionInDays = float64(*toCreateRepository.Spec.Retention.TimeInDays) + } + if toCreateRepository.Spec.Retention.IngestSizeInGB != nil { + ingestRetentionSizeGB = float64(*toCreateRepository.Spec.Retention.IngestSizeInGB) + } + if toCreateRepository.Spec.Retention.StorageSizeInGB != nil { + storageRetentionSizeGB = float64(*toCreateRepository.Spec.Retention.StorageSizeInGB) + } expectedInitialRepository := repositoryExpectation{ Name: toCreateRepository.Spec.Name, - Description: toCreateRepository.Spec.Description, - RetentionDays: float64(toCreateRepository.Spec.Retention.TimeInDays), - IngestRetentionSizeGB: float64(toCreateRepository.Spec.Retention.IngestSizeInGB), - StorageRetentionSizeGB: float64(toCreateRepository.Spec.Retention.StorageSizeInGB), + Description: &toCreateRepository.Spec.Description, + RetentionDays: &retentionInDays, + IngestRetentionSizeGB: &ingestRetentionSizeGB, + StorageRetentionSizeGB: &storageRetentionSizeGB, AutomaticSearch: true, } Eventually(func() repositoryExpectation { - initialRepository, err := humioClient.GetRepository(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedRepository) + initialRepository, err := humioClient.GetRepository(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedRepository) if err != nil { return repositoryExpectation{} } return repositoryExpectation{ - Name: initialRepository.Name, - Description: initialRepository.Description, - RetentionDays: initialRepository.RetentionDays, - IngestRetentionSizeGB: initialRepository.IngestRetentionSizeGB, - StorageRetentionSizeGB: initialRepository.StorageRetentionSizeGB, - SpaceUsed: initialRepository.SpaceUsed, - AutomaticSearch: initialRepository.AutomaticSearch, + Name: initialRepository.GetName(), + Description: initialRepository.GetDescription(), + RetentionDays: initialRepository.GetTimeBasedRetention(), + IngestRetentionSizeGB: initialRepository.GetIngestSizeBasedRetention(), + StorageRetentionSizeGB: initialRepository.GetStorageSizeBasedRetention(), + SpaceUsed: initialRepository.GetCompressedByteSize(), + AutomaticSearch: initialRepository.GetAutomaticSearch(), } - }, testTimeout, suite.TestInterval).Should(Equal(expectedInitialRepository)) + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(expectedInitialRepository)) suite.UsingClusterBy(clusterKey.Name, "HumioRepository: Updating the repository successfully") updatedDescription := "important description - now updated" updatedAutomaticSearch := helpers.BoolPtr(false) Eventually(func() error { - k8sClient.Get(ctx, key, fetchedRepository) + if err := k8sClient.Get(ctx, key, fetchedRepository); err != nil { + return err + } fetchedRepository.Spec.Description = updatedDescription fetchedRepository.Spec.AutomaticSearch = updatedAutomaticSearch return k8sClient.Update(ctx, fetchedRepository) }, testTimeout, suite.TestInterval).Should(Succeed()) - var updatedRepository *humioapi.Repository + var updatedRepository *humiographql.RepositoryDetails Eventually(func() error { - updatedRepository, err = humioClient.GetRepository(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedRepository) + updatedRepository, err = humioClient.GetRepository(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedRepository) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(updatedRepository).ToNot(BeNil()) + var updatedRetentionInDays, updatedIngestRetentionSizeGB, updatedStorageRetentionSizeGB float64 + if toCreateRepository.Spec.Retention.TimeInDays != nil { + updatedRetentionInDays = float64(*fetchedRepository.Spec.Retention.TimeInDays) + } + if toCreateRepository.Spec.Retention.IngestSizeInGB != nil { + updatedIngestRetentionSizeGB = float64(*fetchedRepository.Spec.Retention.IngestSizeInGB) + } + if toCreateRepository.Spec.Retention.StorageSizeInGB != nil { + updatedStorageRetentionSizeGB = float64(*fetchedRepository.Spec.Retention.StorageSizeInGB) + } expectedUpdatedRepository := repositoryExpectation{ Name: fetchedRepository.Spec.Name, - Description: updatedDescription, - RetentionDays: float64(fetchedRepository.Spec.Retention.TimeInDays), - IngestRetentionSizeGB: float64(fetchedRepository.Spec.Retention.IngestSizeInGB), - StorageRetentionSizeGB: float64(fetchedRepository.Spec.Retention.StorageSizeInGB), - AutomaticSearch: *fetchedRepository.Spec.AutomaticSearch, + Description: &updatedDescription, + RetentionDays: &updatedRetentionInDays, + IngestRetentionSizeGB: &updatedIngestRetentionSizeGB, + StorageRetentionSizeGB: &updatedStorageRetentionSizeGB, + AutomaticSearch: helpers.BoolTrue(fetchedRepository.Spec.AutomaticSearch), } Eventually(func() repositoryExpectation { - updatedRepository, err := humioClient.GetRepository(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedRepository) + updatedRepository, err := humioClient.GetRepository(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedRepository) if err != nil { return repositoryExpectation{} } return repositoryExpectation{ - Name: updatedRepository.Name, - Description: updatedRepository.Description, - RetentionDays: updatedRepository.RetentionDays, - IngestRetentionSizeGB: updatedRepository.IngestRetentionSizeGB, - StorageRetentionSizeGB: updatedRepository.StorageRetentionSizeGB, - SpaceUsed: updatedRepository.SpaceUsed, - AutomaticSearch: updatedRepository.AutomaticSearch, + Name: updatedRepository.GetName(), + Description: updatedRepository.GetDescription(), + RetentionDays: updatedRepository.GetTimeBasedRetention(), + IngestRetentionSizeGB: updatedRepository.GetIngestSizeBasedRetention(), + StorageRetentionSizeGB: updatedRepository.GetStorageSizeBasedRetention(), + SpaceUsed: updatedRepository.GetCompressedByteSize(), + AutomaticSearch: updatedRepository.GetAutomaticSearch(), } }, testTimeout, suite.TestInterval).Should(Equal(expectedUpdatedRepository)) @@ -431,9 +460,9 @@ var _ = Describe("Humio Resources Controllers", func() { Name: "example-repository-view", Description: "important description", Retention: humiov1alpha1.HumioRetention{ - TimeInDays: 30, - IngestSizeInGB: 5, - StorageSizeInGB: 1, + TimeInDays: helpers.Int32Ptr(30), + IngestSizeInGB: helpers.Int32Ptr(5), + StorageSizeInGB: helpers.Int32Ptr(1), }, AllowDataDeletion: true, }, @@ -476,25 +505,31 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioViewStateExists)) suite.UsingClusterBy(clusterKey.Name, "HumioView: Creating the view successfully in Humio") - var initialView *humioapi.View + var initialView *humiographql.GetSearchDomainSearchDomainView Eventually(func() error { - initialView, err = humioClient.GetView(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, viewToCreate) + initialView, err = humioClient.GetView(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, viewToCreate) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(initialView).ToNot(BeNil()) - expectedInitialView := humioapi.View{ + expectedInitialView := humiographql.GetSearchDomainSearchDomainView{ + Typename: helpers.StringPtr("View"), + Id: "", Name: viewToCreate.Spec.Name, - Description: viewToCreate.Spec.Description, + Description: &viewToCreate.Spec.Description, Connections: viewToCreate.GetViewConnections(), AutomaticSearch: true, } - Eventually(func() humioapi.View { - initialView, err := humioClient.GetView(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedView) + Eventually(func() humiographql.GetSearchDomainSearchDomainView { + initialView, err := humioClient.GetView(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedView) if err != nil { - return humioapi.View{} + return humiographql.GetSearchDomainSearchDomainView{} } + + // Ignore the ID + initialView.Id = "" + return *initialView }, testTimeout, suite.TestInterval).Should(Equal(expectedInitialView)) @@ -508,7 +543,9 @@ var _ = Describe("Humio Resources Controllers", func() { } updatedViewAutomaticSearch := helpers.BoolPtr(false) Eventually(func() error { - k8sClient.Get(ctx, viewKey, fetchedView) + if err := k8sClient.Get(ctx, viewKey, fetchedView); err != nil { + return err + } fetchedView.Spec.Description = updatedViewDescription fetchedView.Spec.Connections = updatedConnections fetchedView.Spec.AutomaticSearch = updatedViewAutomaticSearch @@ -516,24 +553,30 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioView: Updating the view successfully in Humio") - var updatedView *humioapi.View + var updatedView *humiographql.GetSearchDomainSearchDomainView Eventually(func() error { - updatedView, err = humioClient.GetView(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedView) + updatedView, err = humioClient.GetView(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedView) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(updatedView).ToNot(BeNil()) - expectedUpdatedView := humioapi.View{ + expectedUpdatedView := humiographql.GetSearchDomainSearchDomainView{ + Typename: helpers.StringPtr("View"), + Id: "", Name: viewToCreate.Spec.Name, - Description: fetchedView.Spec.Description, + Description: &fetchedView.Spec.Description, Connections: fetchedView.GetViewConnections(), AutomaticSearch: *fetchedView.Spec.AutomaticSearch, } - Eventually(func() humioapi.View { - updatedView, err := humioClient.GetView(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedView) + Eventually(func() humiographql.GetSearchDomainSearchDomainView { + updatedView, err := humioClient.GetView(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedView) if err != nil { - return humioapi.View{} + return humiographql.GetSearchDomainSearchDomainView{} } + + // Ignore the ID + updatedView.Id = "" + return *updatedView }, testTimeout, suite.TestInterval).Should(Equal(expectedUpdatedView)) @@ -588,53 +631,68 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedParser.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioParserStateExists)) - var initialParser *humioapi.Parser + var initialParser *humiographql.ParserDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - initialParser, err = humioClient.GetParser(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateParser) + initialParser, err = humioClient.GetParser(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateParser) if err != nil { return err } // Ignore the ID when comparing parser content - initialParser.ID = "" + initialParser.Id = "" return nil }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(initialParser).ToNot(BeNil()) - expectedInitialParser := humio.ParserTransform(toCreateParser) + expectedInitialParser := &humiographql.ParserDetails{ + Id: "", + Name: toCreateParser.Spec.Name, + Script: toCreateParser.Spec.ParserScript, + FieldsToTag: toCreateParser.Spec.TagFields, + TestCases: humioapi.TestDataToParserDetailsTestCasesParserTestCase(toCreateParser.Spec.TestData), + } Expect(*initialParser).To(Equal(*expectedInitialParser)) suite.UsingClusterBy(clusterKey.Name, "HumioParser: Updating the parser successfully") updatedScript := "kvParse() | updated" Eventually(func() error { - k8sClient.Get(ctx, key, fetchedParser) + if err := k8sClient.Get(ctx, key, fetchedParser); err != nil { + return err + } fetchedParser.Spec.ParserScript = updatedScript return k8sClient.Update(ctx, fetchedParser) }, testTimeout, suite.TestInterval).Should(Succeed()) - var updatedParser *humioapi.Parser + var updatedParser *humiographql.ParserDetails Eventually(func() error { - updatedParser, err = humioClient.GetParser(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedParser) + updatedParser, err = humioClient.GetParser(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedParser) // Ignore the ID when comparing parser content - updatedParser.ID = "" + updatedParser.Id = "" return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(updatedParser).ToNot(BeNil()) - expectedUpdatedParser := *humio.ParserTransform(fetchedParser) - Eventually(func() humioapi.Parser { - updatedParser, err := humioClient.GetParser(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedParser) + expectedUpdatedParser := &humiographql.ParserDetails{ + Id: "", + Name: fetchedParser.Spec.Name, + Script: fetchedParser.Spec.ParserScript, + FieldsToTag: fetchedParser.Spec.TagFields, + TestCases: humioapi.TestDataToParserDetailsTestCasesParserTestCase(fetchedParser.Spec.TestData), + } + Eventually(func() *humiographql.ParserDetails { + updatedParser, err := humioClient.GetParser(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedParser) if err != nil { - return humioapi.Parser{} + return nil } // Ignore the ID when comparing parser content - updatedParser.ID = "" + updatedParser.Id = "" - return *updatedParser + return updatedParser }, testTimeout, suite.TestInterval).Should(Equal(expectedUpdatedParser)) suite.UsingClusterBy(clusterKey.Name, "HumioParser: Successfully deleting it") @@ -922,7 +980,7 @@ var _ = Describe("Humio Resources Controllers", func() { Name: "example-action", ViewName: testRepo.Spec.Name, EmailProperties: &humiov1alpha1.HumioActionEmailProperties{ - Recipients: []string{"example@example.com"}, + Recipients: []string{EmailActionExample}, }, } @@ -948,9 +1006,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -963,30 +1022,41 @@ var _ = Describe("Humio Resources Controllers", func() { suite.UsingClusterBy(clusterKey.Name, "HumioAction: Waiting for the action to be updated") Eventually(func() error { - k8sClient.Get(ctx, key, fetchedAction) + if err := k8sClient.Get(ctx, key, fetchedAction); err != nil { + return err + } fetchedAction.Spec.EmailProperties = updatedAction.Spec.EmailProperties return k8sClient.Update(ctx, fetchedAction) }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(err).To(BeNil()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the action matches the expected") - Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + Eventually(func() *string { + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { - return "" + return helpers.StringPtr(err.Error()) + } + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsEmailAction: + return v.GetEmailBodyTemplate() } - return updatedAction2.EmailAction.BodyTemplate - }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.EmailProperties.BodyTemplate)) - Expect(updatedAction2.EmailAction.SubjectTemplate).Should(BeEquivalentTo(updatedAction.Spec.EmailProperties.SubjectTemplate)) - Expect(updatedAction2.EmailAction.Recipients).Should(BeEquivalentTo(updatedAction.Spec.EmailProperties.Recipients)) + return nil + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&updatedAction.Spec.EmailProperties.BodyTemplate)) + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsEmailAction: + Expect(v.GetSubjectTemplate()).Should(BeEquivalentTo(&updatedAction.Spec.EmailProperties.SubjectTemplate)) + Expect(v.GetRecipients()).Should(BeEquivalentTo(updatedAction.Spec.EmailProperties.Recipients)) + default: + Fail("got the wrong action type") + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1031,9 +1101,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - action := &humioapi.Action{} + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1055,20 +1126,24 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the humio repo action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the humio repo action matches the expected") Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { return "" } - return updatedAction2.HumioRepoAction.IngestToken + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsHumioRepoAction: + return v.GetIngestToken() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.HumioRepositoryProperties.IngestToken)) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") @@ -1115,9 +1190,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1140,22 +1216,29 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the ops genie action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the ops genie action matches the expected") Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { return "" } - return updatedAction2.OpsGenieAction.GenieKey + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsOpsGenieAction: + return v.GetGenieKey() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.OpsGenieProperties.GenieKey)) - Expect(updatedAction2.OpsGenieAction.ApiUrl).Should(BeEquivalentTo(updatedAction.Spec.OpsGenieProperties.ApiUrl)) + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsOpsGenieAction: + Expect(v.GetApiUrl()).Should(BeEquivalentTo(updatedAction.Spec.OpsGenieProperties.ApiUrl)) + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1201,9 +1284,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1225,22 +1309,29 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the pagerduty action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the pagerduty action matches the expected") Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { return "" } - return updatedAction2.PagerDutyAction.RoutingKey + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsPagerDutyAction: + return v.GetRoutingKey() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.PagerDutyProperties.RoutingKey)) - Expect(updatedAction2.PagerDutyAction.Severity).Should(BeEquivalentTo(updatedAction.Spec.PagerDutyProperties.Severity)) + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsPagerDutyAction: + Expect(v.GetSeverity()).Should(BeEquivalentTo(updatedAction.Spec.PagerDutyProperties.Severity)) + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1288,9 +1379,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1318,26 +1410,33 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the slack post message action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the slack post message action matches the expected") Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { return "" } - return updatedAction2.SlackPostMessageAction.ApiToken + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsSlackPostMessageAction: + return v.GetApiToken() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.SlackPostMessageProperties.ApiToken)) - Expect(updatedAction2.SlackPostMessageAction.Channels).Should(BeEquivalentTo(updatedAction.Spec.SlackPostMessageProperties.Channels)) - Expect(updatedAction2.SlackPostMessageAction.Fields).Should(BeEquivalentTo([]humioapi.SlackFieldEntryInput{{ - FieldName: updatedFieldKey, - Value: updatedFieldValue, - }})) + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsSlackPostMessageAction: + Expect(v.GetChannels()).Should(BeEquivalentTo(updatedAction.Spec.SlackPostMessageProperties.Channels)) + Expect(v.GetFields()).Should(BeEquivalentTo([]humiographql.ActionDetailsFieldsSlackFieldEntry{{ + FieldName: updatedFieldKey, + Value: updatedFieldValue, + }})) + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1384,9 +1483,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1413,25 +1513,32 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the slack action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the slack action matches the expected") Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { return "" } - return updatedAction2.SlackAction.Url + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsSlackAction: + return v.GetUrl() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.SlackProperties.Url)) - Expect(updatedAction2.SlackAction.Fields).Should(BeEquivalentTo([]humioapi.SlackFieldEntryInput{{ - FieldName: updatedFieldKey, - Value: updatedFieldValue, - }})) + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsSlackAction: + Expect(v.GetFields()).Should(BeEquivalentTo([]humiographql.ActionDetailsFieldsSlackFieldEntry{{ + FieldName: updatedFieldKey, + Value: updatedFieldValue, + }})) + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1476,9 +1583,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1501,22 +1609,29 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the victor ops action update succeeded") - var expectedUpdatedAction, updatedAction2 *humioapi.Action + var expectedUpdatedAction, updatedAction2 humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the victor ops action matches the expected") Eventually(func() string { - updatedAction2, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction2, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil { return "" } - return updatedAction2.VictorOpsAction.MessageType + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsVictorOpsAction: + return v.GetMessageType() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedAction.Spec.VictorOpsProperties.MessageType)) - Expect(updatedAction2.VictorOpsAction.NotifyUrl).Should(BeEquivalentTo(updatedAction.Spec.VictorOpsProperties.NotifyUrl)) + switch v := (updatedAction2).(type) { + case *humiographql.ActionDetailsVictorOpsAction: + Expect(v.GetNotifyUrl()).Should(BeEquivalentTo(updatedAction.Spec.VictorOpsProperties.NotifyUrl)) + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1563,9 +1678,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1588,27 +1704,35 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the web hook action update succeeded") - var expectedUpdatedAction, updatedAction *humioapi.Action + var expectedUpdatedAction, updatedAction humiographql.ActionDetails Eventually(func() error { - expectedUpdatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + expectedUpdatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAction).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAction: Verifying the web hook action matches the expected") Eventually(func() string { - updatedAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAction) + updatedAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAction) if err != nil || updatedAction == nil { return "" } - return updatedAction.WebhookAction.Url + switch v := (updatedAction).(type) { + case *humiographql.ActionDetailsWebhookAction: + return v.GetUrl() + } + return "" }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(updatedWebhookActionProperties.Url)) - Expect(updatedAction.WebhookAction.Headers).Should(BeEquivalentTo([]humioapi.HttpHeaderEntryInput{{ - Header: updatedHeaderKey, - Value: updatedHeaderValue, - }})) - Expect(updatedAction.WebhookAction.BodyTemplate).To(BeEquivalentTo(updatedWebhookActionProperties.BodyTemplate)) - Expect(updatedAction.WebhookAction.Method).To(BeEquivalentTo(updatedWebhookActionProperties.Method)) + + switch v := (updatedAction).(type) { + case *humiographql.ActionDetailsWebhookAction: + Expect(v.GetHeaders()).Should(BeEquivalentTo([]humiographql.ActionDetailsHeadersHttpHeaderEntry{{ + Header: updatedHeaderKey, + Value: updatedHeaderValue, + }})) + Expect(v.GetWebhookBodyTemplate()).To(BeEquivalentTo(updatedWebhookActionProperties.BodyTemplate)) + Expect(v.GetMethod()).To(BeEquivalentTo(updatedWebhookActionProperties.Method)) + } suite.UsingClusterBy(clusterKey.Name, "HumioAction: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAction)).To(Succeed()) @@ -1646,9 +1770,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateConfigError)) - var invalidAction *humioapi.Action + var invalidAction humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - invalidAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateInvalidAction) + invalidAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateInvalidAction) if err == nil { suite.UsingClusterBy(clusterKey.Name, fmt.Sprintf("HumioAction: Got the following back even though we did not expect to get anything back: %#+v", invalidAction)) } @@ -1693,9 +1818,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateConfigError)) - var invalidAction *humioapi.Action + var invalidAction humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - invalidAction, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateInvalidAction) + invalidAction, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateInvalidAction) return err }, testTimeout, suite.TestInterval).ShouldNot(Succeed()) Expect(invalidAction).To(BeNil()) @@ -1757,9 +1883,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1827,9 +1954,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1879,9 +2007,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -1949,9 +2078,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2001,9 +2131,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2074,9 +2205,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2128,9 +2260,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2200,9 +2333,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2254,9 +2388,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2324,9 +2459,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2376,9 +2512,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2429,9 +2566,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2500,9 +2638,10 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) @@ -2558,19 +2697,23 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) - Expect(action.WebhookAction.Url).To(Equal(expectedUrl)) - Expect(action.WebhookAction.Headers).Should(ContainElements([]humioapi.HttpHeaderEntryInput{ - { - Header: nonsensitiveHeaderKey, - Value: nonsensitiveHeaderValue, - }, - })) + switch v := (action).(type) { + case *humiographql.ActionDetailsWebhookAction: + Expect(v.GetUrl()).To(Equal(expectedUrl)) + Expect(v.GetHeaders()).Should(ContainElements([]humiographql.ActionDetailsHeadersHttpHeaderEntry{ + { + Header: nonsensitiveHeaderKey, + Value: nonsensitiveHeaderValue, + }, + })) + } // Check the SecretMap rather than the ApiToken on the action apiToken, found := kubernetes.GetSecretForHa(toCreateAction) @@ -2652,23 +2795,27 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) - Expect(action.WebhookAction.Url).To(Equal(expectedUrl)) - Expect(action.WebhookAction.Headers).Should(ContainElements([]humioapi.HttpHeaderEntryInput{ - { - Header: headerKey1, - Value: sensitiveHeaderValue1, - }, - { - Header: headerKey2, - Value: nonsensitiveHeaderValue2, - }, - })) + switch v := (action).(type) { + case *humiographql.ActionDetailsWebhookAction: + Expect(v.GetUrl()).To(Equal(expectedUrl)) + Expect(v.GetHeaders()).Should(ContainElements([]humiographql.ActionDetailsHeadersHttpHeaderEntry{ + { + Header: headerKey1, + Value: sensitiveHeaderValue1, + }, + { + Header: headerKey2, + Value: nonsensitiveHeaderValue2, + }, + })) + } // Check the SecretMap rather than the ApiToken on the action apiToken, found := kubernetes.GetSecretForHa(toCreateAction) @@ -2746,19 +2893,23 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAction.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) - var action *humioapi.Action + var action humiographql.ActionDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - action, err = humioClient.GetAction(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAction) + action, err = humioClient.GetAction(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAction) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(action).ToNot(BeNil()) - Expect(action.WebhookAction.Url).To(Equal(expectedUrl)) - Expect(action.WebhookAction.Headers).Should(ContainElements([]humioapi.HttpHeaderEntryInput{ - { - Header: headerKey, - Value: sensitiveHeaderValue, - }, - })) + switch v := (action).(type) { + case *humiographql.ActionDetailsWebhookAction: + Expect(v.GetUrl()).To(Equal(expectedUrl)) + Expect(v.GetHeaders()).Should(ContainElements([]humiographql.ActionDetailsHeadersHttpHeaderEntry{ + { + Header: headerKey, + Value: sensitiveHeaderValue, + }, + })) + } // Check the SecretMap rather than the ApiToken on the action apiToken, found := kubernetes.GetSecretForHa(toCreateAction) @@ -2787,7 +2938,7 @@ var _ = Describe("Humio Resources Controllers", func() { Name: "example-email-action", ViewName: testRepo.Spec.Name, EmailProperties: &humiov1alpha1.HumioActionEmailProperties{ - Recipients: []string{"example@example.com"}, + Recipients: []string{EmailActionExample}, }, } @@ -2822,7 +2973,7 @@ var _ = Describe("Humio Resources Controllers", func() { Start: "1d", }, ThrottleTimeMillis: 60000, - ThrottleField: "some field", + ThrottleField: helpers.StringPtr("some field"), Silenced: false, Description: "humio alert", Actions: []string{toCreateDependentAction.Spec.Name}, @@ -2851,42 +3002,56 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAlert.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioAlertStateExists)) - var alert *humioapi.Alert + var alert *humiographql.AlertDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - alert, err = humioClient.GetAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAlert) + alert, err = humioClient.GetAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAlert) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(alert).ToNot(BeNil()) - var actionIdMap map[string]string - Eventually(func() error { - actionIdMap, err = humioClient.GetActionIDsMapForAlerts(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAlert) - return err - }, testTimeout, suite.TestInterval).Should(Succeed()) - - originalAlert := humio.AlertTransform(toCreateAlert, actionIdMap) - Expect(alert.Name).To(Equal(originalAlert.Name)) - Expect(alert.Description).To(Equal(originalAlert.Description)) - Expect(alert.Actions).To(Equal(originalAlert.Actions)) - Expect(alert.Labels).To(Equal(originalAlert.Labels)) - Expect(alert.ThrottleTimeMillis).To(Equal(originalAlert.ThrottleTimeMillis)) - Expect(alert.ThrottleField).To(Equal(originalAlert.ThrottleField)) - Expect(alert.Enabled).To(Equal(originalAlert.Enabled)) - Expect(alert.QueryString).To(Equal(originalAlert.QueryString)) - Expect(alert.QueryStart).To(Equal(originalAlert.QueryStart)) + originalAlert := humiographql.AlertDetails{ + Id: "", + Name: toCreateAlert.Spec.Name, + QueryString: toCreateAlert.Spec.Query.QueryString, + QueryStart: toCreateAlert.Spec.Query.Start, + ThrottleField: toCreateAlert.Spec.ThrottleField, + Description: &toCreateAlert.Spec.Description, + ThrottleTimeMillis: int64(toCreateAlert.Spec.ThrottleTimeMillis), + Enabled: !toCreateAlert.Spec.Silenced, + ActionsV2: humioapi.ActionNamesToEmailActions(toCreateAlert.Spec.Actions), + Labels: toCreateAlert.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + Expect(alert.Name).To(Equal(originalAlert.GetName())) + Expect(alert.Description).To(Equal(originalAlert.GetDescription())) + Expect(alert.GetActionsV2()).To(BeEquivalentTo(originalAlert.GetActionsV2())) + Expect(alert.Labels).To(Equal(originalAlert.GetLabels())) + Expect(alert.ThrottleTimeMillis).To(Equal(originalAlert.GetThrottleTimeMillis())) + Expect(alert.ThrottleField).To(Equal(originalAlert.GetThrottleField())) + Expect(alert.Enabled).To(Equal(originalAlert.GetEnabled())) + Expect(alert.QueryString).To(Equal(originalAlert.GetQueryString())) + Expect(alert.QueryStart).To(Equal(originalAlert.GetQueryStart())) suite.UsingClusterBy(clusterKey.Name, "HumioAlert: Updating the alert successfully") updatedAlert := toCreateAlert updatedAlert.Spec.Query.QueryString = "#repo = test | updated=true | count()" updatedAlert.Spec.ThrottleTimeMillis = 70000 - updatedAlert.Spec.ThrottleField = "some other field" + updatedAlert.Spec.ThrottleField = helpers.StringPtr("some other field") updatedAlert.Spec.Silenced = true updatedAlert.Spec.Description = "updated humio alert" updatedAlert.Spec.Actions = []string{toCreateDependentAction.Spec.Name} suite.UsingClusterBy(clusterKey.Name, "HumioAlert: Waiting for the alert to be updated") Eventually(func() error { - k8sClient.Get(ctx, key, fetchedAlert) + if err := k8sClient.Get(ctx, key, fetchedAlert); err != nil { + return err + } fetchedAlert.Spec.Query = updatedAlert.Spec.Query fetchedAlert.Spec.ThrottleTimeMillis = updatedAlert.Spec.ThrottleTimeMillis fetchedAlert.Spec.ThrottleField = updatedAlert.Spec.ThrottleField @@ -2896,28 +3061,43 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAlert: Verifying the alert update succeeded") - var expectedUpdatedAlert *humioapi.Alert + var expectedUpdatedAlert *humiographql.AlertDetails Eventually(func() error { - expectedUpdatedAlert, err = humioClient.GetAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAlert) + expectedUpdatedAlert, err = humioClient.GetAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAlert) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAlert).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAlert: Verifying the alert matches the expected") - verifiedAlert := humio.AlertTransform(updatedAlert, actionIdMap) - Eventually(func() humioapi.Alert { - updatedAlert, err := humioClient.GetAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAlert) + verifiedAlert := humiographql.AlertDetails{ + Id: "", + Name: updatedAlert.Spec.Name, + QueryString: updatedAlert.Spec.Query.QueryString, + QueryStart: updatedAlert.Spec.Query.Start, + ThrottleField: updatedAlert.Spec.ThrottleField, + Description: &updatedAlert.Spec.Description, + ThrottleTimeMillis: int64(updatedAlert.Spec.ThrottleTimeMillis), + Enabled: !updatedAlert.Spec.Silenced, + ActionsV2: humioapi.ActionNamesToEmailActions(updatedAlert.Spec.Actions), + Labels: updatedAlert.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + Eventually(func() *humiographql.AlertDetails { + updatedAlert, err := humioClient.GetAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAlert) if err != nil { - return *updatedAlert + return nil } - // Ignore the ID, QueryOwnershipType and RunAsUserID - updatedAlert.ID = "" - updatedAlert.QueryOwnershipType = "" - updatedAlert.RunAsUserID = "" + // Ignore the ID + updatedAlert.Id = "" - return *updatedAlert - }, testTimeout, suite.TestInterval).Should(Equal(*verifiedAlert)) + return updatedAlert + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&verifiedAlert)) suite.UsingClusterBy(clusterKey.Name, "HumioAlert: Successfully deleting it") Expect(k8sClient.Delete(ctx, fetchedAlert)).To(Succeed()) @@ -2963,10 +3143,10 @@ var _ = Describe("Humio Resources Controllers", func() { suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Should handle filter alert correctly") dependentEmailActionSpec := humiov1alpha1.HumioActionSpec{ ManagedClusterName: clusterKey.Name, - Name: "example-email-action", + Name: "example-email-action4", ViewName: testRepo.Spec.Name, EmailProperties: &humiov1alpha1.HumioActionEmailProperties{ - Recipients: []string{"example@example.com"}, + Recipients: []string{EmailActionExample}, }, } @@ -2993,14 +3173,16 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioActionStateExists)) filterAlertSpec := humiov1alpha1.HumioFilterAlertSpec{ - ManagedClusterName: clusterKey.Name, - Name: "example-filter-alert", - ViewName: testRepo.Spec.Name, - QueryString: "#repo = humio | error = true", - Enabled: true, - Description: "humio filter alert", - Actions: []string{toCreateDependentAction.Spec.Name}, - Labels: []string{"some-label"}, + ManagedClusterName: clusterKey.Name, + Name: "example-filter-alert", + ViewName: testRepo.Spec.Name, + QueryString: "#repo = humio | error = true", + Enabled: true, + Description: "humio filter alert", + Actions: []string{toCreateDependentAction.Spec.Name}, + Labels: []string{"some-label"}, + ThrottleTimeSeconds: 300, + ThrottleField: helpers.StringPtr("somefield"), } key := types.NamespacedName{ @@ -3025,29 +3207,63 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedFilterAlert.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioFilterAlertStateExists)) - var filterAlert *humioapi.FilterAlert + var filterAlert *humiographql.FilterAlertDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - filterAlert, err = humioClient.GetFilterAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateFilterAlert) + filterAlert, err = humioClient.GetFilterAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateFilterAlert) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(filterAlert).ToNot(BeNil()) Eventually(func() error { - return humioClient.ValidateActionsForFilterAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateFilterAlert) + return humioClient.ValidateActionsForFilterAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateFilterAlert) }, testTimeout, suite.TestInterval).Should(Succeed()) - originalFilterAlert := humio.FilterAlertTransform(toCreateFilterAlert) - Expect(filterAlert.Name).To(Equal(originalFilterAlert.Name)) - Expect(filterAlert.Description).To(Equal(originalFilterAlert.Description)) - Expect(filterAlert.ThrottleTimeSeconds).To(Equal(originalFilterAlert.ThrottleTimeSeconds)) - Expect(filterAlert.ThrottleField).To(Equal(originalFilterAlert.ThrottleField)) - Expect(filterAlert.ActionNames).To(Equal(originalFilterAlert.ActionNames)) - Expect(filterAlert.Labels).To(Equal(originalFilterAlert.Labels)) - Expect(filterAlert.Enabled).To(Equal(originalFilterAlert.Enabled)) - Expect(filterAlert.QueryString).To(Equal(originalFilterAlert.QueryString)) + originalFilterAlert := humiographql.FilterAlertDetails{ + Id: "", + Name: toCreateFilterAlert.Spec.Name, + Description: &toCreateFilterAlert.Spec.Description, + QueryString: toCreateFilterAlert.Spec.QueryString, + ThrottleTimeSeconds: helpers.Int64Ptr(int64(toCreateFilterAlert.Spec.ThrottleTimeSeconds)), + ThrottleField: toCreateFilterAlert.Spec.ThrottleField, + Labels: toCreateFilterAlert.Spec.Labels, + Enabled: toCreateFilterAlert.Spec.Enabled, + Actions: humioapi.ActionNamesToEmailActions(toCreateFilterAlert.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + Expect(filterAlert.GetName()).To(Equal(originalFilterAlert.GetName())) + Expect(filterAlert.GetDescription()).To(Equal(originalFilterAlert.GetDescription())) + Expect(filterAlert.GetThrottleTimeSeconds()).To(Equal(originalFilterAlert.GetThrottleTimeSeconds())) + Expect(filterAlert.GetThrottleField()).To(Equal(originalFilterAlert.GetThrottleField())) + Expect(filterAlert.GetActions()).To(BeEquivalentTo(originalFilterAlert.GetActions())) + Expect(filterAlert.GetLabels()).To(Equal(originalFilterAlert.GetLabels())) + Expect(filterAlert.GetEnabled()).To(Equal(originalFilterAlert.GetEnabled())) + Expect(filterAlert.GetQueryString()).To(Equal(originalFilterAlert.GetQueryString())) createdFilterAlert := toCreateFilterAlert - humio.FilterAlertHydrate(createdFilterAlert, filterAlert) + var throttleTimeSeconds int + if filterAlert.ThrottleTimeSeconds != nil { + throttleTimeSeconds = int(*filterAlert.ThrottleTimeSeconds) + } + var description string + if filterAlert.Description != nil { + description = *filterAlert.Description + } + createdFilterAlert.Spec = humiov1alpha1.HumioFilterAlertSpec{ + Name: filterAlert.Name, + QueryString: filterAlert.QueryString, + Description: description, + ThrottleTimeSeconds: throttleTimeSeconds, + ThrottleField: filterAlert.ThrottleField, + Enabled: filterAlert.Enabled, + Actions: humioapi.GetActionNames(filterAlert.Actions), + Labels: filterAlert.Labels, + } Expect(createdFilterAlert.Spec).To(Equal(toCreateFilterAlert.Spec)) suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Updating the filter alert successfully") @@ -3056,12 +3272,14 @@ var _ = Describe("Humio Resources Controllers", func() { updatedFilterAlert.Spec.Enabled = false updatedFilterAlert.Spec.Description = "updated humio filter alert" updatedFilterAlert.Spec.ThrottleTimeSeconds = 3600 - updatedFilterAlert.Spec.ThrottleField = "newfield" + updatedFilterAlert.Spec.ThrottleField = helpers.StringPtr("newfield") updatedFilterAlert.Spec.Actions = []string{toCreateDependentAction.Spec.Name} suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Waiting for the filter alert to be updated") Eventually(func() error { - k8sClient.Get(ctx, key, fetchedFilterAlert) + if err := k8sClient.Get(ctx, key, fetchedFilterAlert); err != nil { + return err + } fetchedFilterAlert.Spec.QueryString = updatedFilterAlert.Spec.QueryString fetchedFilterAlert.Spec.Enabled = updatedFilterAlert.Spec.Enabled fetchedFilterAlert.Spec.Description = updatedFilterAlert.Spec.Description @@ -3071,30 +3289,43 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Verifying the filter alert update succeeded") - var expectedUpdatedFilterAlert *humioapi.FilterAlert + var expectedUpdatedFilterAlert *humiographql.FilterAlertDetails Eventually(func() error { - expectedUpdatedFilterAlert, err = humioClient.GetFilterAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedFilterAlert) + expectedUpdatedFilterAlert, err = humioClient.GetFilterAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedFilterAlert) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedFilterAlert).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Verifying the alert matches the expected") - verifiedFilterAlert := humio.FilterAlertTransform(updatedFilterAlert) - verifiedFilterAlert.ID = "" - verifiedFilterAlert.RunAsUserID = "" + verifiedFilterAlert := humiographql.FilterAlertDetails{ + Id: "", + Name: updatedFilterAlert.Spec.Name, + QueryString: updatedFilterAlert.Spec.QueryString, + Description: &updatedFilterAlert.Spec.Description, + ThrottleTimeSeconds: helpers.Int64Ptr(int64(updatedFilterAlert.Spec.ThrottleTimeSeconds)), + ThrottleField: updatedFilterAlert.Spec.ThrottleField, + Enabled: updatedFilterAlert.Spec.Enabled, + Actions: humioapi.ActionNamesToEmailActions(updatedFilterAlert.Spec.Actions), + Labels: updatedFilterAlert.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } - Eventually(func() humioapi.FilterAlert { - updatedFilterAlert, err := humioClient.GetFilterAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedFilterAlert) + Eventually(func() *humiographql.FilterAlertDetails { + updatedFilterAlert, err := humioClient.GetFilterAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedFilterAlert) if err != nil { - return *updatedFilterAlert + return nil } - // Ignore the ID and RunAsUserID - updatedFilterAlert.ID = "" - updatedFilterAlert.RunAsUserID = "" + // Ignore the ID + updatedFilterAlert.Id = "" - return *updatedFilterAlert - }, testTimeout, suite.TestInterval).Should(Equal(*verifiedFilterAlert)) + return updatedFilterAlert + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&verifiedFilterAlert)) suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Successfully deleting the filter alert") Expect(k8sClient.Delete(ctx, fetchedFilterAlert)).To(Succeed()) @@ -3143,7 +3374,7 @@ var _ = Describe("Humio Resources Controllers", func() { Name: "example-email-action3", ViewName: testRepo.Spec.Name, EmailProperties: &humiov1alpha1.HumioActionEmailProperties{ - Recipients: []string{"example@example.com"}, + Recipients: []string{EmailActionExample}, }, } @@ -3177,7 +3408,7 @@ var _ = Describe("Humio Resources Controllers", func() { QueryTimestampType: "EventTimestamp", SearchIntervalSeconds: 60, ThrottleTimeSeconds: 120, - ThrottleField: "@timestamp", + ThrottleField: helpers.StringPtr("@timestamp"), TriggerMode: "ImmediateMode", Enabled: true, Description: "humio aggregate alert", @@ -3207,27 +3438,59 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedAggregateAlert.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioAggregateAlertStateExists)) - var aggregateAlert *humioapi.AggregateAlert + var aggregateAlert *humiographql.AggregateAlertDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - aggregateAlert, err = humioClient.GetAggregateAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAggregateAlert) + aggregateAlert, err = humioClient.GetAggregateAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAggregateAlert) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(aggregateAlert).ToNot(BeNil()) Eventually(func() error { - return humioClient.ValidateActionsForAggregateAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAggregateAlert) - }, testTimeout, suite.TestInterval).Should(Succeed()) - - originalAggregateAlert := humio.AggregateAlertTransform(toCreateAggregateAlert) - Expect(aggregateAlert.Name).To(Equal(originalAggregateAlert.Name)) - Expect(aggregateAlert.Description).To(Equal(originalAggregateAlert.Description)) - Expect(aggregateAlert.ThrottleTimeSeconds).To(Equal(originalAggregateAlert.ThrottleTimeSeconds)) - Expect(aggregateAlert.ThrottleField).To(Equal(originalAggregateAlert.ThrottleField)) - Expect(aggregateAlert.ActionNames).To(Equal(originalAggregateAlert.ActionNames)) - Expect(aggregateAlert.Labels).To(Equal(originalAggregateAlert.Labels)) + return humioClient.ValidateActionsForAggregateAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateAggregateAlert) + }, testTimeout, suite.TestInterval).Should(Succeed()) + + originalAggregateAlert := humiographql.AggregateAlertDetails{ + Id: "", + Name: toCreateAggregateAlert.Spec.Name, + Description: &toCreateAggregateAlert.Spec.Description, + QueryString: toCreateAggregateAlert.Spec.QueryString, + SearchIntervalSeconds: int64(toCreateAggregateAlert.Spec.SearchIntervalSeconds), + ThrottleTimeSeconds: int64(toCreateAggregateAlert.Spec.ThrottleTimeSeconds), + ThrottleField: toCreateAggregateAlert.Spec.ThrottleField, + Labels: toCreateAggregateAlert.Spec.Labels, + Enabled: toCreateAggregateAlert.Spec.Enabled, + TriggerMode: humiographql.TriggerMode(toCreateAggregateAlert.Spec.TriggerMode), + QueryTimestampType: humiographql.QueryTimestampType(toCreateAggregateAlert.Spec.QueryTimestampType), + Actions: humioapi.ActionNamesToEmailActions(toCreateAggregateAlert.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + Expect(aggregateAlert.GetName()).To(Equal(originalAggregateAlert.GetName())) + Expect(aggregateAlert.GetDescription()).To(Equal(originalAggregateAlert.GetDescription())) + Expect(aggregateAlert.GetThrottleTimeSeconds()).To(Equal(originalAggregateAlert.GetThrottleTimeSeconds())) + Expect(aggregateAlert.GetThrottleField()).To(Equal(originalAggregateAlert.GetThrottleField())) + Expect(aggregateAlert.GetLabels()).To(Equal(originalAggregateAlert.GetLabels())) + Expect(humioapi.GetActionNames(aggregateAlert.GetActions())).To(Equal(humioapi.GetActionNames(originalAggregateAlert.GetActions()))) createdAggregateAlert := toCreateAggregateAlert - humio.AggregateAlertHydrate(createdAggregateAlert, aggregateAlert) + createdAggregateAlert.Spec = humiov1alpha1.HumioAggregateAlertSpec{ + Name: aggregateAlert.Name, + QueryString: aggregateAlert.QueryString, + QueryTimestampType: string(aggregateAlert.QueryTimestampType), + Description: *aggregateAlert.Description, + SearchIntervalSeconds: int(aggregateAlert.SearchIntervalSeconds), + ThrottleTimeSeconds: int(aggregateAlert.ThrottleTimeSeconds), + ThrottleField: aggregateAlert.ThrottleField, + TriggerMode: string(aggregateAlert.TriggerMode), + Enabled: aggregateAlert.Enabled, + Actions: humioapi.GetActionNames(aggregateAlert.GetActions()), + Labels: aggregateAlert.Labels, + } Expect(err).To(BeNil()) Expect(createdAggregateAlert.Spec).To(Equal(toCreateAggregateAlert.Spec)) @@ -3238,13 +3501,15 @@ var _ = Describe("Humio Resources Controllers", func() { updatedAggregateAlert.Spec.Description = "updated humio aggregate alert" updatedAggregateAlert.Spec.SearchIntervalSeconds = 120 updatedAggregateAlert.Spec.ThrottleTimeSeconds = 3600 - updatedAggregateAlert.Spec.ThrottleField = "newfield" + updatedAggregateAlert.Spec.ThrottleField = helpers.StringPtr("newfield") updatedAggregateAlert.Spec.Actions = []string{toCreateDependentAction.Spec.Name} updatedAggregateAlert.Spec.TriggerMode = "CompleteMode" suite.UsingClusterBy(clusterKey.Name, "HumioAggregateAlert: Waiting for the aggregate alert to be updated") Eventually(func() error { - k8sClient.Get(ctx, key, fetchedAggregateAlert) + if err := k8sClient.Get(ctx, key, fetchedAggregateAlert); err != nil { + return err + } fetchedAggregateAlert.Spec.QueryString = updatedAggregateAlert.Spec.QueryString fetchedAggregateAlert.Spec.Enabled = updatedAggregateAlert.Spec.Enabled fetchedAggregateAlert.Spec.Description = updatedAggregateAlert.Spec.Description @@ -3258,30 +3523,46 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioAggregateAlert: Verifying the aggregate alert update succeeded") - var expectedUpdatedAggregateAlert *humioapi.AggregateAlert + var expectedUpdatedAggregateAlert *humiographql.AggregateAlertDetails Eventually(func() error { - expectedUpdatedAggregateAlert, err = humioClient.GetAggregateAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAggregateAlert) + expectedUpdatedAggregateAlert, err = humioClient.GetAggregateAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAggregateAlert) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedAggregateAlert).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAggregateAlert: Verifying the alert matches the expected") - verifiedAggregateAlert := humio.AggregateAlertTransform(updatedAggregateAlert) - verifiedAggregateAlert.ID = "" - verifiedAggregateAlert.RunAsUserID = "" + verifiedAggregateAlert := humiographql.AggregateAlertDetails{ + Id: "", + Name: updatedAggregateAlert.Spec.Name, + Description: &updatedAggregateAlert.Spec.Description, + QueryString: updatedAggregateAlert.Spec.QueryString, + SearchIntervalSeconds: int64(updatedAggregateAlert.Spec.SearchIntervalSeconds), + ThrottleTimeSeconds: int64(updatedAggregateAlert.Spec.ThrottleTimeSeconds), + ThrottleField: updatedAggregateAlert.Spec.ThrottleField, + Labels: updatedAggregateAlert.Spec.Labels, + Enabled: updatedAggregateAlert.Spec.Enabled, + TriggerMode: humiographql.TriggerMode(updatedAggregateAlert.Spec.TriggerMode), + QueryTimestampType: humiographql.QueryTimestampType(updatedAggregateAlert.Spec.QueryTimestampType), + Actions: humioapi.ActionNamesToEmailActions(updatedAggregateAlert.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } - Eventually(func() humioapi.AggregateAlert { - updatedAggregateAlert, err := humioClient.GetAggregateAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAggregateAlert) + Eventually(func() *humiographql.AggregateAlertDetails { + updatedAggregateAlert, err := humioClient.GetAggregateAlert(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedAggregateAlert) if err != nil { - return *updatedAggregateAlert + return nil } - // Ignore the ID and RunAsUserID - updatedAggregateAlert.ID = "" - updatedAggregateAlert.RunAsUserID = "" + // Ignore the ID + updatedAggregateAlert.Id = "" - return *updatedAggregateAlert - }, testTimeout, suite.TestInterval).Should(Equal(*verifiedAggregateAlert)) + return updatedAggregateAlert + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&verifiedAggregateAlert)) suite.UsingClusterBy(clusterKey.Name, "HumioAggregateAlert: Successfully deleting the aggregate alert") Expect(k8sClient.Delete(ctx, fetchedAggregateAlert)).To(Succeed()) @@ -3329,7 +3610,7 @@ var _ = Describe("Humio Resources Controllers", func() { Name: "example-email-action2", ViewName: testRepo.Spec.Name, EmailProperties: &humiov1alpha1.HumioActionEmailProperties{ - Recipients: []string{"example@example.com"}, + Recipients: []string{EmailActionExample}, }, } @@ -3393,32 +3674,48 @@ var _ = Describe("Humio Resources Controllers", func() { return fetchedScheduledSearch.Status.State }, testTimeout, suite.TestInterval).Should(Equal(humiov1alpha1.HumioScheduledSearchStateExists)) - var scheduledSearch *humioapi.ScheduledSearch + var scheduledSearch *humiographql.ScheduledSearchDetails + humioHttpClient := humioClient.GetHumioHttpClient(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}) Eventually(func() error { - scheduledSearch, err = humioClient.GetScheduledSearch(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateScheduledSearch) + scheduledSearch, err = humioClient.GetScheduledSearch(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateScheduledSearch) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(scheduledSearch).ToNot(BeNil()) Eventually(func() error { - return humioClient.ValidateActionsForScheduledSearch(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateScheduledSearch) + return humioClient.ValidateActionsForScheduledSearch(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, toCreateScheduledSearch) }, testTimeout, suite.TestInterval).Should(Succeed()) - originalScheduledSearch := humio.ScheduledSearchTransform(toCreateScheduledSearch) - Expect(scheduledSearch.Name).To(Equal(originalScheduledSearch.Name)) - Expect(scheduledSearch.Description).To(Equal(originalScheduledSearch.Description)) - Expect(scheduledSearch.ActionNames).To(Equal(originalScheduledSearch.ActionNames)) - Expect(scheduledSearch.Labels).To(Equal(originalScheduledSearch.Labels)) - Expect(scheduledSearch.Enabled).To(Equal(originalScheduledSearch.Enabled)) - Expect(scheduledSearch.QueryString).To(Equal(originalScheduledSearch.QueryString)) - Expect(scheduledSearch.QueryStart).To(Equal(originalScheduledSearch.QueryStart)) - Expect(scheduledSearch.QueryEnd).To(Equal(originalScheduledSearch.QueryEnd)) - Expect(scheduledSearch.Schedule).To(Equal(originalScheduledSearch.Schedule)) - Expect(scheduledSearch.TimeZone).To(Equal(originalScheduledSearch.TimeZone)) - Expect(scheduledSearch.BackfillLimit).To(Equal(originalScheduledSearch.BackfillLimit)) + Expect(humioapi.GetActionNames(scheduledSearch.ActionsV2)).To(Equal(toCreateScheduledSearch.Spec.Actions)) + Expect(scheduledSearch.Name).To(Equal(toCreateScheduledSearch.Spec.Name)) + Expect(scheduledSearch.Description).To(Equal(&toCreateScheduledSearch.Spec.Description)) + Expect(scheduledSearch.Labels).To(Equal(toCreateScheduledSearch.Spec.Labels)) + Expect(scheduledSearch.Enabled).To(Equal(toCreateScheduledSearch.Spec.Enabled)) + Expect(scheduledSearch.QueryString).To(Equal(toCreateScheduledSearch.Spec.QueryString)) + Expect(scheduledSearch.Start).To(Equal(toCreateScheduledSearch.Spec.QueryStart)) + Expect(scheduledSearch.End).To(Equal(toCreateScheduledSearch.Spec.QueryEnd)) + Expect(scheduledSearch.Schedule).To(Equal(toCreateScheduledSearch.Spec.Schedule)) + Expect(scheduledSearch.TimeZone).To(Equal(toCreateScheduledSearch.Spec.TimeZone)) + Expect(scheduledSearch.BackfillLimit).To(Equal(toCreateScheduledSearch.Spec.BackfillLimit)) createdScheduledSearch := toCreateScheduledSearch - humio.ScheduledSearchHydrate(createdScheduledSearch, scheduledSearch) + var description string + if scheduledSearch.Description != nil { + description = *scheduledSearch.Description + } + createdScheduledSearch.Spec = humiov1alpha1.HumioScheduledSearchSpec{ + Name: scheduledSearch.Name, + QueryString: scheduledSearch.QueryString, + Description: description, + QueryStart: scheduledSearch.Start, + QueryEnd: scheduledSearch.End, + Schedule: scheduledSearch.Schedule, + TimeZone: scheduledSearch.TimeZone, + BackfillLimit: scheduledSearch.BackfillLimit, + Enabled: scheduledSearch.Enabled, + Actions: humioapi.GetActionNames(scheduledSearch.ActionsV2), + Labels: scheduledSearch.Labels, + } Expect(createdScheduledSearch.Spec).To(Equal(toCreateScheduledSearch.Spec)) suite.UsingClusterBy(clusterKey.Name, "HumioScheduledSearch: Updating the scheduled search successfully") @@ -3448,30 +3745,45 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) suite.UsingClusterBy(clusterKey.Name, "HumioScheduledSearch: Verifying the scheduled search update succeeded") - var expectedUpdatedScheduledSearch *humioapi.ScheduledSearch + var expectedUpdatedScheduledSearch *humiographql.ScheduledSearchDetails Eventually(func() error { - expectedUpdatedScheduledSearch, err = humioClient.GetScheduledSearch(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedScheduledSearch) + expectedUpdatedScheduledSearch, err = humioClient.GetScheduledSearch(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedScheduledSearch) return err }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(expectedUpdatedScheduledSearch).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioScheduledSearch: Verifying the scheduled search matches the expected") - verifiedScheduledSearch := humio.ScheduledSearchTransform(updatedScheduledSearch) - verifiedScheduledSearch.ID = "" - verifiedScheduledSearch.RunAsUserID = "" + verifiedScheduledSearch := humiographql.ScheduledSearchDetails{ + Name: updatedScheduledSearch.Spec.Name, + QueryString: updatedScheduledSearch.Spec.QueryString, + Description: &updatedScheduledSearch.Spec.Description, + Start: updatedScheduledSearch.Spec.QueryStart, + End: updatedScheduledSearch.Spec.QueryEnd, + Schedule: updatedScheduledSearch.Spec.Schedule, + TimeZone: updatedScheduledSearch.Spec.TimeZone, + BackfillLimit: updatedScheduledSearch.Spec.BackfillLimit, + Enabled: updatedScheduledSearch.Spec.Enabled, + ActionsV2: humioapi.ActionNamesToEmailActions(updatedScheduledSearch.Spec.Actions), + Labels: updatedScheduledSearch.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } - Eventually(func() humioapi.ScheduledSearch { - updatedScheduledSearch, err := humioClient.GetScheduledSearch(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedScheduledSearch) + Eventually(func() *humiographql.ScheduledSearchDetails { + updatedScheduledSearch, err := humioClient.GetScheduledSearch(ctx, humioHttpClient, reconcile.Request{NamespacedName: clusterKey}, fetchedScheduledSearch) if err != nil { - return *updatedScheduledSearch + return nil } - // Ignore the ID and RunAsUserID - updatedScheduledSearch.ID = "" - updatedScheduledSearch.RunAsUserID = "" + // Ignore the ID + updatedScheduledSearch.Id = "" - return *updatedScheduledSearch - }, testTimeout, suite.TestInterval).Should(Equal(*verifiedScheduledSearch)) + return updatedScheduledSearch + }, testTimeout, suite.TestInterval).Should(BeEquivalentTo(&verifiedScheduledSearch)) suite.UsingClusterBy(clusterKey.Name, "HumioScheduledSearch: Successfully deleting the scheduled search") Expect(k8sClient.Delete(ctx, fetchedScheduledSearch)).To(Succeed()) @@ -3515,10 +3827,10 @@ var _ = Describe("Humio Resources Controllers", func() { type repositoryExpectation struct { Name string - Description string - RetentionDays float64 `graphql:"timeBasedRetention"` - IngestRetentionSizeGB float64 `graphql:"ingestSizeBasedRetention"` - StorageRetentionSizeGB float64 `graphql:"storageSizeBasedRetention"` - SpaceUsed int64 `graphql:"compressedByteSize"` + Description *string + RetentionDays *float64 + IngestRetentionSizeGB *float64 + StorageRetentionSizeGB *float64 + SpaceUsed int64 AutomaticSearch bool } diff --git a/controllers/suite/resources/suite_test.go b/controllers/suite/resources/suite_test.go index a8e200b0..f15104c8 100644 --- a/controllers/suite/resources/suite_test.go +++ b/controllers/suite/resources/suite_test.go @@ -25,7 +25,9 @@ import ( "testing" "time" - "github.com/humio/humio-operator/pkg/kubernetes" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" + "github.com/humio/humio-operator/internal/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/client-go/rest" @@ -43,9 +45,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "k8s.io/client-go/kubernetes/scheme" @@ -340,24 +339,38 @@ var _ = BeforeSuite(func() { var _ = AfterSuite(func() { if k8sClient != nil { - Expect(k8sClient.Delete(context.TODO(), &corev1alpha1.HumioRepository{ - ObjectMeta: metav1.ObjectMeta{ - Name: testRepo.Name, - Namespace: testRepo.Namespace, - }, - })).To(Succeed()) - Expect(k8sClient.Delete(context.TODO(), &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: testService1.Name, - Namespace: testService1.Namespace, - }, - })).To(Succeed()) - Expect(k8sClient.Delete(context.TODO(), &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: testService2.Name, - Namespace: testService2.Namespace, - }, - })).To(Succeed()) + if testRepo.Name != "" { + Expect(k8sClient.Delete(context.TODO(), &corev1alpha1.HumioRepository{ + ObjectMeta: metav1.ObjectMeta{ + Name: testRepo.Name, + Namespace: testRepo.Namespace, + }, + })).To(Succeed()) + Eventually(func() bool { + return k8serrors.IsNotFound( + k8sClient.Get(ctx, types.NamespacedName{ + Name: testRepo.Name, + Namespace: testRepo.Namespace, + }, &corev1alpha1.HumioRepository{}), + ) + }, testTimeout, suite.TestInterval).Should(BeTrue()) + } + if testService1.Name != "" { + Expect(k8sClient.Delete(context.TODO(), &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: testService1.Name, + Namespace: testService1.Namespace, + }, + })).To(Succeed()) + } + if testService2.Name != "" { + Expect(k8sClient.Delete(context.TODO(), &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: testService2.Name, + Namespace: testService2.Namespace, + }, + })).To(Succeed()) + } suite.UsingClusterBy(clusterKey.Name, "HumioCluster: Confirming resource generation wasn't updated excessively") Expect(k8sClient.Get(context.Background(), clusterKey, cluster)).Should(Succeed()) @@ -375,7 +388,7 @@ var _ = AfterSuite(func() { })).To(Succeed()) } - if testNamespace.ObjectMeta.Name != "" && !helpers.UseEnvtest() && helpers.PreserveKindCluster() { + if testNamespace.Name != "" && !helpers.UseEnvtest() && helpers.PreserveKindCluster() { By(fmt.Sprintf("Removing test namespace: %s", clusterKey.Namespace)) err := k8sClient.Delete(context.TODO(), &testNamespace) Expect(err).ToNot(HaveOccurred()) diff --git a/controllers/versions/versions.go b/controllers/versions/versions.go index df2f2079..ac9a9bdb 100644 --- a/controllers/versions/versions.go +++ b/controllers/versions/versions.go @@ -3,24 +3,24 @@ package versions import ( "strings" - "github.com/humio/humio-operator/pkg/helpers" + "github.com/humio/humio-operator/internal/helpers" ) const ( defaultHelperImageVersion = "humio/humio-operator-helper:0801827ac0aeec0976097099ae00742209677a70" - defaultHumioImageVersion = "humio/humio-core:1.153.3" + defaultHumioImageVersion = "humio/humio-core:1.159.1" - oldSupportedHumioVersion = "humio/humio-core:1.118.0" - upgradeJumpHumioVersion = "humio/humio-core:1.128.0" + oldSupportedHumioVersion = "humio/humio-core:1.130.0" + upgradeJumpHumioVersion = "humio/humio-core:1.142.3" oldUnsupportedHumioVersion = "humio/humio-core:1.18.4" upgradeHelperImageVersion = "humio/humio-operator-helper:master" - upgradePatchBestEffortOldVersion = "humio/humio-core:1.124.1" - upgradePatchBestEffortNewVersion = "humio/humio-core:1.124.2" + upgradePatchBestEffortOldVersion = "humio/humio-core:1.136.1" + upgradePatchBestEffortNewVersion = "humio/humio-core:1.136.2" - upgradeRollingBestEffortVersionJumpOldVersion = "humio/humio-core:1.124.1" - upgradeRollingBestEffortVersionJumpNewVersion = "humio/humio-core:1.131.1" + upgradeRollingBestEffortVersionJumpOldVersion = "humio/humio-core:1.136.1" + upgradeRollingBestEffortVersionJumpNewVersion = "humio/humio-core:1.142.3" sidecarWaitForGlobalImageVersion = "alpine:20240329" diff --git a/go.mod b/go.mod index e1214074..7738ea01 100644 --- a/go.mod +++ b/go.mod @@ -3,17 +3,17 @@ module github.com/humio/humio-operator go 1.22 require ( + github.com/Khan/genqlient v0.7.0 github.com/Masterminds/semver/v3 v3.2.1 github.com/cert-manager/cert-manager v1.12.14 - github.com/cli/shurcooL-graphql v0.0.4 github.com/go-jose/go-jose/v4 v4.0.1 github.com/go-logr/logr v1.4.1 github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 - github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.34.1 github.com/prometheus/client_golang v1.19.0 + github.com/vektah/gqlparser/v2 v2.5.20 go.uber.org/zap v1.27.0 k8s.io/api v0.29.7 k8s.io/apimachinery v0.29.7 @@ -23,6 +23,9 @@ require ( ) require ( + github.com/agnivade/levenshtein v1.2.0 // indirect + github.com/alexflint/go-arg v1.4.2 // indirect + github.com/alexflint/go-scalar v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -59,6 +62,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sync v0.10.0 // indirect diff --git a/go.sum b/go.sum index a41552b6..f5d7cfe9 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,33 @@ +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY= +github.com/agnivade/levenshtein v1.2.0/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= +github.com/alexflint/go-arg v1.4.2 h1:lDWZAXxpAnZUq4qwb86p/3rIJJ2Li81EoMbTMujhVa0= +github.com/alexflint/go-arg v1.4.2/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM= +github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70= +github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs= +github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/cert-manager/cert-manager v1.12.14 h1:EyQMXPzIHcuXVu2kV4gKgEFQw3K/jMUkIyZhOWStz9I= github.com/cert-manager/cert-manager v1.12.14/go.mod h1:nApwszKTPUxB+gMZ2SeKtHWVojqJsuWplKvF+qb3fj8= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJu2GuY= -github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= +github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= @@ -57,8 +71,6 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce h1:WRVLad++Yerg08UcQCzAXY9UwV0P7U1lkOvrdMYUjVY= -github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -102,12 +114,17 @@ github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGK github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.20 h1:kPaWbhBntxoZPaNdBaIPT1Kh0i1b/onb5kXgEdP5JCo= +github.com/vektah/gqlparser/v2 v2.5.20/go.mod h1:xMl+ta8a5M1Yo1A1Iwt/k7gSpscwSnHZdw7tfhEGfTM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -125,6 +142,8 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/hack/run-e2e-within-kind-test-pod.sh b/hack/run-e2e-within-kind-test-pod.sh index 76de4515..22212a62 100755 --- a/hack/run-e2e-within-kind-test-pod.sh +++ b/hack/run-e2e-within-kind-test-pod.sh @@ -5,4 +5,4 @@ set -x -o pipefail source hack/functions.sh # We skip the helpers package as those tests assumes the environment variable USE_CERT_MANAGER is not set. -ginkgo --label-filter=real -timeout 120m -procs=$GINKGO_NODES --no-color --skip-package helpers -v ./controllers/suite/... -covermode=count -coverprofile cover.out -progress | tee /proc/1/fd/1 +ginkgo --label-filter=real -timeout 120m -procs=$GINKGO_NODES --no-color --skip-package helpers -v ./controllers/suite/... -covermode=count -coverprofile cover.out -progress | tee /proc/1/fd/1 \ No newline at end of file diff --git a/internal/api/client.go b/internal/api/client.go new file mode 100644 index 00000000..c649d8f6 --- /dev/null +++ b/internal/api/client.go @@ -0,0 +1,299 @@ +package api + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/Khan/genqlient/graphql" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/vektah/gqlparser/v2/ast" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +const defaultUserAgent = "Humio-go-client/unknown" + +type Client struct { + config Config + httpTransport *http.Transport +} + +type Response struct { + Data interface{} `json:"data"` + Extensions map[string]interface{} `json:"extensions,omitempty"` + Errors ErrorList `json:"errors,omitempty"` +} + +type ErrorList []*GraphqlError + +type GraphqlError struct { + Err error `json:"-"` + Message string `json:"message"` + Path ast.Path `json:"path,omitempty"` + Locations []gqlerror.Location `json:"locations,omitempty"` + Extensions map[string]interface{} `json:"extensions,omitempty"` + Rule string `json:"-"` + State map[string]string `json:"state,omitempty"` +} + +func (err *GraphqlError) Error() string { + var res bytes.Buffer + if err == nil { + return "" + } + filename, _ := err.Extensions["file"].(string) + if filename == "" { + filename = "input" + } + + res.WriteString(filename) + + if len(err.Locations) > 0 { + res.WriteByte(':') + res.WriteString(strconv.Itoa(err.Locations[0].Line)) + } + + res.WriteString(": ") + if ps := err.pathString(); ps != "" { + res.WriteString(ps) + res.WriteByte(' ') + } + + for key, value := range err.State { + res.WriteString(fmt.Sprintf("(%s: %s) ", key, value)) + } + + res.WriteString(err.Message) + + return res.String() +} +func (err *GraphqlError) pathString() string { + return err.Path.String() +} + +func (errs ErrorList) Error() string { + var buf bytes.Buffer + for _, err := range errs { + buf.WriteString(err.Error()) + buf.WriteByte('\n') + } + return buf.String() +} + +func (c *Client) MakeRequest(ctx context.Context, req *graphql.Request, resp *graphql.Response) error { + var httpReq *http.Request + var err error + + body, err := json.Marshal(req) + if err != nil { + return err + } + graphqlURL, err := c.Address().Parse("graphql") + if err != nil { + return nil + } + httpReq, err = http.NewRequest( + http.MethodPost, + graphqlURL.String(), + bytes.NewReader(body)) + if err != nil { + return err + } + + httpReq.Header.Set("Content-Type", JSONContentType) + + if ctx != nil { + httpReq = httpReq.WithContext(ctx) + } + httpClient := c.newHTTPClientWithHeaders(c.headers()) + httpResp, err := httpClient.Do(httpReq) + if err != nil { + return err + } + if httpResp == nil { + return fmt.Errorf("could not execute http request") + } + defer httpResp.Body.Close() + + if httpResp.StatusCode != http.StatusOK { + var respBody []byte + respBody, err = io.ReadAll(httpResp.Body) + if err != nil { + respBody = []byte(fmt.Sprintf("", err)) + } + return fmt.Errorf("returned error %v: %s", httpResp.Status, respBody) + } + + var actualResponse Response + actualResponse.Data = resp.Data + + err = json.NewDecoder(httpResp.Body).Decode(&actualResponse) + resp.Extensions = actualResponse.Extensions + for _, actualError := range actualResponse.Errors { + gqlError := gqlerror.Error{ + Err: actualError.Err, + Message: actualError.Message, + Path: actualError.Path, + Locations: actualError.Locations, + Extensions: actualError.Extensions, + Rule: actualError.Rule, + } + resp.Errors = append(resp.Errors, &gqlError) + } + if err != nil { + return err + } + + // This prints all extensions. To use this properly, use a logger + //if len(actualResponse.Extensions) > 0 { + // for _, extension := range resp.Extensions { + // fmt.Printf("%v\n", extension) + // } + //} + if len(actualResponse.Errors) > 0 { + return actualResponse.Errors + } + return nil +} + +type Config struct { + Address *url.URL + UserAgent string + Token string + CACertificatePEM string + Insecure bool + DialContext func(ctx context.Context, network, addr string) (net.Conn, error) +} + +func (c *Client) Address() *url.URL { + return c.config.Address +} + +func (c *Client) Token() string { + return c.config.Token +} + +func (c *Client) Config() Config { + return c.config +} + +func NewClient(config Config) *Client { + httpTransport := NewHttpTransport(config) + return NewClientWithTransport(config, httpTransport) +} + +func NewClientWithTransport(config Config, httpTransport *http.Transport) *Client { + if config.Address != nil && !strings.HasSuffix(config.Address.Path, "/") { + config.Address.Path = config.Address.Path + "/" + } + + if config.UserAgent == "" { + config.UserAgent = defaultUserAgent + } + + return &Client{ + config: config, + httpTransport: httpTransport, + } +} + +func (c *Client) headers() map[string]string { + headers := map[string]string{} + + if c.Token() != "" { + headers["Authorization"] = fmt.Sprintf("Bearer %s", c.Token()) + } + + if c.config.UserAgent != "" { + headers["User-Agent"] = c.config.UserAgent + } + + return headers +} + +// JSONContentType is "application/json" +const JSONContentType string = "application/json" + +func (c *Client) HTTPRequestContext(ctx context.Context, httpMethod string, path string, body io.Reader, contentType string) (*http.Response, error) { + if body == nil { + body = bytes.NewReader(nil) + } + + parsedUrl, err := c.Address().Parse(path) + if err != nil { + return nil, err + } + + req, reqErr := http.NewRequestWithContext(ctx, httpMethod, parsedUrl.String(), body) + if reqErr != nil { + return nil, reqErr + } + + headers := c.headers() + headers["Content-Type"] = contentType + + var client = c.newHTTPClientWithHeaders(headers) + return client.Do(req) +} + +// GetActionNames takes a list of humiographql.SharedActionNameType and returns a string slice with names of all the actions +func GetActionNames(o []humiographql.SharedActionNameType) []string { + actionNames := make([]string, len(o)) + for i := range o { + actionNames[i] = o[i].GetName() + } + return actionNames +} + +func TestDataToParserTestCaseInput(o []string) []humiographql.ParserTestCaseInput { + testCasesInput := make([]humiographql.ParserTestCaseInput, len(o)) + for i := range o { + testCasesInput[i] = humiographql.ParserTestCaseInput{ + Event: humiographql.ParserTestEventInput{RawString: o[i]}, + OutputAssertions: []humiographql.ParserTestCaseAssertionsForOutputInput{}, + } + } + return testCasesInput +} + +func TestDataToParserDetailsTestCasesParserTestCase(o []string) []humiographql.ParserDetailsTestCasesParserTestCase { + testCases := make([]humiographql.ParserDetailsTestCasesParserTestCase, len(o)) + for i := range o { + testCases[i] = humiographql.ParserDetailsTestCasesParserTestCase{ + Event: humiographql.ParserDetailsTestCasesParserTestCaseEventParserTestEvent{ + RawString: o[i], + }, + OutputAssertions: []humiographql.ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput{}, + } + } + return testCases +} + +func ActionNamesToEmailActions(o []string) []humiographql.SharedActionNameType { + emailTypeName := "EmailAction" + actions := make([]humiographql.SharedActionNameType, len(o)) + for i := range o { + actions[i] = &humiographql.SharedActionNameTypeEmailAction{ + Typename: &emailTypeName, + ActionNameEmailAction: humiographql.ActionNameEmailAction{ + Name: o[i], + }, + } + } + return actions +} + +func QueryOwnershipIsOrganizationOwnership(v humiographql.SharedQueryOwnershipType) bool { + switch v.(type) { + case *humiographql.SharedQueryOwnershipTypeOrganizationOwnership: + return true + } + return false +} diff --git a/internal/api/error.go b/internal/api/error.go new file mode 100644 index 00000000..27100d44 --- /dev/null +++ b/internal/api/error.go @@ -0,0 +1,119 @@ +package api + +import ( + "fmt" +) + +type entityType string + +const ( + entityTypeSearchDomain entityType = "search-domain" + entityTypeRepository entityType = "repository" + entityTypeView entityType = "view" + entityTypeIngestToken entityType = "ingest-token" + entityTypeParser entityType = "parser" + entityTypeAction entityType = "action" + entityTypeAlert entityType = "alert" + entityTypeFilterAlert entityType = "filter-alert" + entityTypeScheduledSearch entityType = "scheduled-search" + entityTypeAggregateAlert entityType = "aggregate-alert" + entityTypeUser entityType = "user" +) + +func (e entityType) String() string { + return string(e) +} + +type EntityNotFound struct { + entityType entityType + key string +} + +func (e EntityNotFound) EntityType() entityType { + return e.entityType +} + +func (e EntityNotFound) Key() string { + return e.key +} + +func (e EntityNotFound) Error() string { + return fmt.Sprintf("%s %q not found", e.entityType.String(), e.key) +} + +func SearchDomainNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeSearchDomain, + key: name, + } +} + +func RepositoryNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeRepository, + key: name, + } +} + +func ViewNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeView, + key: name, + } +} + +func IngestTokenNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeIngestToken, + key: name, + } +} + +func ParserNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeParser, + key: name, + } +} + +func ActionNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeAction, + key: name, + } +} + +func AlertNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeAlert, + key: name, + } +} + +func FilterAlertNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeFilterAlert, + key: name, + } +} + +func ScheduledSearchNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeScheduledSearch, + key: name, + } +} + +func AggregateAlertNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeAggregateAlert, + key: name, + } +} + +func UserNotFound(name string) error { + return EntityNotFound{ + entityType: entityTypeUser, + key: name, + } +} diff --git a/internal/api/httpclient.go b/internal/api/httpclient.go new file mode 100644 index 00000000..dbfde9c9 --- /dev/null +++ b/internal/api/httpclient.go @@ -0,0 +1,120 @@ +package api + +import ( + "crypto/tls" + "crypto/x509" + "net" + "net/http" + "time" +) + +// We must our own http.Client which adds the authorization header in all requests sent to Humio. +// We use the approach described here: https://github.com/shurcooL/graphql/issues/28#issuecomment-464713908 + +type headerTransport struct { + base http.RoundTripper + headers map[string]string +} + +func NewHttpTransport(config Config) *http.Transport { + dialContext := config.DialContext + if dialContext == nil { + dialContext = (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext + } + + if config.Insecure { + // Return HTTP transport where we skip certificate verification + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: config.Insecure, // #nosec G402 + }, + } + } + + if len(config.CACertificatePEM) > 0 { + // Create a certificate pool and return a HTTP transport with the specified specified CA certificate. + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM([]byte(config.CACertificatePEM)) + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + + TLSClientConfig: &tls.Config{ + RootCAs: caCertPool, + InsecureSkipVerify: config.Insecure, // #nosec G402 + }, + } + } + + // Return a regular default HTTP client + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} + +// NewHTTPClientWithHeaders returns a *http.Client that attaches a defined set of Headers to all requests. +func (c *Client) newHTTPClientWithHeaders(headers map[string]string) *http.Client { + return &http.Client{ + Transport: &headerTransport{ + base: c.httpTransport, + headers: headers, + }, + Timeout: 30 * time.Second, + } +} + +func (h *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req2 := CloneRequest(req) + for key, val := range h.headers { + req2.Header.Set(key, val) + } + return h.base.RoundTrip(req2) +} + +// CloneRequest and CloneHeader copied from https://github.com/kubernetes/apimachinery/blob/a76b7114b20a2e56fd698bba815b1e2c82ec4bff/pkg/util/net/http.go#L469-L491 + +// CloneRequest creates a shallow copy of the request along with a deep copy of the Headers. +func CloneRequest(req *http.Request) *http.Request { + r := new(http.Request) + + // shallow clone + *r = *req + + // deep copy headers + r.Header = CloneHeader(req.Header) + + return r +} + +// CloneHeader creates a deep copy of an http.Header. +func CloneHeader(in http.Header) http.Header { + out := make(http.Header, len(in)) + for key, values := range in { + newValues := make([]string, len(values)) + copy(newValues, values) + out[key] = newValues + } + return out +} diff --git a/internal/api/humiographql/genqlient.yaml b/internal/api/humiographql/genqlient.yaml new file mode 100644 index 00000000..c6d3655f --- /dev/null +++ b/internal/api/humiographql/genqlient.yaml @@ -0,0 +1,37 @@ +schema: schema/_schema.graphql +operations: + - graphql/actions.graphql + - graphql/aggregate-alerts.graphql + - graphql/alerts.graphql + - graphql/cluster.graphql + - graphql/filter-alerts.graphql + - graphql/fragments.graphql + - graphql/ingest-tokens.graphql + - graphql/license.graphql + - graphql/parsers.graphql + - graphql/repositories.graphql + - graphql/scheduled-search.graphql + - graphql/searchdomains.graphql + - graphql/token.graphql + - graphql/viewer.graphql + - graphql/views.graphql + - graphql/users.graphql +generated: humiographql.go + +bindings: + DateTime: + type: time.Time + RepoOrViewName: + type: string + Long: + type: int64 + VersionedPackageSpecifier: + type: string + UnversionedPackageSpecifier: + type: string + PackageVersion: + type: string + YAML: + type: string + +optional: pointer \ No newline at end of file diff --git a/internal/api/humiographql/graphql/actions.graphql b/internal/api/humiographql/graphql/actions.graphql new file mode 100644 index 00000000..7bab598e --- /dev/null +++ b/internal/api/humiographql/graphql/actions.graphql @@ -0,0 +1,418 @@ +fragment ActionDetails on Action { + id + name + + ... on EmailAction { + recipients + subjectTemplate + emailBodyTemplate: bodyTemplate + useProxy + + } + + ... on HumioRepoAction { + ingestToken + } + + ... on OpsGenieAction { + apiUrl + genieKey + useProxy + } + + ... on PagerDutyAction { + severity + routingKey + useProxy + } + + ... on SlackAction { + url + fields { + fieldName + value + } + useProxy + } + + ... on SlackPostMessageAction { + apiToken + channels + fields { + fieldName + value + } + useProxy + } + + ... on VictorOpsAction { + messageType + notifyUrl + useProxy + } + + ... on WebhookAction { + method + url + headers { + header + value + } + WebhookBodyTemplate: bodyTemplate + ignoreSSL + useProxy + } +} + +query ListActions( + $SearchDomainName: String! +) { + searchDomain( + name: $SearchDomainName + ) { + actions { + ...ActionDetails + } + } +} + +query GetActionByID( + $SearchDomainName: String! + $ActionID: String! +) { + searchDomain( + name: $SearchDomainName + ) { + action( + id: $ActionID + ) { + ...ActionDetails + } + } +} + +mutation DeleteActionByID( + $SearchDomainName: String! + $ActionID: String! +) { + deleteAction(input: { + viewName: $SearchDomainName + id: $ActionID + }) +} + +mutation UpdateEmailAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $Recipients: [String!]! + $SubjectTemplate: String + $BodyTemplate: String + $UseProxy: Boolean! +) { + updateEmailAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + recipients: $Recipients + subjectTemplate: $SubjectTemplate + bodyTemplate: $BodyTemplate + useProxy: $UseProxy + }) { + __typename + } +} + +mutation UpdateHumioRepoAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $IngestToken: String! +) { + updateHumioRepoAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + ingestToken: $IngestToken + }) { + __typename + } +} + +mutation UpdateOpsGenieAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $ApiUrl: String! + $GenieKey: String! + $UseProxy: Boolean! +) { + updateOpsGenieAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + apiUrl: $ApiUrl + genieKey: $GenieKey + useProxy: $UseProxy + }) { + __typename + } +} + +mutation UpdatePagerDutyAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $Severity: String! + $RoutingKey: String! + $UseProxy: Boolean! +) { + updatePagerDutyAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + severity: $Severity + routingKey: $RoutingKey + useProxy: $UseProxy + }) { + __typename + } +} + +mutation UpdateSlackAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $Fields: [SlackFieldEntryInput!]! + $Url: String! + $UseProxy: Boolean! +) { + updateSlackAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + fields: $Fields + url: $Url + useProxy: $UseProxy + }) { + __typename + } +} + +mutation UpdateSlackPostMessageAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $ApiToken: String! + $Channels: [String!]! + $Fields: [SlackFieldEntryInput!]! + $UseProxy: Boolean! +) { + updateSlackPostMessageAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + apiToken: $ApiToken + channels: $Channels + fields: $Fields + useProxy: $UseProxy + }) { + __typename + } +} + +mutation UpdateVictorOpsAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $MessageType: String! + $NotifyUrl: String! + $UseProxy: Boolean! +) { + updateVictorOpsAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + messageType: $MessageType + notifyUrl: $NotifyUrl + useProxy: $UseProxy + }) { + __typename + } +} + +mutation UpdateWebhookAction( + $SearchDomainName: String! + $ActionID: String! + $ActionName: String! + $Url: String! + $Method: String! + $Headers: [HttpHeaderEntryInput!]! + $BodyTemplate: String! + $IgnoreSSL: Boolean! + $UseProxy: Boolean! +) { + updateWebhookAction(input: { + viewName: $SearchDomainName + id: $ActionID + name: $ActionName + url: $Url + method: $Method + headers: $Headers + bodyTemplate: $BodyTemplate + ignoreSSL: $IgnoreSSL + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreateEmailAction( + $SearchDomainName: String! + $ActionName: String! + $Recipients: [String!]! + $SubjectTemplate: String + $BodyTemplate: String + $UseProxy: Boolean! +) { + createEmailAction(input: { + viewName: $SearchDomainName + name: $ActionName + recipients: $Recipients + subjectTemplate: $SubjectTemplate + bodyTemplate: $BodyTemplate + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreateHumioRepoAction( + $SearchDomainName: String! + $ActionName: String! + $IngestToken: String! +) { + createHumioRepoAction(input: { + viewName: $SearchDomainName + name: $ActionName + ingestToken: $IngestToken + }) { + __typename + } +} + +mutation CreateOpsGenieAction( + $SearchDomainName: String! + $ActionName: String! + $ApiUrl: String! + $GenieKey: String! + $UseProxy: Boolean! +) { + createOpsGenieAction(input: { + viewName: $SearchDomainName + name: $ActionName + apiUrl: $ApiUrl + genieKey: $GenieKey + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreatePagerDutyAction( + $SearchDomainName: String! + $ActionName: String! + $Severity: String! + $RoutingKey: String! + $UseProxy: Boolean! +) { + createPagerDutyAction(input: { + viewName: $SearchDomainName + name: $ActionName + severity: $Severity + routingKey: $RoutingKey + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreateSlackAction( + $SearchDomainName: String! + $ActionName: String! + $Fields: [SlackFieldEntryInput!]! + $Url: String! + $UseProxy: Boolean! +) { + createSlackAction(input: { + viewName: $SearchDomainName + name: $ActionName + fields: $Fields + url: $Url + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreateSlackPostMessageAction( + $SearchDomainName: String! + $ActionName: String! + $ApiToken: String! + $Channels: [String!]! + $Fields: [SlackFieldEntryInput!]! + $UseProxy: Boolean! +) { + createSlackPostMessageAction(input: { + viewName: $SearchDomainName + name: $ActionName + apiToken: $ApiToken + channels: $Channels + fields: $Fields + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreateVictorOpsAction( + $SearchDomainName: String! + $ActionName: String! + $MessageType: String! + $NotifyUrl: String! + $UseProxy: Boolean! +) { + createVictorOpsAction(input: { + viewName: $SearchDomainName + name: $ActionName + messageType: $MessageType + notifyUrl: $NotifyUrl + useProxy: $UseProxy + }) { + __typename + } +} + +mutation CreateWebhookAction( + $SearchDomainName: String! + $ActionName: String! + $Url: String! + $Method: String! + $Headers: [HttpHeaderEntryInput!]! + $BodyTemplate: String! + $IgnoreSSL: Boolean! + $UseProxy: Boolean! +) { + createWebhookAction(input: { + viewName: $SearchDomainName + name: $ActionName + url: $Url + method: $Method + headers: $Headers + bodyTemplate: $BodyTemplate + ignoreSSL: $IgnoreSSL + useProxy: $UseProxy + }) { + __typename + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/aggregate-alerts.graphql b/internal/api/humiographql/graphql/aggregate-alerts.graphql new file mode 100644 index 00000000..ac863b47 --- /dev/null +++ b/internal/api/humiographql/graphql/aggregate-alerts.graphql @@ -0,0 +1,128 @@ +fragment AggregateAlertDetails on AggregateAlert { + id + name + description + queryString + searchIntervalSeconds + throttleTimeSeconds + throttleField + labels + enabled + triggerMode + queryTimestampType + + # @genqlient(typename: "SharedActionNameType") + actions { + ...ActionName + } + + # @genqlient(typename: "SharedQueryOwnershipType") + queryOwnership { + ...QueryOwnership + } +} + +query ListAggregateAlerts( + $SearchDomainName: String! +) { + searchDomain( + name: $SearchDomainName + ) { + aggregateAlerts { + ...AggregateAlertDetails + } + } +} + +mutation UpdateAggregateAlert( + $SearchDomainName: RepoOrViewName! + $ID: String! + $Name: String! + $Description: String + $QueryString: String! + $SearchIntervalSeconds: Long! + $ActionIdsOrNames: [String!]! + $Labels: [String!]! + $Enabled: Boolean! + $ThrottleField: String + $ThrottleTimeSeconds: Long! + $TriggerMode: TriggerMode! + $QueryTimestampMode: QueryTimestampType! + $QueryOwnershipType: QueryOwnershipType! +) { + updateAggregateAlert(input: { + viewName: $SearchDomainName + id: $ID + name: $Name + description: $Description + queryString: $QueryString + searchIntervalSeconds: $SearchIntervalSeconds + actionIdsOrNames: $ActionIdsOrNames + labels: $Labels + enabled: $Enabled + throttleField: $ThrottleField + throttleTimeSeconds: $ThrottleTimeSeconds + triggerMode: $TriggerMode + queryTimestampType: $QueryTimestampMode + queryOwnershipType: $QueryOwnershipType + }) { + ...AggregateAlertDetails + } +} + +mutation CreateAggregateAlert( + $SearchDomainName: RepoOrViewName! + $Name: String! + $Description: String + $QueryString: String! + $SearchIntervalSeconds: Long! + $ActionIdsOrNames: [String!]! + $Labels: [String!]! + $Enabled: Boolean! + $ThrottleField: String + $ThrottleTimeSeconds: Long! + $TriggerMode: TriggerMode! + $QueryTimestampMode: QueryTimestampType! + $QueryOwnershipType: QueryOwnershipType! +) { + createAggregateAlert(input: { + viewName: $SearchDomainName + name: $Name + description: $Description + queryString: $QueryString + searchIntervalSeconds: $SearchIntervalSeconds + actionIdsOrNames: $ActionIdsOrNames + labels: $Labels + enabled: $Enabled + throttleField: $ThrottleField + throttleTimeSeconds: $ThrottleTimeSeconds + triggerMode: $TriggerMode + queryTimestampType: $QueryTimestampMode + queryOwnershipType: $QueryOwnershipType + }) { + ...AggregateAlertDetails + } +} + +mutation DeleteAggregateAlert( + $SearchDomainName: RepoOrViewName! + $AggregateAlertID: String! +) { + deleteAggregateAlert(input: { + id: $AggregateAlertID + viewName: $SearchDomainName + }) +} + +query GetAggregateAlertByID( + $SearchDomainName: String! + $AggregateAlertID: String! +) { + searchDomain( + name: $SearchDomainName + ) { + aggregateAlert(id: $AggregateAlertID) { + ...AggregateAlertDetails + } + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/alerts.graphql b/internal/api/humiographql/graphql/alerts.graphql new file mode 100644 index 00000000..919ac899 --- /dev/null +++ b/internal/api/humiographql/graphql/alerts.graphql @@ -0,0 +1,105 @@ +fragment AlertDetails on Alert { + id + name + queryString + queryStart + throttleField + description + throttleTimeMillis + enabled + labels + + # @genqlient(typename: "SharedActionNameType") + actionsV2 { + ...ActionName + } + + # @genqlient(typename: "SharedQueryOwnershipType") + queryOwnership { + ...QueryOwnership + } +} + +query ListAlerts( + $SearchDomainName: String! +) { + searchDomain( + name: $SearchDomainName + ) { + alerts { + ...AlertDetails + } + } +} + +mutation UpdateAlert( + $SearchDomainName: String! + $AlertID: String! + $Name: String! + $Description: String + $QueryString: String! + $QueryStart: String! + $ThrottleTimeMillis: Long! + $Enabled: Boolean! + $Actions: [String!]! + $Labels: [String!]! + $QueryOwnershipType: QueryOwnershipType + $ThrottleField: String +) { + updateAlert(input: { + id: $AlertID + viewName: $SearchDomainName + name: $Name + description: $Description + queryString: $QueryString + queryStart: $QueryStart + throttleTimeMillis: $ThrottleTimeMillis + enabled: $Enabled + actions: $Actions + labels: $Labels + queryOwnershipType: $QueryOwnershipType + throttleField: $ThrottleField + }) { + ...AlertDetails + } +} + +mutation CreateAlert( + $SearchDomainName: String! + $Name: String! + $Description: String + $QueryString: String! + $QueryStart: String! + $ThrottleTimeMillis: Long! + $Enabled: Boolean + $Actions: [String!]! + $Labels: [String!] + $QueryOwnershipType: QueryOwnershipType + $ThrottleField: String +) { + createAlert(input: { + viewName: $SearchDomainName + name: $Name + description: $Description + queryString: $QueryString + queryStart: $QueryStart + throttleTimeMillis: $ThrottleTimeMillis + enabled: $Enabled + actions: $Actions + labels: $Labels + queryOwnershipType: $QueryOwnershipType + throttleField: $ThrottleField + }) { + ...AlertDetails + } +} + +mutation DeleteAlertByID( + $SearchDomainName: String! + $AlertID: String! +) { + deleteAlert(input: { + viewName: $SearchDomainName + id: $AlertID + }) +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/cluster.graphql b/internal/api/humiographql/graphql/cluster.graphql new file mode 100644 index 00000000..9e36f81f --- /dev/null +++ b/internal/api/humiographql/graphql/cluster.graphql @@ -0,0 +1,8 @@ +query GetCluster { + cluster { + nodes { + id + zone + } + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/filter-alerts.graphql b/internal/api/humiographql/graphql/filter-alerts.graphql new file mode 100644 index 00000000..212e5f43 --- /dev/null +++ b/internal/api/humiographql/graphql/filter-alerts.graphql @@ -0,0 +1,113 @@ +fragment FilterAlertDetails on FilterAlert { + id + name + description + queryString + throttleTimeSeconds + throttleField + labels + enabled + + # @genqlient(typename: "SharedActionNameType") + actions { + ...ActionName + } + + # @genqlient(typename: "SharedQueryOwnershipType") + queryOwnership { + ...QueryOwnership + } +} + +query ListFilterAlerts( + $SearchDomainName: String! +) { + searchDomain( + name: $SearchDomainName + ) { + filterAlerts { + ...FilterAlertDetails + } + } +} + +mutation UpdateFilterAlert( + $SearchDomainName: RepoOrViewName! + $ID: String! + $Name: String! + $Description: String + $QueryString: String! + $ActionIdsOrNames: [String!]! + $Labels: [String!]! + $Enabled: Boolean! + $ThrottleField: String + $ThrottleTimeSeconds: Long! + $QueryOwnershipType: QueryOwnershipType! +) { + updateFilterAlert(input: { + viewName: $SearchDomainName + id: $ID + name: $Name + description: $Description + queryString: $QueryString + actionIdsOrNames: $ActionIdsOrNames + labels: $Labels + enabled: $Enabled + throttleField: $ThrottleField + throttleTimeSeconds: $ThrottleTimeSeconds + queryOwnershipType: $QueryOwnershipType + }) { + ...FilterAlertDetails + } +} + +mutation CreateFilterAlert( + $SearchDomainName: RepoOrViewName! + $Name: String! + $Description: String + $QueryString: String! + $ActionIdsOrNames: [String!]! + $Labels: [String!]! + $Enabled: Boolean! + $ThrottleField: String + $ThrottleTimeSeconds: Long! + $QueryOwnershipType: QueryOwnershipType! +) { + createFilterAlert(input: { + viewName: $SearchDomainName + name: $Name + description: $Description + queryString: $QueryString + actionIdsOrNames: $ActionIdsOrNames + labels: $Labels + enabled: $Enabled + throttleField: $ThrottleField + throttleTimeSeconds: $ThrottleTimeSeconds + queryOwnershipType: $QueryOwnershipType + }) { + ...FilterAlertDetails + } +} + +mutation DeleteFilterAlert( + $SearchDomainName: RepoOrViewName! + $FilterAlertID: String! +) { + deleteFilterAlert(input: { + id: $FilterAlertID + viewName: $SearchDomainName + }) +} + +query GetFilterAlertByID( + $SearchDomainName: String! + $FilterAlertID: String! +) { + searchDomain( + name: $SearchDomainName + ) { + filterAlert(id: $FilterAlertID) { + ...FilterAlertDetails + } + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/fragments.graphql b/internal/api/humiographql/graphql/fragments.graphql new file mode 100644 index 00000000..53c5a188 --- /dev/null +++ b/internal/api/humiographql/graphql/fragments.graphql @@ -0,0 +1,7 @@ +fragment QueryOwnership on QueryOwnership { + __typename +} + +fragment ActionName on Action { + name +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/ingest-tokens.graphql b/internal/api/humiographql/graphql/ingest-tokens.graphql new file mode 100644 index 00000000..61870323 --- /dev/null +++ b/internal/api/humiographql/graphql/ingest-tokens.graphql @@ -0,0 +1,71 @@ +fragment IngestTokenDetails on IngestToken { + name + token + parser { + name + } +} + +query ListIngestTokens( + $RepositoryName: String! +) { + repository( + name: $RepositoryName + ) { + ingestTokens { + ...IngestTokenDetails + } + } +} + +mutation AddIngestToken( + $RepositoryName: String! + $Name: String! + $ParserName: String +) { + addIngestTokenV3(input: { + repositoryName: $RepositoryName + name: $Name + parser: $ParserName + }) { + ...IngestTokenDetails + } +} + +mutation AssignParserToIngestToken( + $RepositoryName: String! + $IngestTokenName: String! + $ParserName: String! +) { + assignParserToIngestTokenV2(input: { + repositoryName: $RepositoryName + parser: $ParserName + tokenName: $IngestTokenName + }) { + __typename + } +} + +mutation UnassignParserToIngestToken( + $RepositoryName: String! + $IngestTokenName: String! +) { + unassignIngestToken( + repositoryName: $RepositoryName + tokenName: $IngestTokenName + ) { + __typename + } +} + +mutation RemoveIngestToken( + $RepositoryName: String! + $Name: String! +) { + removeIngestToken( + repositoryName: $RepositoryName + name: $Name + ) { + __typename + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/license.graphql b/internal/api/humiographql/graphql/license.graphql new file mode 100644 index 00000000..521fca67 --- /dev/null +++ b/internal/api/humiographql/graphql/license.graphql @@ -0,0 +1,16 @@ +query GetLicense { + installedLicense { + ... on OnPremLicense { + uid + expiresAt + } + } +} + +mutation UpdateLicenseKey( + $LicenseKey: String! +) { + updateLicenseKey(license: $LicenseKey) { + __typename + } +} diff --git a/internal/api/humiographql/graphql/parsers.graphql b/internal/api/humiographql/graphql/parsers.graphql new file mode 100644 index 00000000..05263e8e --- /dev/null +++ b/internal/api/humiographql/graphql/parsers.graphql @@ -0,0 +1,76 @@ +fragment ParserDetails on Parser { + id + name + script + fieldsToTag + testCases { + event { + rawString + } + outputAssertions { + __typename + } + } +} + +query ListParsers( + $RepositoryName: String! +) { + repository( + name: $RepositoryName + ) { + parsers { + id + name + } + } +} + +mutation DeleteParserByID( + $RepositoryName: RepoOrViewName! + $ParserID: String! +) { + deleteParser(input: { + repositoryName: $RepositoryName + id: $ParserID + }) { + __typename + } +} + +mutation CreateParserOrUpdate( + $RepositoryName: RepoOrViewName! + $Name: String! + $Script: String! + $TestCases: [ParserTestCaseInput!]! + $FieldsToTag: [String!]! + $FieldsToBeRemovedBeforeParsing: [String!]! + $AllowOverridingExistingParser: Boolean! +) { + createParserV2(input: { + name: $Name + script: $Script + testCases: $TestCases + repositoryName: $RepositoryName + fieldsToTag: $FieldsToTag + fieldsToBeRemovedBeforeParsing: $FieldsToBeRemovedBeforeParsing + allowOverwritingExistingParser: $AllowOverridingExistingParser + }) { + ...ParserDetails + } +} + +query GetParserByID( + $RepositoryName: String! + $ParserID: String! +) { + repository( + name: $RepositoryName + ) { + parser( + id: $ParserID + ) { + ...ParserDetails + } + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/repositories.graphql b/internal/api/humiographql/graphql/repositories.graphql new file mode 100644 index 00000000..f466db2b --- /dev/null +++ b/internal/api/humiographql/graphql/repositories.graphql @@ -0,0 +1,118 @@ +fragment RepositoryDetails on Repository { + id + name + description + timeBasedRetention + ingestSizeBasedRetention + storageSizeBasedRetention + compressedByteSize + automaticSearch + s3ArchivingConfiguration { + bucket + region + disabled + format + } +} + +query GetRepository( + $RepositoryName: String! +) { + repository( + name: $RepositoryName + ) { + ...RepositoryDetails + } +} + +query ListRepositories +{ + repositories { + id + name + compressedByteSize + } +} + +mutation CreateRepository( + $RepositoryName: String! +) { + createRepository( + name: $RepositoryName + ) { + repository { + ...RepositoryDetails + } + } +} + +mutation UpdateTimeBasedRetention( + $RepositoryName: String! + $RetentionInDays: Float +) { + updateRetention( + repositoryName: $RepositoryName + timeBasedRetention: $RetentionInDays + ) { + __typename + } +} + +mutation UpdateStorageBasedRetention( + $RepositoryName: String! + $StorageInGB: Float +) { + updateRetention( + repositoryName: $RepositoryName + storageSizeBasedRetention: $StorageInGB + ) { + __typename + } +} + +mutation UpdateIngestBasedRetention( + $RepositoryName: String! + $IngestInGB: Float +) { + updateRetention( + repositoryName: $RepositoryName + ingestSizeBasedRetention: $IngestInGB + ) { + __typename + } +} + +mutation EnableS3Archiving( + $RepositoryName: String! +) { + s3EnableArchiving( + repositoryName: $RepositoryName + ) { + __typename + } +} + +mutation DisableS3Archiving( + $RepositoryName: String! +) { + s3DisableArchiving( + repositoryName: $RepositoryName + ) { + __typename + } +} + +mutation UpdateS3ArchivingConfiguration( + $RepositoryName: String! + $BucketName: String! + $BucketRegion: String! + $Format: S3ArchivingFormat! +) { + s3ConfigureArchiving(repositoryName: $RepositoryName + bucket: $BucketName + region: $BucketRegion + format: $Format + ) { + __typename + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/scheduled-search.graphql b/internal/api/humiographql/graphql/scheduled-search.graphql new file mode 100644 index 00000000..53703b44 --- /dev/null +++ b/internal/api/humiographql/graphql/scheduled-search.graphql @@ -0,0 +1,130 @@ +fragment ScheduledSearchDetails on ScheduledSearch { + id + name + description + queryString + start + end + timeZone + schedule + backfillLimit + enabled + labels + + # @genqlient(typename: "SharedActionNameType") + actionsV2 { + ...ActionName + } + + # @genqlient(typename: "SharedQueryOwnershipType") + queryOwnership { + ...QueryOwnership + } +} + +query ListScheduledSearches( + $SearchDomainName: String! +) { + searchDomain( + name: $SearchDomainName + ) { + scheduledSearches { + ...ScheduledSearchDetails + } + } +} + +mutation UpdateScheduledSearch( + $SearchDomainName: String! + $ID: String! + $Name: String! + $Description: String + $QueryString: String! + $QueryStart: String! + $QueryEnd: String! + $Schedule: String! + $TimeZone: String! + $BackfillLimit: Int! + $Enabled: Boolean! + $ActionIdsOrNames: [String!]! + $Labels: [String!]! + $QueryOwnershipType: QueryOwnershipType +) { + updateScheduledSearch(input: { + viewName: $SearchDomainName + id: $ID + name: $Name + description: $Description + queryString: $QueryString + queryStart: $QueryStart + queryEnd: $QueryEnd + schedule: $Schedule + timeZone: $TimeZone + backfillLimit: $BackfillLimit + enabled: $Enabled + actions: $ActionIdsOrNames + labels: $Labels + queryOwnershipType: $QueryOwnershipType + }) { + ...ScheduledSearchDetails + } +} + +mutation CreateScheduledSearch( + $SearchDomainName: String! + $Name: String! + $Description: String + $QueryString: String! + $QueryStart: String! + $QueryEnd: String! + $Schedule: String! + $TimeZone: String! + $BackfillLimit: Int! + $Enabled: Boolean! + $ActionIdsOrNames: [String!]! + $Labels: [String!]! + $QueryOwnershipType: QueryOwnershipType +) { + createScheduledSearch(input: { + viewName: $SearchDomainName + name: $Name + description: $Description + queryString: $QueryString + queryStart: $QueryStart + queryEnd: $QueryEnd + schedule: $Schedule + timeZone: $TimeZone + backfillLimit: $BackfillLimit + enabled: $Enabled + actions: $ActionIdsOrNames + labels: $Labels + queryOwnershipType: $QueryOwnershipType + }) { + ...ScheduledSearchDetails + } +} + +mutation DeleteScheduledSearchByID( + $SearchDomainName: String! + $ScheduledSearchID: String! +) { + deleteScheduledSearch(input: { + viewName: $SearchDomainName + id: $ScheduledSearchID + }) +} + +query GetScheduledSearchByID( + $SearchDomainName: String! + $ScheduledSearchID: String! +) { + searchDomain( + name: $SearchDomainName + ) { + scheduledSearch( + id: $ScheduledSearchID + ) { + ...ScheduledSearchDetails + } + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/searchdomains.graphql b/internal/api/humiographql/graphql/searchdomains.graphql new file mode 100644 index 00000000..b374ed40 --- /dev/null +++ b/internal/api/humiographql/graphql/searchdomains.graphql @@ -0,0 +1,65 @@ +mutation DeleteSearchDomain( + $SearchDomainName: String! + $DeleteMessage: String! +) { + deleteSearchDomain( + name: $SearchDomainName + deleteMessage: $DeleteMessage + ) { + __typename + } +} + +mutation UpdateDescriptionForSearchDomain( + $SearchDomainName: String! + $NewDescription: String! +) { + updateDescriptionForSearchDomain( + name: $SearchDomainName + newDescription: $NewDescription + ) { + __typename + } +} + +mutation SetAutomaticSearching( + $SearchDomainName: String! + $AutomaticSearch: Boolean! +) { + setAutomaticSearching( + name: $SearchDomainName + automaticSearch: $AutomaticSearch + ) { + __typename + } +} + +query GetSearchDomain( + $SearchDomainName: String! +) { + searchDomain( + name: $SearchDomainName + ) { + id + name + description + automaticSearch + ... on View { + connections { + repository { + name + } + filter + } + } + __typename + } +} + +query ListSearchDomains +{ + searchDomains { + name + automaticSearch + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/token.graphql b/internal/api/humiographql/graphql/token.graphql new file mode 100644 index 00000000..feedcae1 --- /dev/null +++ b/internal/api/humiographql/graphql/token.graphql @@ -0,0 +1,5 @@ +mutation RotateTokenByID( + $TokenID: String! +) { + rotateToken(input:{id:$TokenID}) +} diff --git a/internal/api/humiographql/graphql/users.graphql b/internal/api/humiographql/graphql/users.graphql new file mode 100644 index 00000000..e8f416be --- /dev/null +++ b/internal/api/humiographql/graphql/users.graphql @@ -0,0 +1,27 @@ +fragment UserDetails on User { + id + username + isRoot +} + +query GetUsersByUsername( + $Username: String! +) { + users(search: $Username) { + ...UserDetails + } +} + +mutation AddUser( + $Username: String! + $IsRoot: Boolean +) { + addUserV2(input: { + username: $Username + isRoot: $IsRoot + }) { + ... on User { + ...UserDetails + } + } +} diff --git a/internal/api/humiographql/graphql/viewer.graphql b/internal/api/humiographql/graphql/viewer.graphql new file mode 100644 index 00000000..9ccd7118 --- /dev/null +++ b/internal/api/humiographql/graphql/viewer.graphql @@ -0,0 +1,5 @@ +query GetUsername { + viewer { + username + } +} \ No newline at end of file diff --git a/internal/api/humiographql/graphql/views.graphql b/internal/api/humiographql/graphql/views.graphql new file mode 100644 index 00000000..550e14e0 --- /dev/null +++ b/internal/api/humiographql/graphql/views.graphql @@ -0,0 +1,25 @@ +mutation CreateView( + $ViewName: String! + $Description: String + $Connections: [ViewConnectionInput!] +) { + createView( + name: $ViewName + description: $Description + connections: $Connections + ) { + __typename + } +} + +mutation UpdateViewConnections( + $ViewName: String! + $Connections: [ViewConnectionInput!]! +) { + updateView( + viewName: $ViewName + connections: $Connections + ) { + name + } +} \ No newline at end of file diff --git a/internal/api/humiographql/humiographql.go b/internal/api/humiographql/humiographql.go new file mode 100644 index 00000000..62ae4328 --- /dev/null +++ b/internal/api/humiographql/humiographql.go @@ -0,0 +1,17254 @@ +// Code generated by github.com/Khan/genqlient, DO NOT EDIT. + +package humiographql + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/Khan/genqlient/graphql" +) + +// ActionDetails includes the GraphQL fields of Action requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +// +// ActionDetails is implemented by the following types: +// ActionDetailsEmailAction +// ActionDetailsHumioRepoAction +// ActionDetailsOpsGenieAction +// ActionDetailsPagerDutyAction +// ActionDetailsSlackAction +// ActionDetailsSlackPostMessageAction +// ActionDetailsUploadFileAction +// ActionDetailsVictorOpsAction +// ActionDetailsWebhookAction +type ActionDetails interface { + implementsGraphQLInterfaceActionDetails() + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // An action that can be invoked from a trigger. + GetId() string + // GetName returns the interface-field "name" from its implementation. + // The GraphQL interface field's documentation follows. + // + // An action that can be invoked from a trigger. + GetName() string +} + +func (v *ActionDetailsEmailAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsHumioRepoAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsOpsGenieAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsPagerDutyAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsSlackAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsSlackPostMessageAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsUploadFileAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsVictorOpsAction) implementsGraphQLInterfaceActionDetails() {} +func (v *ActionDetailsWebhookAction) implementsGraphQLInterfaceActionDetails() {} + +func __unmarshalActionDetails(b []byte, v *ActionDetails) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "EmailAction": + *v = new(ActionDetailsEmailAction) + return json.Unmarshal(b, *v) + case "HumioRepoAction": + *v = new(ActionDetailsHumioRepoAction) + return json.Unmarshal(b, *v) + case "OpsGenieAction": + *v = new(ActionDetailsOpsGenieAction) + return json.Unmarshal(b, *v) + case "PagerDutyAction": + *v = new(ActionDetailsPagerDutyAction) + return json.Unmarshal(b, *v) + case "SlackAction": + *v = new(ActionDetailsSlackAction) + return json.Unmarshal(b, *v) + case "SlackPostMessageAction": + *v = new(ActionDetailsSlackPostMessageAction) + return json.Unmarshal(b, *v) + case "UploadFileAction": + *v = new(ActionDetailsUploadFileAction) + return json.Unmarshal(b, *v) + case "VictorOpsAction": + *v = new(ActionDetailsVictorOpsAction) + return json.Unmarshal(b, *v) + case "WebhookAction": + *v = new(ActionDetailsWebhookAction) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Action.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ActionDetails: "%v"`, tn.TypeName) + } +} + +func __marshalActionDetails(v *ActionDetails) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ActionDetailsEmailAction: + typename = "EmailAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsEmailAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsHumioRepoAction: + typename = "HumioRepoAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsHumioRepoAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsOpsGenieAction: + typename = "OpsGenieAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsOpsGenieAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsPagerDutyAction: + typename = "PagerDutyAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsPagerDutyAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsSlackAction: + typename = "SlackAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsSlackAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsSlackPostMessageAction: + typename = "SlackPostMessageAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsSlackPostMessageAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsUploadFileAction: + typename = "UploadFileAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsUploadFileAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsVictorOpsAction: + typename = "VictorOpsAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsVictorOpsAction + }{typename, v} + return json.Marshal(result) + case *ActionDetailsWebhookAction: + typename = "WebhookAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionDetailsWebhookAction + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ActionDetails: "%T"`, v) + } +} + +// ActionDetails includes the GraphQL fields of EmailAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsEmailAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // List of email addresses to send an email to. + Recipients []string `json:"recipients"` + // Subject of the email. Can be templated with values from the result. + SubjectTemplate *string `json:"subjectTemplate"` + // Body of the email. Can be templated with values from the result. + EmailBodyTemplate *string `json:"emailBodyTemplate"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsEmailAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsEmailAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsEmailAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsEmailAction) GetName() string { return v.Name } + +// GetRecipients returns ActionDetailsEmailAction.Recipients, and is useful for accessing the field via an interface. +func (v *ActionDetailsEmailAction) GetRecipients() []string { return v.Recipients } + +// GetSubjectTemplate returns ActionDetailsEmailAction.SubjectTemplate, and is useful for accessing the field via an interface. +func (v *ActionDetailsEmailAction) GetSubjectTemplate() *string { return v.SubjectTemplate } + +// GetEmailBodyTemplate returns ActionDetailsEmailAction.EmailBodyTemplate, and is useful for accessing the field via an interface. +func (v *ActionDetailsEmailAction) GetEmailBodyTemplate() *string { return v.EmailBodyTemplate } + +// GetUseProxy returns ActionDetailsEmailAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsEmailAction) GetUseProxy() bool { return v.UseProxy } + +// ActionDetailsFieldsSlackFieldEntry includes the requested fields of the GraphQL type SlackFieldEntry. +// The GraphQL type's documentation follows. +// +// Field entry in a Slack message +type ActionDetailsFieldsSlackFieldEntry struct { + // Key of a Slack field. + FieldName string `json:"fieldName"` + // Value of a Slack field. + Value string `json:"value"` +} + +// GetFieldName returns ActionDetailsFieldsSlackFieldEntry.FieldName, and is useful for accessing the field via an interface. +func (v *ActionDetailsFieldsSlackFieldEntry) GetFieldName() string { return v.FieldName } + +// GetValue returns ActionDetailsFieldsSlackFieldEntry.Value, and is useful for accessing the field via an interface. +func (v *ActionDetailsFieldsSlackFieldEntry) GetValue() string { return v.Value } + +// ActionDetailsHeadersHttpHeaderEntry includes the requested fields of the GraphQL type HttpHeaderEntry. +// The GraphQL type's documentation follows. +// +// A http request header. +type ActionDetailsHeadersHttpHeaderEntry struct { + // Key of a http(s) header. + Header string `json:"header"` + // Value of a http(s) header. + Value string `json:"value"` +} + +// GetHeader returns ActionDetailsHeadersHttpHeaderEntry.Header, and is useful for accessing the field via an interface. +func (v *ActionDetailsHeadersHttpHeaderEntry) GetHeader() string { return v.Header } + +// GetValue returns ActionDetailsHeadersHttpHeaderEntry.Value, and is useful for accessing the field via an interface. +func (v *ActionDetailsHeadersHttpHeaderEntry) GetValue() string { return v.Value } + +// ActionDetails includes the GraphQL fields of HumioRepoAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsHumioRepoAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // Humio ingest token for the dataspace that the action should ingest into. + IngestToken string `json:"ingestToken"` +} + +// GetId returns ActionDetailsHumioRepoAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsHumioRepoAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsHumioRepoAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsHumioRepoAction) GetName() string { return v.Name } + +// GetIngestToken returns ActionDetailsHumioRepoAction.IngestToken, and is useful for accessing the field via an interface. +func (v *ActionDetailsHumioRepoAction) GetIngestToken() string { return v.IngestToken } + +// ActionDetails includes the GraphQL fields of OpsGenieAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsOpsGenieAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // OpsGenie webhook url to send the request to. + ApiUrl string `json:"apiUrl"` + // Key to authenticate with OpsGenie. + GenieKey string `json:"genieKey"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsOpsGenieAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsOpsGenieAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsOpsGenieAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsOpsGenieAction) GetName() string { return v.Name } + +// GetApiUrl returns ActionDetailsOpsGenieAction.ApiUrl, and is useful for accessing the field via an interface. +func (v *ActionDetailsOpsGenieAction) GetApiUrl() string { return v.ApiUrl } + +// GetGenieKey returns ActionDetailsOpsGenieAction.GenieKey, and is useful for accessing the field via an interface. +func (v *ActionDetailsOpsGenieAction) GetGenieKey() string { return v.GenieKey } + +// GetUseProxy returns ActionDetailsOpsGenieAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsOpsGenieAction) GetUseProxy() bool { return v.UseProxy } + +// ActionDetails includes the GraphQL fields of PagerDutyAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsPagerDutyAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // Severity level to give to the message. + Severity string `json:"severity"` + // Routing key to authenticate with PagerDuty. + RoutingKey string `json:"routingKey"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsPagerDutyAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsPagerDutyAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsPagerDutyAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsPagerDutyAction) GetName() string { return v.Name } + +// GetSeverity returns ActionDetailsPagerDutyAction.Severity, and is useful for accessing the field via an interface. +func (v *ActionDetailsPagerDutyAction) GetSeverity() string { return v.Severity } + +// GetRoutingKey returns ActionDetailsPagerDutyAction.RoutingKey, and is useful for accessing the field via an interface. +func (v *ActionDetailsPagerDutyAction) GetRoutingKey() string { return v.RoutingKey } + +// GetUseProxy returns ActionDetailsPagerDutyAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsPagerDutyAction) GetUseProxy() bool { return v.UseProxy } + +// ActionDetails includes the GraphQL fields of SlackAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsSlackAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // Slack webhook url to send the request to. + Url string `json:"url"` + // Fields to include within the Slack message. Can be templated with values from the result. + Fields []ActionDetailsFieldsSlackFieldEntry `json:"fields"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsSlackAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsSlackAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackAction) GetName() string { return v.Name } + +// GetUrl returns ActionDetailsSlackAction.Url, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackAction) GetUrl() string { return v.Url } + +// GetFields returns ActionDetailsSlackAction.Fields, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackAction) GetFields() []ActionDetailsFieldsSlackFieldEntry { return v.Fields } + +// GetUseProxy returns ActionDetailsSlackAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackAction) GetUseProxy() bool { return v.UseProxy } + +// ActionDetails includes the GraphQL fields of SlackPostMessageAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsSlackPostMessageAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // Api token to authenticate with Slack. + ApiToken string `json:"apiToken"` + // List of Slack channels to message. + Channels []string `json:"channels"` + // Fields to include within the Slack message. Can be templated with values from the result. + Fields []ActionDetailsFieldsSlackFieldEntry `json:"fields"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsSlackPostMessageAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackPostMessageAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsSlackPostMessageAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackPostMessageAction) GetName() string { return v.Name } + +// GetApiToken returns ActionDetailsSlackPostMessageAction.ApiToken, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackPostMessageAction) GetApiToken() string { return v.ApiToken } + +// GetChannels returns ActionDetailsSlackPostMessageAction.Channels, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackPostMessageAction) GetChannels() []string { return v.Channels } + +// GetFields returns ActionDetailsSlackPostMessageAction.Fields, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackPostMessageAction) GetFields() []ActionDetailsFieldsSlackFieldEntry { + return v.Fields +} + +// GetUseProxy returns ActionDetailsSlackPostMessageAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsSlackPostMessageAction) GetUseProxy() bool { return v.UseProxy } + +// ActionDetails includes the GraphQL fields of UploadFileAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsUploadFileAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetId returns ActionDetailsUploadFileAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsUploadFileAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsUploadFileAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsUploadFileAction) GetName() string { return v.Name } + +// ActionDetails includes the GraphQL fields of VictorOpsAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsVictorOpsAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // Type of the VictorOps message to make. + MessageType string `json:"messageType"` + // VictorOps webhook url to send the request to. + NotifyUrl string `json:"notifyUrl"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsVictorOpsAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsVictorOpsAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsVictorOpsAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsVictorOpsAction) GetName() string { return v.Name } + +// GetMessageType returns ActionDetailsVictorOpsAction.MessageType, and is useful for accessing the field via an interface. +func (v *ActionDetailsVictorOpsAction) GetMessageType() string { return v.MessageType } + +// GetNotifyUrl returns ActionDetailsVictorOpsAction.NotifyUrl, and is useful for accessing the field via an interface. +func (v *ActionDetailsVictorOpsAction) GetNotifyUrl() string { return v.NotifyUrl } + +// GetUseProxy returns ActionDetailsVictorOpsAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsVictorOpsAction) GetUseProxy() bool { return v.UseProxy } + +// ActionDetails includes the GraphQL fields of WebhookAction requested by the fragment ActionDetails. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionDetailsWebhookAction struct { + // An action that can be invoked from a trigger. + Id string `json:"id"` + // An action that can be invoked from a trigger. + Name string `json:"name"` + // Method to use for the request. + Method string `json:"method"` + // Url to send the http(s) request to. + Url string `json:"url"` + // Headers of the http(s) request. + Headers []ActionDetailsHeadersHttpHeaderEntry `json:"headers"` + // Body of the http(s) request. Can be templated with values from the result. + WebhookBodyTemplate string `json:"WebhookBodyTemplate"` + // Flag indicating whether SSL should be ignored for the request. + IgnoreSSL bool `json:"ignoreSSL"` + // Defines whether the action should use the configured proxy to make web requests. + UseProxy bool `json:"useProxy"` +} + +// GetId returns ActionDetailsWebhookAction.Id, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetId() string { return v.Id } + +// GetName returns ActionDetailsWebhookAction.Name, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetName() string { return v.Name } + +// GetMethod returns ActionDetailsWebhookAction.Method, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetMethod() string { return v.Method } + +// GetUrl returns ActionDetailsWebhookAction.Url, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetUrl() string { return v.Url } + +// GetHeaders returns ActionDetailsWebhookAction.Headers, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetHeaders() []ActionDetailsHeadersHttpHeaderEntry { + return v.Headers +} + +// GetWebhookBodyTemplate returns ActionDetailsWebhookAction.WebhookBodyTemplate, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetWebhookBodyTemplate() string { return v.WebhookBodyTemplate } + +// GetIgnoreSSL returns ActionDetailsWebhookAction.IgnoreSSL, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetIgnoreSSL() bool { return v.IgnoreSSL } + +// GetUseProxy returns ActionDetailsWebhookAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ActionDetailsWebhookAction) GetUseProxy() bool { return v.UseProxy } + +// ActionName includes the GraphQL fields of Action requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +// +// ActionName is implemented by the following types: +// ActionNameEmailAction +// ActionNameHumioRepoAction +// ActionNameOpsGenieAction +// ActionNamePagerDutyAction +// ActionNameSlackAction +// ActionNameSlackPostMessageAction +// ActionNameUploadFileAction +// ActionNameVictorOpsAction +// ActionNameWebhookAction +type ActionName interface { + implementsGraphQLInterfaceActionName() + // GetName returns the interface-field "name" from its implementation. + // The GraphQL interface field's documentation follows. + // + // An action that can be invoked from a trigger. + GetName() string +} + +func (v *ActionNameEmailAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameHumioRepoAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameOpsGenieAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNamePagerDutyAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameSlackAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameSlackPostMessageAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameUploadFileAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameVictorOpsAction) implementsGraphQLInterfaceActionName() {} +func (v *ActionNameWebhookAction) implementsGraphQLInterfaceActionName() {} + +func __unmarshalActionName(b []byte, v *ActionName) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "EmailAction": + *v = new(ActionNameEmailAction) + return json.Unmarshal(b, *v) + case "HumioRepoAction": + *v = new(ActionNameHumioRepoAction) + return json.Unmarshal(b, *v) + case "OpsGenieAction": + *v = new(ActionNameOpsGenieAction) + return json.Unmarshal(b, *v) + case "PagerDutyAction": + *v = new(ActionNamePagerDutyAction) + return json.Unmarshal(b, *v) + case "SlackAction": + *v = new(ActionNameSlackAction) + return json.Unmarshal(b, *v) + case "SlackPostMessageAction": + *v = new(ActionNameSlackPostMessageAction) + return json.Unmarshal(b, *v) + case "UploadFileAction": + *v = new(ActionNameUploadFileAction) + return json.Unmarshal(b, *v) + case "VictorOpsAction": + *v = new(ActionNameVictorOpsAction) + return json.Unmarshal(b, *v) + case "WebhookAction": + *v = new(ActionNameWebhookAction) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Action.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ActionName: "%v"`, tn.TypeName) + } +} + +func __marshalActionName(v *ActionName) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ActionNameEmailAction: + typename = "EmailAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameEmailAction + }{typename, v} + return json.Marshal(result) + case *ActionNameHumioRepoAction: + typename = "HumioRepoAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameHumioRepoAction + }{typename, v} + return json.Marshal(result) + case *ActionNameOpsGenieAction: + typename = "OpsGenieAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameOpsGenieAction + }{typename, v} + return json.Marshal(result) + case *ActionNamePagerDutyAction: + typename = "PagerDutyAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNamePagerDutyAction + }{typename, v} + return json.Marshal(result) + case *ActionNameSlackAction: + typename = "SlackAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameSlackAction + }{typename, v} + return json.Marshal(result) + case *ActionNameSlackPostMessageAction: + typename = "SlackPostMessageAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameSlackPostMessageAction + }{typename, v} + return json.Marshal(result) + case *ActionNameUploadFileAction: + typename = "UploadFileAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameUploadFileAction + }{typename, v} + return json.Marshal(result) + case *ActionNameVictorOpsAction: + typename = "VictorOpsAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameVictorOpsAction + }{typename, v} + return json.Marshal(result) + case *ActionNameWebhookAction: + typename = "WebhookAction" + + result := struct { + TypeName string `json:"__typename"` + *ActionNameWebhookAction + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ActionName: "%T"`, v) + } +} + +// ActionName includes the GraphQL fields of EmailAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameEmailAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameEmailAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameEmailAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of HumioRepoAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameHumioRepoAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameHumioRepoAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameHumioRepoAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of OpsGenieAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameOpsGenieAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameOpsGenieAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameOpsGenieAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of PagerDutyAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNamePagerDutyAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNamePagerDutyAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNamePagerDutyAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of SlackAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameSlackAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameSlackAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameSlackAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of SlackPostMessageAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameSlackPostMessageAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameSlackPostMessageAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameSlackPostMessageAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of UploadFileAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameUploadFileAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameUploadFileAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameUploadFileAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of VictorOpsAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameVictorOpsAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameVictorOpsAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameVictorOpsAction) GetName() string { return v.Name } + +// ActionName includes the GraphQL fields of WebhookAction requested by the fragment ActionName. +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ActionNameWebhookAction struct { + // An action that can be invoked from a trigger. + Name string `json:"name"` +} + +// GetName returns ActionNameWebhookAction.Name, and is useful for accessing the field via an interface. +func (v *ActionNameWebhookAction) GetName() string { return v.Name } + +// AddIngestTokenAddIngestTokenV3IngestToken includes the requested fields of the GraphQL type IngestToken. +// The GraphQL type's documentation follows. +// +// An API ingest token used for sending data to LogScale. +type AddIngestTokenAddIngestTokenV3IngestToken struct { + IngestTokenDetails `json:"-"` +} + +// GetName returns AddIngestTokenAddIngestTokenV3IngestToken.Name, and is useful for accessing the field via an interface. +func (v *AddIngestTokenAddIngestTokenV3IngestToken) GetName() string { + return v.IngestTokenDetails.Name +} + +// GetToken returns AddIngestTokenAddIngestTokenV3IngestToken.Token, and is useful for accessing the field via an interface. +func (v *AddIngestTokenAddIngestTokenV3IngestToken) GetToken() string { + return v.IngestTokenDetails.Token +} + +// GetParser returns AddIngestTokenAddIngestTokenV3IngestToken.Parser, and is useful for accessing the field via an interface. +func (v *AddIngestTokenAddIngestTokenV3IngestToken) GetParser() *IngestTokenDetailsParser { + return v.IngestTokenDetails.Parser +} + +func (v *AddIngestTokenAddIngestTokenV3IngestToken) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AddIngestTokenAddIngestTokenV3IngestToken + graphql.NoUnmarshalJSON + } + firstPass.AddIngestTokenAddIngestTokenV3IngestToken = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.IngestTokenDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalAddIngestTokenAddIngestTokenV3IngestToken struct { + Name string `json:"name"` + + Token string `json:"token"` + + Parser *IngestTokenDetailsParser `json:"parser"` +} + +func (v *AddIngestTokenAddIngestTokenV3IngestToken) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AddIngestTokenAddIngestTokenV3IngestToken) __premarshalJSON() (*__premarshalAddIngestTokenAddIngestTokenV3IngestToken, error) { + var retval __premarshalAddIngestTokenAddIngestTokenV3IngestToken + + retval.Name = v.IngestTokenDetails.Name + retval.Token = v.IngestTokenDetails.Token + retval.Parser = v.IngestTokenDetails.Parser + return &retval, nil +} + +// AddIngestTokenResponse is returned by AddIngestToken on success. +type AddIngestTokenResponse struct { + // Create a new Ingest API Token. + AddIngestTokenV3 AddIngestTokenAddIngestTokenV3IngestToken `json:"addIngestTokenV3"` +} + +// GetAddIngestTokenV3 returns AddIngestTokenResponse.AddIngestTokenV3, and is useful for accessing the field via an interface. +func (v *AddIngestTokenResponse) GetAddIngestTokenV3() AddIngestTokenAddIngestTokenV3IngestToken { + return v.AddIngestTokenV3 +} + +// AddUserAddUserV2PendingUser includes the requested fields of the GraphQL type PendingUser. +// The GraphQL type's documentation follows. +// +// A pending user. I.e. a user that was invited to join an organization. +type AddUserAddUserV2PendingUser struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns AddUserAddUserV2PendingUser.Typename, and is useful for accessing the field via an interface. +func (v *AddUserAddUserV2PendingUser) GetTypename() *string { return v.Typename } + +// AddUserAddUserV2User includes the requested fields of the GraphQL type User. +// The GraphQL type's documentation follows. +// +// A user profile. +type AddUserAddUserV2User struct { + Typename *string `json:"__typename"` + UserDetails `json:"-"` +} + +// GetTypename returns AddUserAddUserV2User.Typename, and is useful for accessing the field via an interface. +func (v *AddUserAddUserV2User) GetTypename() *string { return v.Typename } + +// GetId returns AddUserAddUserV2User.Id, and is useful for accessing the field via an interface. +func (v *AddUserAddUserV2User) GetId() string { return v.UserDetails.Id } + +// GetUsername returns AddUserAddUserV2User.Username, and is useful for accessing the field via an interface. +func (v *AddUserAddUserV2User) GetUsername() string { return v.UserDetails.Username } + +// GetIsRoot returns AddUserAddUserV2User.IsRoot, and is useful for accessing the field via an interface. +func (v *AddUserAddUserV2User) GetIsRoot() bool { return v.UserDetails.IsRoot } + +func (v *AddUserAddUserV2User) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AddUserAddUserV2User + graphql.NoUnmarshalJSON + } + firstPass.AddUserAddUserV2User = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.UserDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalAddUserAddUserV2User struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Username string `json:"username"` + + IsRoot bool `json:"isRoot"` +} + +func (v *AddUserAddUserV2User) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AddUserAddUserV2User) __premarshalJSON() (*__premarshalAddUserAddUserV2User, error) { + var retval __premarshalAddUserAddUserV2User + + retval.Typename = v.Typename + retval.Id = v.UserDetails.Id + retval.Username = v.UserDetails.Username + retval.IsRoot = v.UserDetails.IsRoot + return &retval, nil +} + +// AddUserAddUserV2UserOrPendingUser includes the requested fields of the GraphQL interface userOrPendingUser. +// +// AddUserAddUserV2UserOrPendingUser is implemented by the following types: +// AddUserAddUserV2PendingUser +// AddUserAddUserV2User +// The GraphQL type's documentation follows. +// +// A user or pending user, depending on whether an invitation was sent +type AddUserAddUserV2UserOrPendingUser interface { + implementsGraphQLInterfaceAddUserAddUserV2UserOrPendingUser() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string +} + +func (v *AddUserAddUserV2PendingUser) implementsGraphQLInterfaceAddUserAddUserV2UserOrPendingUser() {} +func (v *AddUserAddUserV2User) implementsGraphQLInterfaceAddUserAddUserV2UserOrPendingUser() {} + +func __unmarshalAddUserAddUserV2UserOrPendingUser(b []byte, v *AddUserAddUserV2UserOrPendingUser) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "PendingUser": + *v = new(AddUserAddUserV2PendingUser) + return json.Unmarshal(b, *v) + case "User": + *v = new(AddUserAddUserV2User) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing userOrPendingUser.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for AddUserAddUserV2UserOrPendingUser: "%v"`, tn.TypeName) + } +} + +func __marshalAddUserAddUserV2UserOrPendingUser(v *AddUserAddUserV2UserOrPendingUser) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *AddUserAddUserV2PendingUser: + typename = "PendingUser" + + result := struct { + TypeName string `json:"__typename"` + *AddUserAddUserV2PendingUser + }{typename, v} + return json.Marshal(result) + case *AddUserAddUserV2User: + typename = "User" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalAddUserAddUserV2User + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for AddUserAddUserV2UserOrPendingUser: "%T"`, v) + } +} + +// AddUserResponse is returned by AddUser on success. +type AddUserResponse struct { + // Add or invite a user. Calling this with an invitation token, will activate the account. By activating the account the client accepts LogScale's Terms and Conditions: https://www.humio.com/terms-and-conditions + AddUserV2 AddUserAddUserV2UserOrPendingUser `json:"-"` +} + +// GetAddUserV2 returns AddUserResponse.AddUserV2, and is useful for accessing the field via an interface. +func (v *AddUserResponse) GetAddUserV2() AddUserAddUserV2UserOrPendingUser { return v.AddUserV2 } + +func (v *AddUserResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AddUserResponse + AddUserV2 json.RawMessage `json:"addUserV2"` + graphql.NoUnmarshalJSON + } + firstPass.AddUserResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.AddUserV2 + src := firstPass.AddUserV2 + if len(src) != 0 && string(src) != "null" { + err = __unmarshalAddUserAddUserV2UserOrPendingUser( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal AddUserResponse.AddUserV2: %w", err) + } + } + } + return nil +} + +type __premarshalAddUserResponse struct { + AddUserV2 json.RawMessage `json:"addUserV2"` +} + +func (v *AddUserResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AddUserResponse) __premarshalJSON() (*__premarshalAddUserResponse, error) { + var retval __premarshalAddUserResponse + + { + + dst := &retval.AddUserV2 + src := v.AddUserV2 + var err error + *dst, err = __marshalAddUserAddUserV2UserOrPendingUser( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal AddUserResponse.AddUserV2: %w", err) + } + } + return &retval, nil +} + +// AggregateAlertDetails includes the GraphQL fields of AggregateAlert requested by the fragment AggregateAlertDetails. +// The GraphQL type's documentation follows. +// +// An aggregate alert. +type AggregateAlertDetails struct { + // Id of the aggregate alert. + Id string `json:"id"` + // Name of the aggregate alert. + Name string `json:"name"` + // Description of the aggregate alert. + Description *string `json:"description"` + // LogScale query to execute. + QueryString string `json:"queryString"` + // Search interval in seconds. + SearchIntervalSeconds int64 `json:"searchIntervalSeconds"` + // Throttle time in seconds. + ThrottleTimeSeconds int64 `json:"throttleTimeSeconds"` + // A field to throttle on. Can only be set if throttleTimeSeconds is set. + ThrottleField *string `json:"throttleField"` + // Labels attached to the aggregate alert. + Labels []string `json:"labels"` + // Flag indicating whether the aggregate alert is enabled. + Enabled bool `json:"enabled"` + // Trigger mode used for triggering the alert. + TriggerMode TriggerMode `json:"triggerMode"` + // Timestamp type to use for a query. + QueryTimestampType QueryTimestampType `json:"queryTimestampType"` + // List of actions to fire on query result. + Actions []SharedActionNameType `json:"-"` + // Ownership of the query run by this alert + QueryOwnership SharedQueryOwnershipType `json:"-"` +} + +// GetId returns AggregateAlertDetails.Id, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetId() string { return v.Id } + +// GetName returns AggregateAlertDetails.Name, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetName() string { return v.Name } + +// GetDescription returns AggregateAlertDetails.Description, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetDescription() *string { return v.Description } + +// GetQueryString returns AggregateAlertDetails.QueryString, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetQueryString() string { return v.QueryString } + +// GetSearchIntervalSeconds returns AggregateAlertDetails.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetSearchIntervalSeconds() int64 { return v.SearchIntervalSeconds } + +// GetThrottleTimeSeconds returns AggregateAlertDetails.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetThrottleTimeSeconds() int64 { return v.ThrottleTimeSeconds } + +// GetThrottleField returns AggregateAlertDetails.ThrottleField, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetThrottleField() *string { return v.ThrottleField } + +// GetLabels returns AggregateAlertDetails.Labels, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetLabels() []string { return v.Labels } + +// GetEnabled returns AggregateAlertDetails.Enabled, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetEnabled() bool { return v.Enabled } + +// GetTriggerMode returns AggregateAlertDetails.TriggerMode, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetTriggerMode() TriggerMode { return v.TriggerMode } + +// GetQueryTimestampType returns AggregateAlertDetails.QueryTimestampType, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetQueryTimestampType() QueryTimestampType { + return v.QueryTimestampType +} + +// GetActions returns AggregateAlertDetails.Actions, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetActions() []SharedActionNameType { return v.Actions } + +// GetQueryOwnership returns AggregateAlertDetails.QueryOwnership, and is useful for accessing the field via an interface. +func (v *AggregateAlertDetails) GetQueryOwnership() SharedQueryOwnershipType { return v.QueryOwnership } + +func (v *AggregateAlertDetails) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AggregateAlertDetails + Actions []json.RawMessage `json:"actions"` + QueryOwnership json.RawMessage `json:"queryOwnership"` + graphql.NoUnmarshalJSON + } + firstPass.AggregateAlertDetails = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Actions + src := firstPass.Actions + *dst = make( + []SharedActionNameType, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedActionNameType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal AggregateAlertDetails.Actions: %w", err) + } + } + } + } + + { + dst := &v.QueryOwnership + src := firstPass.QueryOwnership + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedQueryOwnershipType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal AggregateAlertDetails.QueryOwnership: %w", err) + } + } + } + return nil +} + +type __premarshalAggregateAlertDetails struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + SearchIntervalSeconds int64 `json:"searchIntervalSeconds"` + + ThrottleTimeSeconds int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + TriggerMode TriggerMode `json:"triggerMode"` + + QueryTimestampType QueryTimestampType `json:"queryTimestampType"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *AggregateAlertDetails) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AggregateAlertDetails) __premarshalJSON() (*__premarshalAggregateAlertDetails, error) { + var retval __premarshalAggregateAlertDetails + + retval.Id = v.Id + retval.Name = v.Name + retval.Description = v.Description + retval.QueryString = v.QueryString + retval.SearchIntervalSeconds = v.SearchIntervalSeconds + retval.ThrottleTimeSeconds = v.ThrottleTimeSeconds + retval.ThrottleField = v.ThrottleField + retval.Labels = v.Labels + retval.Enabled = v.Enabled + retval.TriggerMode = v.TriggerMode + retval.QueryTimestampType = v.QueryTimestampType + { + + dst := &retval.Actions + src := v.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal AggregateAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal AggregateAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// AlertDetails includes the GraphQL fields of Alert requested by the fragment AlertDetails. +// The GraphQL type's documentation follows. +// +// An alert. +type AlertDetails struct { + // Id of the alert. + Id string `json:"id"` + // Name of the alert. + Name string `json:"name"` + // LogScale query to execute. + QueryString string `json:"queryString"` + // Start of the relative time interval for the query. + QueryStart string `json:"queryStart"` + // Field to throttle on. + ThrottleField *string `json:"throttleField"` + // Name of the alert. + Description *string `json:"description"` + // Throttle time in milliseconds. + ThrottleTimeMillis int64 `json:"throttleTimeMillis"` + // Flag indicating whether the alert is enabled. + Enabled bool `json:"enabled"` + // Labels attached to the alert. + Labels []string `json:"labels"` + // List of ids for actions to fire on query result. + ActionsV2 []SharedActionNameType `json:"-"` + // Ownership of the query run by this alert + QueryOwnership SharedQueryOwnershipType `json:"-"` +} + +// GetId returns AlertDetails.Id, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetId() string { return v.Id } + +// GetName returns AlertDetails.Name, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetName() string { return v.Name } + +// GetQueryString returns AlertDetails.QueryString, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetQueryString() string { return v.QueryString } + +// GetQueryStart returns AlertDetails.QueryStart, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetQueryStart() string { return v.QueryStart } + +// GetThrottleField returns AlertDetails.ThrottleField, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetThrottleField() *string { return v.ThrottleField } + +// GetDescription returns AlertDetails.Description, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetDescription() *string { return v.Description } + +// GetThrottleTimeMillis returns AlertDetails.ThrottleTimeMillis, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetThrottleTimeMillis() int64 { return v.ThrottleTimeMillis } + +// GetEnabled returns AlertDetails.Enabled, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetEnabled() bool { return v.Enabled } + +// GetLabels returns AlertDetails.Labels, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetLabels() []string { return v.Labels } + +// GetActionsV2 returns AlertDetails.ActionsV2, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetActionsV2() []SharedActionNameType { return v.ActionsV2 } + +// GetQueryOwnership returns AlertDetails.QueryOwnership, and is useful for accessing the field via an interface. +func (v *AlertDetails) GetQueryOwnership() SharedQueryOwnershipType { return v.QueryOwnership } + +func (v *AlertDetails) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *AlertDetails + ActionsV2 []json.RawMessage `json:"actionsV2"` + QueryOwnership json.RawMessage `json:"queryOwnership"` + graphql.NoUnmarshalJSON + } + firstPass.AlertDetails = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.ActionsV2 + src := firstPass.ActionsV2 + *dst = make( + []SharedActionNameType, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedActionNameType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal AlertDetails.ActionsV2: %w", err) + } + } + } + } + + { + dst := &v.QueryOwnership + src := firstPass.QueryOwnership + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedQueryOwnershipType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal AlertDetails.QueryOwnership: %w", err) + } + } + } + return nil +} + +type __premarshalAlertDetails struct { + Id string `json:"id"` + + Name string `json:"name"` + + QueryString string `json:"queryString"` + + QueryStart string `json:"queryStart"` + + ThrottleField *string `json:"throttleField"` + + Description *string `json:"description"` + + ThrottleTimeMillis int64 `json:"throttleTimeMillis"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *AlertDetails) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *AlertDetails) __premarshalJSON() (*__premarshalAlertDetails, error) { + var retval __premarshalAlertDetails + + retval.Id = v.Id + retval.Name = v.Name + retval.QueryString = v.QueryString + retval.QueryStart = v.QueryStart + retval.ThrottleField = v.ThrottleField + retval.Description = v.Description + retval.ThrottleTimeMillis = v.ThrottleTimeMillis + retval.Enabled = v.Enabled + retval.Labels = v.Labels + { + + dst := &retval.ActionsV2 + src := v.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal AlertDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal AlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// AssignParserToIngestTokenAssignParserToIngestTokenV2IngestToken includes the requested fields of the GraphQL type IngestToken. +// The GraphQL type's documentation follows. +// +// An API ingest token used for sending data to LogScale. +type AssignParserToIngestTokenAssignParserToIngestTokenV2IngestToken struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns AssignParserToIngestTokenAssignParserToIngestTokenV2IngestToken.Typename, and is useful for accessing the field via an interface. +func (v *AssignParserToIngestTokenAssignParserToIngestTokenV2IngestToken) GetTypename() *string { + return v.Typename +} + +// AssignParserToIngestTokenResponse is returned by AssignParserToIngestToken on success. +type AssignParserToIngestTokenResponse struct { + // Assign an ingest token to be associated with a parser. + AssignParserToIngestTokenV2 AssignParserToIngestTokenAssignParserToIngestTokenV2IngestToken `json:"assignParserToIngestTokenV2"` +} + +// GetAssignParserToIngestTokenV2 returns AssignParserToIngestTokenResponse.AssignParserToIngestTokenV2, and is useful for accessing the field via an interface. +func (v *AssignParserToIngestTokenResponse) GetAssignParserToIngestTokenV2() AssignParserToIngestTokenAssignParserToIngestTokenV2IngestToken { + return v.AssignParserToIngestTokenV2 +} + +// CreateAggregateAlertCreateAggregateAlert includes the requested fields of the GraphQL type AggregateAlert. +// The GraphQL type's documentation follows. +// +// An aggregate alert. +type CreateAggregateAlertCreateAggregateAlert struct { + AggregateAlertDetails `json:"-"` +} + +// GetId returns CreateAggregateAlertCreateAggregateAlert.Id, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetId() string { return v.AggregateAlertDetails.Id } + +// GetName returns CreateAggregateAlertCreateAggregateAlert.Name, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetName() string { + return v.AggregateAlertDetails.Name +} + +// GetDescription returns CreateAggregateAlertCreateAggregateAlert.Description, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetDescription() *string { + return v.AggregateAlertDetails.Description +} + +// GetQueryString returns CreateAggregateAlertCreateAggregateAlert.QueryString, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetQueryString() string { + return v.AggregateAlertDetails.QueryString +} + +// GetSearchIntervalSeconds returns CreateAggregateAlertCreateAggregateAlert.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetSearchIntervalSeconds() int64 { + return v.AggregateAlertDetails.SearchIntervalSeconds +} + +// GetThrottleTimeSeconds returns CreateAggregateAlertCreateAggregateAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetThrottleTimeSeconds() int64 { + return v.AggregateAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns CreateAggregateAlertCreateAggregateAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetThrottleField() *string { + return v.AggregateAlertDetails.ThrottleField +} + +// GetLabels returns CreateAggregateAlertCreateAggregateAlert.Labels, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetLabels() []string { + return v.AggregateAlertDetails.Labels +} + +// GetEnabled returns CreateAggregateAlertCreateAggregateAlert.Enabled, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetEnabled() bool { + return v.AggregateAlertDetails.Enabled +} + +// GetTriggerMode returns CreateAggregateAlertCreateAggregateAlert.TriggerMode, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetTriggerMode() TriggerMode { + return v.AggregateAlertDetails.TriggerMode +} + +// GetQueryTimestampType returns CreateAggregateAlertCreateAggregateAlert.QueryTimestampType, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetQueryTimestampType() QueryTimestampType { + return v.AggregateAlertDetails.QueryTimestampType +} + +// GetActions returns CreateAggregateAlertCreateAggregateAlert.Actions, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetActions() []SharedActionNameType { + return v.AggregateAlertDetails.Actions +} + +// GetQueryOwnership returns CreateAggregateAlertCreateAggregateAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertCreateAggregateAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AggregateAlertDetails.QueryOwnership +} + +func (v *CreateAggregateAlertCreateAggregateAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateAggregateAlertCreateAggregateAlert + graphql.NoUnmarshalJSON + } + firstPass.CreateAggregateAlertCreateAggregateAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AggregateAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateAggregateAlertCreateAggregateAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + SearchIntervalSeconds int64 `json:"searchIntervalSeconds"` + + ThrottleTimeSeconds int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + TriggerMode TriggerMode `json:"triggerMode"` + + QueryTimestampType QueryTimestampType `json:"queryTimestampType"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *CreateAggregateAlertCreateAggregateAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateAggregateAlertCreateAggregateAlert) __premarshalJSON() (*__premarshalCreateAggregateAlertCreateAggregateAlert, error) { + var retval __premarshalCreateAggregateAlertCreateAggregateAlert + + retval.Id = v.AggregateAlertDetails.Id + retval.Name = v.AggregateAlertDetails.Name + retval.Description = v.AggregateAlertDetails.Description + retval.QueryString = v.AggregateAlertDetails.QueryString + retval.SearchIntervalSeconds = v.AggregateAlertDetails.SearchIntervalSeconds + retval.ThrottleTimeSeconds = v.AggregateAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.AggregateAlertDetails.ThrottleField + retval.Labels = v.AggregateAlertDetails.Labels + retval.Enabled = v.AggregateAlertDetails.Enabled + retval.TriggerMode = v.AggregateAlertDetails.TriggerMode + retval.QueryTimestampType = v.AggregateAlertDetails.QueryTimestampType + { + + dst := &retval.Actions + src := v.AggregateAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateAggregateAlertCreateAggregateAlert.AggregateAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AggregateAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateAggregateAlertCreateAggregateAlert.AggregateAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// CreateAggregateAlertResponse is returned by CreateAggregateAlert on success. +type CreateAggregateAlertResponse struct { + // Create an aggregate alert. + CreateAggregateAlert CreateAggregateAlertCreateAggregateAlert `json:"createAggregateAlert"` +} + +// GetCreateAggregateAlert returns CreateAggregateAlertResponse.CreateAggregateAlert, and is useful for accessing the field via an interface. +func (v *CreateAggregateAlertResponse) GetCreateAggregateAlert() CreateAggregateAlertCreateAggregateAlert { + return v.CreateAggregateAlert +} + +// CreateAlertCreateAlert includes the requested fields of the GraphQL type Alert. +// The GraphQL type's documentation follows. +// +// An alert. +type CreateAlertCreateAlert struct { + AlertDetails `json:"-"` +} + +// GetId returns CreateAlertCreateAlert.Id, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetId() string { return v.AlertDetails.Id } + +// GetName returns CreateAlertCreateAlert.Name, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetName() string { return v.AlertDetails.Name } + +// GetQueryString returns CreateAlertCreateAlert.QueryString, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetQueryString() string { return v.AlertDetails.QueryString } + +// GetQueryStart returns CreateAlertCreateAlert.QueryStart, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetQueryStart() string { return v.AlertDetails.QueryStart } + +// GetThrottleField returns CreateAlertCreateAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetThrottleField() *string { return v.AlertDetails.ThrottleField } + +// GetDescription returns CreateAlertCreateAlert.Description, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetDescription() *string { return v.AlertDetails.Description } + +// GetThrottleTimeMillis returns CreateAlertCreateAlert.ThrottleTimeMillis, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetThrottleTimeMillis() int64 { + return v.AlertDetails.ThrottleTimeMillis +} + +// GetEnabled returns CreateAlertCreateAlert.Enabled, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetEnabled() bool { return v.AlertDetails.Enabled } + +// GetLabels returns CreateAlertCreateAlert.Labels, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetLabels() []string { return v.AlertDetails.Labels } + +// GetActionsV2 returns CreateAlertCreateAlert.ActionsV2, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetActionsV2() []SharedActionNameType { + return v.AlertDetails.ActionsV2 +} + +// GetQueryOwnership returns CreateAlertCreateAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *CreateAlertCreateAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AlertDetails.QueryOwnership +} + +func (v *CreateAlertCreateAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateAlertCreateAlert + graphql.NoUnmarshalJSON + } + firstPass.CreateAlertCreateAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateAlertCreateAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + QueryString string `json:"queryString"` + + QueryStart string `json:"queryStart"` + + ThrottleField *string `json:"throttleField"` + + Description *string `json:"description"` + + ThrottleTimeMillis int64 `json:"throttleTimeMillis"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *CreateAlertCreateAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateAlertCreateAlert) __premarshalJSON() (*__premarshalCreateAlertCreateAlert, error) { + var retval __premarshalCreateAlertCreateAlert + + retval.Id = v.AlertDetails.Id + retval.Name = v.AlertDetails.Name + retval.QueryString = v.AlertDetails.QueryString + retval.QueryStart = v.AlertDetails.QueryStart + retval.ThrottleField = v.AlertDetails.ThrottleField + retval.Description = v.AlertDetails.Description + retval.ThrottleTimeMillis = v.AlertDetails.ThrottleTimeMillis + retval.Enabled = v.AlertDetails.Enabled + retval.Labels = v.AlertDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.AlertDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateAlertCreateAlert.AlertDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateAlertCreateAlert.AlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// CreateAlertResponse is returned by CreateAlert on success. +type CreateAlertResponse struct { + // Create an alert. + CreateAlert CreateAlertCreateAlert `json:"createAlert"` +} + +// GetCreateAlert returns CreateAlertResponse.CreateAlert, and is useful for accessing the field via an interface. +func (v *CreateAlertResponse) GetCreateAlert() CreateAlertCreateAlert { return v.CreateAlert } + +// CreateEmailActionCreateEmailAction includes the requested fields of the GraphQL type EmailAction. +// The GraphQL type's documentation follows. +// +// An email action. +type CreateEmailActionCreateEmailAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateEmailActionCreateEmailAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateEmailActionCreateEmailAction) GetTypename() *string { return v.Typename } + +// CreateEmailActionResponse is returned by CreateEmailAction on success. +type CreateEmailActionResponse struct { + // Create an email action. + CreateEmailAction CreateEmailActionCreateEmailAction `json:"createEmailAction"` +} + +// GetCreateEmailAction returns CreateEmailActionResponse.CreateEmailAction, and is useful for accessing the field via an interface. +func (v *CreateEmailActionResponse) GetCreateEmailAction() CreateEmailActionCreateEmailAction { + return v.CreateEmailAction +} + +// CreateFilterAlertCreateFilterAlert includes the requested fields of the GraphQL type FilterAlert. +// The GraphQL type's documentation follows. +// +// A filter alert. +type CreateFilterAlertCreateFilterAlert struct { + FilterAlertDetails `json:"-"` +} + +// GetId returns CreateFilterAlertCreateFilterAlert.Id, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetId() string { return v.FilterAlertDetails.Id } + +// GetName returns CreateFilterAlertCreateFilterAlert.Name, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetName() string { return v.FilterAlertDetails.Name } + +// GetDescription returns CreateFilterAlertCreateFilterAlert.Description, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetDescription() *string { + return v.FilterAlertDetails.Description +} + +// GetQueryString returns CreateFilterAlertCreateFilterAlert.QueryString, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetQueryString() string { + return v.FilterAlertDetails.QueryString +} + +// GetThrottleTimeSeconds returns CreateFilterAlertCreateFilterAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetThrottleTimeSeconds() *int64 { + return v.FilterAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns CreateFilterAlertCreateFilterAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetThrottleField() *string { + return v.FilterAlertDetails.ThrottleField +} + +// GetLabels returns CreateFilterAlertCreateFilterAlert.Labels, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetLabels() []string { return v.FilterAlertDetails.Labels } + +// GetEnabled returns CreateFilterAlertCreateFilterAlert.Enabled, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetEnabled() bool { return v.FilterAlertDetails.Enabled } + +// GetActions returns CreateFilterAlertCreateFilterAlert.Actions, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetActions() []SharedActionNameType { + return v.FilterAlertDetails.Actions +} + +// GetQueryOwnership returns CreateFilterAlertCreateFilterAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertCreateFilterAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.FilterAlertDetails.QueryOwnership +} + +func (v *CreateFilterAlertCreateFilterAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateFilterAlertCreateFilterAlert + graphql.NoUnmarshalJSON + } + firstPass.CreateFilterAlertCreateFilterAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FilterAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateFilterAlertCreateFilterAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + ThrottleTimeSeconds *int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *CreateFilterAlertCreateFilterAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateFilterAlertCreateFilterAlert) __premarshalJSON() (*__premarshalCreateFilterAlertCreateFilterAlert, error) { + var retval __premarshalCreateFilterAlertCreateFilterAlert + + retval.Id = v.FilterAlertDetails.Id + retval.Name = v.FilterAlertDetails.Name + retval.Description = v.FilterAlertDetails.Description + retval.QueryString = v.FilterAlertDetails.QueryString + retval.ThrottleTimeSeconds = v.FilterAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.FilterAlertDetails.ThrottleField + retval.Labels = v.FilterAlertDetails.Labels + retval.Enabled = v.FilterAlertDetails.Enabled + { + + dst := &retval.Actions + src := v.FilterAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateFilterAlertCreateFilterAlert.FilterAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.FilterAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateFilterAlertCreateFilterAlert.FilterAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// CreateFilterAlertResponse is returned by CreateFilterAlert on success. +type CreateFilterAlertResponse struct { + // Create a filter alert. + CreateFilterAlert CreateFilterAlertCreateFilterAlert `json:"createFilterAlert"` +} + +// GetCreateFilterAlert returns CreateFilterAlertResponse.CreateFilterAlert, and is useful for accessing the field via an interface. +func (v *CreateFilterAlertResponse) GetCreateFilterAlert() CreateFilterAlertCreateFilterAlert { + return v.CreateFilterAlert +} + +// CreateHumioRepoActionCreateHumioRepoAction includes the requested fields of the GraphQL type HumioRepoAction. +// The GraphQL type's documentation follows. +// +// A LogScale repository action. +type CreateHumioRepoActionCreateHumioRepoAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateHumioRepoActionCreateHumioRepoAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateHumioRepoActionCreateHumioRepoAction) GetTypename() *string { return v.Typename } + +// CreateHumioRepoActionResponse is returned by CreateHumioRepoAction on success. +type CreateHumioRepoActionResponse struct { + // Create a LogScale repository action. + CreateHumioRepoAction CreateHumioRepoActionCreateHumioRepoAction `json:"createHumioRepoAction"` +} + +// GetCreateHumioRepoAction returns CreateHumioRepoActionResponse.CreateHumioRepoAction, and is useful for accessing the field via an interface. +func (v *CreateHumioRepoActionResponse) GetCreateHumioRepoAction() CreateHumioRepoActionCreateHumioRepoAction { + return v.CreateHumioRepoAction +} + +// CreateOpsGenieActionCreateOpsGenieAction includes the requested fields of the GraphQL type OpsGenieAction. +// The GraphQL type's documentation follows. +// +// An OpsGenie action +type CreateOpsGenieActionCreateOpsGenieAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateOpsGenieActionCreateOpsGenieAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateOpsGenieActionCreateOpsGenieAction) GetTypename() *string { return v.Typename } + +// CreateOpsGenieActionResponse is returned by CreateOpsGenieAction on success. +type CreateOpsGenieActionResponse struct { + // Create an OpsGenie action. + CreateOpsGenieAction CreateOpsGenieActionCreateOpsGenieAction `json:"createOpsGenieAction"` +} + +// GetCreateOpsGenieAction returns CreateOpsGenieActionResponse.CreateOpsGenieAction, and is useful for accessing the field via an interface. +func (v *CreateOpsGenieActionResponse) GetCreateOpsGenieAction() CreateOpsGenieActionCreateOpsGenieAction { + return v.CreateOpsGenieAction +} + +// CreatePagerDutyActionCreatePagerDutyAction includes the requested fields of the GraphQL type PagerDutyAction. +// The GraphQL type's documentation follows. +// +// A PagerDuty action. +type CreatePagerDutyActionCreatePagerDutyAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreatePagerDutyActionCreatePagerDutyAction.Typename, and is useful for accessing the field via an interface. +func (v *CreatePagerDutyActionCreatePagerDutyAction) GetTypename() *string { return v.Typename } + +// CreatePagerDutyActionResponse is returned by CreatePagerDutyAction on success. +type CreatePagerDutyActionResponse struct { + // Create a PagerDuty action. + CreatePagerDutyAction CreatePagerDutyActionCreatePagerDutyAction `json:"createPagerDutyAction"` +} + +// GetCreatePagerDutyAction returns CreatePagerDutyActionResponse.CreatePagerDutyAction, and is useful for accessing the field via an interface. +func (v *CreatePagerDutyActionResponse) GetCreatePagerDutyAction() CreatePagerDutyActionCreatePagerDutyAction { + return v.CreatePagerDutyAction +} + +// CreateParserOrUpdateCreateParserV2Parser includes the requested fields of the GraphQL type Parser. +// The GraphQL type's documentation follows. +// +// A configured parser for incoming data. +type CreateParserOrUpdateCreateParserV2Parser struct { + ParserDetails `json:"-"` +} + +// GetId returns CreateParserOrUpdateCreateParserV2Parser.Id, and is useful for accessing the field via an interface. +func (v *CreateParserOrUpdateCreateParserV2Parser) GetId() string { return v.ParserDetails.Id } + +// GetName returns CreateParserOrUpdateCreateParserV2Parser.Name, and is useful for accessing the field via an interface. +func (v *CreateParserOrUpdateCreateParserV2Parser) GetName() string { return v.ParserDetails.Name } + +// GetScript returns CreateParserOrUpdateCreateParserV2Parser.Script, and is useful for accessing the field via an interface. +func (v *CreateParserOrUpdateCreateParserV2Parser) GetScript() string { return v.ParserDetails.Script } + +// GetFieldsToTag returns CreateParserOrUpdateCreateParserV2Parser.FieldsToTag, and is useful for accessing the field via an interface. +func (v *CreateParserOrUpdateCreateParserV2Parser) GetFieldsToTag() []string { + return v.ParserDetails.FieldsToTag +} + +// GetTestCases returns CreateParserOrUpdateCreateParserV2Parser.TestCases, and is useful for accessing the field via an interface. +func (v *CreateParserOrUpdateCreateParserV2Parser) GetTestCases() []ParserDetailsTestCasesParserTestCase { + return v.ParserDetails.TestCases +} + +func (v *CreateParserOrUpdateCreateParserV2Parser) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateParserOrUpdateCreateParserV2Parser + graphql.NoUnmarshalJSON + } + firstPass.CreateParserOrUpdateCreateParserV2Parser = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ParserDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateParserOrUpdateCreateParserV2Parser struct { + Id string `json:"id"` + + Name string `json:"name"` + + Script string `json:"script"` + + FieldsToTag []string `json:"fieldsToTag"` + + TestCases []ParserDetailsTestCasesParserTestCase `json:"testCases"` +} + +func (v *CreateParserOrUpdateCreateParserV2Parser) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateParserOrUpdateCreateParserV2Parser) __premarshalJSON() (*__premarshalCreateParserOrUpdateCreateParserV2Parser, error) { + var retval __premarshalCreateParserOrUpdateCreateParserV2Parser + + retval.Id = v.ParserDetails.Id + retval.Name = v.ParserDetails.Name + retval.Script = v.ParserDetails.Script + retval.FieldsToTag = v.ParserDetails.FieldsToTag + retval.TestCases = v.ParserDetails.TestCases + return &retval, nil +} + +// CreateParserOrUpdateResponse is returned by CreateParserOrUpdate on success. +type CreateParserOrUpdateResponse struct { + // Create a parser. + CreateParserV2 CreateParserOrUpdateCreateParserV2Parser `json:"createParserV2"` +} + +// GetCreateParserV2 returns CreateParserOrUpdateResponse.CreateParserV2, and is useful for accessing the field via an interface. +func (v *CreateParserOrUpdateResponse) GetCreateParserV2() CreateParserOrUpdateCreateParserV2Parser { + return v.CreateParserV2 +} + +// CreateRepositoryCreateRepositoryCreateRepositoryMutation includes the requested fields of the GraphQL type CreateRepositoryMutation. +type CreateRepositoryCreateRepositoryCreateRepositoryMutation struct { + Repository CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository `json:"repository"` +} + +// GetRepository returns CreateRepositoryCreateRepositoryCreateRepositoryMutation.Repository, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutation) GetRepository() CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository { + return v.Repository +} + +// CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository struct { + RepositoryDetails `json:"-"` +} + +// GetId returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.Id, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetId() string { + return v.RepositoryDetails.Id +} + +// GetName returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.Name, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetName() string { + return v.RepositoryDetails.Name +} + +// GetDescription returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.Description, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetDescription() *string { + return v.RepositoryDetails.Description +} + +// GetTimeBasedRetention returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.TimeBasedRetention, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetTimeBasedRetention() *float64 { + return v.RepositoryDetails.TimeBasedRetention +} + +// GetIngestSizeBasedRetention returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.IngestSizeBasedRetention, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetIngestSizeBasedRetention() *float64 { + return v.RepositoryDetails.IngestSizeBasedRetention +} + +// GetStorageSizeBasedRetention returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.StorageSizeBasedRetention, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetStorageSizeBasedRetention() *float64 { + return v.RepositoryDetails.StorageSizeBasedRetention +} + +// GetCompressedByteSize returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.CompressedByteSize, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetCompressedByteSize() int64 { + return v.RepositoryDetails.CompressedByteSize +} + +// GetAutomaticSearch returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetAutomaticSearch() bool { + return v.RepositoryDetails.AutomaticSearch +} + +// GetS3ArchivingConfiguration returns CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository.S3ArchivingConfiguration, and is useful for accessing the field via an interface. +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) GetS3ArchivingConfiguration() *RepositoryDetailsS3ArchivingConfigurationS3Configuration { + return v.RepositoryDetails.S3ArchivingConfiguration +} + +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository + graphql.NoUnmarshalJSON + } + firstPass.CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.RepositoryDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateRepositoryCreateRepositoryCreateRepositoryMutationRepository struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + TimeBasedRetention *float64 `json:"timeBasedRetention"` + + IngestSizeBasedRetention *float64 `json:"ingestSizeBasedRetention"` + + StorageSizeBasedRetention *float64 `json:"storageSizeBasedRetention"` + + CompressedByteSize int64 `json:"compressedByteSize"` + + AutomaticSearch bool `json:"automaticSearch"` + + S3ArchivingConfiguration *RepositoryDetailsS3ArchivingConfigurationS3Configuration `json:"s3ArchivingConfiguration"` +} + +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateRepositoryCreateRepositoryCreateRepositoryMutationRepository) __premarshalJSON() (*__premarshalCreateRepositoryCreateRepositoryCreateRepositoryMutationRepository, error) { + var retval __premarshalCreateRepositoryCreateRepositoryCreateRepositoryMutationRepository + + retval.Id = v.RepositoryDetails.Id + retval.Name = v.RepositoryDetails.Name + retval.Description = v.RepositoryDetails.Description + retval.TimeBasedRetention = v.RepositoryDetails.TimeBasedRetention + retval.IngestSizeBasedRetention = v.RepositoryDetails.IngestSizeBasedRetention + retval.StorageSizeBasedRetention = v.RepositoryDetails.StorageSizeBasedRetention + retval.CompressedByteSize = v.RepositoryDetails.CompressedByteSize + retval.AutomaticSearch = v.RepositoryDetails.AutomaticSearch + retval.S3ArchivingConfiguration = v.RepositoryDetails.S3ArchivingConfiguration + return &retval, nil +} + +// CreateRepositoryResponse is returned by CreateRepository on success. +type CreateRepositoryResponse struct { + // Create a new repository. + CreateRepository CreateRepositoryCreateRepositoryCreateRepositoryMutation `json:"createRepository"` +} + +// GetCreateRepository returns CreateRepositoryResponse.CreateRepository, and is useful for accessing the field via an interface. +func (v *CreateRepositoryResponse) GetCreateRepository() CreateRepositoryCreateRepositoryCreateRepositoryMutation { + return v.CreateRepository +} + +// CreateScheduledSearchCreateScheduledSearch includes the requested fields of the GraphQL type ScheduledSearch. +// The GraphQL type's documentation follows. +// +// Information about a scheduled search +type CreateScheduledSearchCreateScheduledSearch struct { + ScheduledSearchDetails `json:"-"` +} + +// GetId returns CreateScheduledSearchCreateScheduledSearch.Id, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetId() string { + return v.ScheduledSearchDetails.Id +} + +// GetName returns CreateScheduledSearchCreateScheduledSearch.Name, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetName() string { + return v.ScheduledSearchDetails.Name +} + +// GetDescription returns CreateScheduledSearchCreateScheduledSearch.Description, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetDescription() *string { + return v.ScheduledSearchDetails.Description +} + +// GetQueryString returns CreateScheduledSearchCreateScheduledSearch.QueryString, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetQueryString() string { + return v.ScheduledSearchDetails.QueryString +} + +// GetStart returns CreateScheduledSearchCreateScheduledSearch.Start, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetStart() string { + return v.ScheduledSearchDetails.Start +} + +// GetEnd returns CreateScheduledSearchCreateScheduledSearch.End, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetEnd() string { + return v.ScheduledSearchDetails.End +} + +// GetTimeZone returns CreateScheduledSearchCreateScheduledSearch.TimeZone, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetTimeZone() string { + return v.ScheduledSearchDetails.TimeZone +} + +// GetSchedule returns CreateScheduledSearchCreateScheduledSearch.Schedule, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetSchedule() string { + return v.ScheduledSearchDetails.Schedule +} + +// GetBackfillLimit returns CreateScheduledSearchCreateScheduledSearch.BackfillLimit, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetBackfillLimit() int { + return v.ScheduledSearchDetails.BackfillLimit +} + +// GetEnabled returns CreateScheduledSearchCreateScheduledSearch.Enabled, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetEnabled() bool { + return v.ScheduledSearchDetails.Enabled +} + +// GetLabels returns CreateScheduledSearchCreateScheduledSearch.Labels, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetLabels() []string { + return v.ScheduledSearchDetails.Labels +} + +// GetActionsV2 returns CreateScheduledSearchCreateScheduledSearch.ActionsV2, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetActionsV2() []SharedActionNameType { + return v.ScheduledSearchDetails.ActionsV2 +} + +// GetQueryOwnership returns CreateScheduledSearchCreateScheduledSearch.QueryOwnership, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchCreateScheduledSearch) GetQueryOwnership() SharedQueryOwnershipType { + return v.ScheduledSearchDetails.QueryOwnership +} + +func (v *CreateScheduledSearchCreateScheduledSearch) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CreateScheduledSearchCreateScheduledSearch + graphql.NoUnmarshalJSON + } + firstPass.CreateScheduledSearchCreateScheduledSearch = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ScheduledSearchDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalCreateScheduledSearchCreateScheduledSearch struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + Start string `json:"start"` + + End string `json:"end"` + + TimeZone string `json:"timeZone"` + + Schedule string `json:"schedule"` + + BackfillLimit int `json:"backfillLimit"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *CreateScheduledSearchCreateScheduledSearch) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CreateScheduledSearchCreateScheduledSearch) __premarshalJSON() (*__premarshalCreateScheduledSearchCreateScheduledSearch, error) { + var retval __premarshalCreateScheduledSearchCreateScheduledSearch + + retval.Id = v.ScheduledSearchDetails.Id + retval.Name = v.ScheduledSearchDetails.Name + retval.Description = v.ScheduledSearchDetails.Description + retval.QueryString = v.ScheduledSearchDetails.QueryString + retval.Start = v.ScheduledSearchDetails.Start + retval.End = v.ScheduledSearchDetails.End + retval.TimeZone = v.ScheduledSearchDetails.TimeZone + retval.Schedule = v.ScheduledSearchDetails.Schedule + retval.BackfillLimit = v.ScheduledSearchDetails.BackfillLimit + retval.Enabled = v.ScheduledSearchDetails.Enabled + retval.Labels = v.ScheduledSearchDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.ScheduledSearchDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateScheduledSearchCreateScheduledSearch.ScheduledSearchDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.ScheduledSearchDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal CreateScheduledSearchCreateScheduledSearch.ScheduledSearchDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// CreateScheduledSearchResponse is returned by CreateScheduledSearch on success. +type CreateScheduledSearchResponse struct { + // Create a scheduled search. + CreateScheduledSearch CreateScheduledSearchCreateScheduledSearch `json:"createScheduledSearch"` +} + +// GetCreateScheduledSearch returns CreateScheduledSearchResponse.CreateScheduledSearch, and is useful for accessing the field via an interface. +func (v *CreateScheduledSearchResponse) GetCreateScheduledSearch() CreateScheduledSearchCreateScheduledSearch { + return v.CreateScheduledSearch +} + +// CreateSlackActionCreateSlackAction includes the requested fields of the GraphQL type SlackAction. +// The GraphQL type's documentation follows. +// +// A Slack action +type CreateSlackActionCreateSlackAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateSlackActionCreateSlackAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateSlackActionCreateSlackAction) GetTypename() *string { return v.Typename } + +// CreateSlackActionResponse is returned by CreateSlackAction on success. +type CreateSlackActionResponse struct { + // Create a Slack action. + CreateSlackAction CreateSlackActionCreateSlackAction `json:"createSlackAction"` +} + +// GetCreateSlackAction returns CreateSlackActionResponse.CreateSlackAction, and is useful for accessing the field via an interface. +func (v *CreateSlackActionResponse) GetCreateSlackAction() CreateSlackActionCreateSlackAction { + return v.CreateSlackAction +} + +// CreateSlackPostMessageActionCreateSlackPostMessageAction includes the requested fields of the GraphQL type SlackPostMessageAction. +// The GraphQL type's documentation follows. +// +// A slack post-message action. +type CreateSlackPostMessageActionCreateSlackPostMessageAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateSlackPostMessageActionCreateSlackPostMessageAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateSlackPostMessageActionCreateSlackPostMessageAction) GetTypename() *string { + return v.Typename +} + +// CreateSlackPostMessageActionResponse is returned by CreateSlackPostMessageAction on success. +type CreateSlackPostMessageActionResponse struct { + // Create a post message Slack action. + CreateSlackPostMessageAction CreateSlackPostMessageActionCreateSlackPostMessageAction `json:"createSlackPostMessageAction"` +} + +// GetCreateSlackPostMessageAction returns CreateSlackPostMessageActionResponse.CreateSlackPostMessageAction, and is useful for accessing the field via an interface. +func (v *CreateSlackPostMessageActionResponse) GetCreateSlackPostMessageAction() CreateSlackPostMessageActionCreateSlackPostMessageAction { + return v.CreateSlackPostMessageAction +} + +// CreateVictorOpsActionCreateVictorOpsAction includes the requested fields of the GraphQL type VictorOpsAction. +// The GraphQL type's documentation follows. +// +// A VictorOps action. +type CreateVictorOpsActionCreateVictorOpsAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateVictorOpsActionCreateVictorOpsAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateVictorOpsActionCreateVictorOpsAction) GetTypename() *string { return v.Typename } + +// CreateVictorOpsActionResponse is returned by CreateVictorOpsAction on success. +type CreateVictorOpsActionResponse struct { + // Create a VictorOps action. + CreateVictorOpsAction CreateVictorOpsActionCreateVictorOpsAction `json:"createVictorOpsAction"` +} + +// GetCreateVictorOpsAction returns CreateVictorOpsActionResponse.CreateVictorOpsAction, and is useful for accessing the field via an interface. +func (v *CreateVictorOpsActionResponse) GetCreateVictorOpsAction() CreateVictorOpsActionCreateVictorOpsAction { + return v.CreateVictorOpsAction +} + +// CreateViewCreateView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type CreateViewCreateView struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateViewCreateView.Typename, and is useful for accessing the field via an interface. +func (v *CreateViewCreateView) GetTypename() *string { return v.Typename } + +// CreateViewResponse is returned by CreateView on success. +type CreateViewResponse struct { + // Create a new view. + CreateView CreateViewCreateView `json:"createView"` +} + +// GetCreateView returns CreateViewResponse.CreateView, and is useful for accessing the field via an interface. +func (v *CreateViewResponse) GetCreateView() CreateViewCreateView { return v.CreateView } + +// CreateWebhookActionCreateWebhookAction includes the requested fields of the GraphQL type WebhookAction. +// The GraphQL type's documentation follows. +// +// A webhook action +type CreateWebhookActionCreateWebhookAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns CreateWebhookActionCreateWebhookAction.Typename, and is useful for accessing the field via an interface. +func (v *CreateWebhookActionCreateWebhookAction) GetTypename() *string { return v.Typename } + +// CreateWebhookActionResponse is returned by CreateWebhookAction on success. +type CreateWebhookActionResponse struct { + // Create a webhook action. + CreateWebhookAction CreateWebhookActionCreateWebhookAction `json:"createWebhookAction"` +} + +// GetCreateWebhookAction returns CreateWebhookActionResponse.CreateWebhookAction, and is useful for accessing the field via an interface. +func (v *CreateWebhookActionResponse) GetCreateWebhookAction() CreateWebhookActionCreateWebhookAction { + return v.CreateWebhookAction +} + +// DeleteActionByIDResponse is returned by DeleteActionByID on success. +type DeleteActionByIDResponse struct { + // Delete an action. + DeleteAction bool `json:"deleteAction"` +} + +// GetDeleteAction returns DeleteActionByIDResponse.DeleteAction, and is useful for accessing the field via an interface. +func (v *DeleteActionByIDResponse) GetDeleteAction() bool { return v.DeleteAction } + +// DeleteAggregateAlertResponse is returned by DeleteAggregateAlert on success. +type DeleteAggregateAlertResponse struct { + // Delete an aggregate alert. + DeleteAggregateAlert bool `json:"deleteAggregateAlert"` +} + +// GetDeleteAggregateAlert returns DeleteAggregateAlertResponse.DeleteAggregateAlert, and is useful for accessing the field via an interface. +func (v *DeleteAggregateAlertResponse) GetDeleteAggregateAlert() bool { return v.DeleteAggregateAlert } + +// DeleteAlertByIDResponse is returned by DeleteAlertByID on success. +type DeleteAlertByIDResponse struct { + // Delete an alert. + DeleteAlert bool `json:"deleteAlert"` +} + +// GetDeleteAlert returns DeleteAlertByIDResponse.DeleteAlert, and is useful for accessing the field via an interface. +func (v *DeleteAlertByIDResponse) GetDeleteAlert() bool { return v.DeleteAlert } + +// DeleteFilterAlertResponse is returned by DeleteFilterAlert on success. +type DeleteFilterAlertResponse struct { + // Delete a filter alert. + DeleteFilterAlert bool `json:"deleteFilterAlert"` +} + +// GetDeleteFilterAlert returns DeleteFilterAlertResponse.DeleteFilterAlert, and is useful for accessing the field via an interface. +func (v *DeleteFilterAlertResponse) GetDeleteFilterAlert() bool { return v.DeleteFilterAlert } + +// DeleteParserByIDDeleteParserBooleanResultType includes the requested fields of the GraphQL type BooleanResultType. +type DeleteParserByIDDeleteParserBooleanResultType struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns DeleteParserByIDDeleteParserBooleanResultType.Typename, and is useful for accessing the field via an interface. +func (v *DeleteParserByIDDeleteParserBooleanResultType) GetTypename() *string { return v.Typename } + +// DeleteParserByIDResponse is returned by DeleteParserByID on success. +type DeleteParserByIDResponse struct { + // Delete a parser. + DeleteParser DeleteParserByIDDeleteParserBooleanResultType `json:"deleteParser"` +} + +// GetDeleteParser returns DeleteParserByIDResponse.DeleteParser, and is useful for accessing the field via an interface. +func (v *DeleteParserByIDResponse) GetDeleteParser() DeleteParserByIDDeleteParserBooleanResultType { + return v.DeleteParser +} + +// DeleteScheduledSearchByIDResponse is returned by DeleteScheduledSearchByID on success. +type DeleteScheduledSearchByIDResponse struct { + // Delete a scheduled search. + DeleteScheduledSearch bool `json:"deleteScheduledSearch"` +} + +// GetDeleteScheduledSearch returns DeleteScheduledSearchByIDResponse.DeleteScheduledSearch, and is useful for accessing the field via an interface. +func (v *DeleteScheduledSearchByIDResponse) GetDeleteScheduledSearch() bool { + return v.DeleteScheduledSearch +} + +// DeleteSearchDomainDeleteSearchDomainBooleanResultType includes the requested fields of the GraphQL type BooleanResultType. +type DeleteSearchDomainDeleteSearchDomainBooleanResultType struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns DeleteSearchDomainDeleteSearchDomainBooleanResultType.Typename, and is useful for accessing the field via an interface. +func (v *DeleteSearchDomainDeleteSearchDomainBooleanResultType) GetTypename() *string { + return v.Typename +} + +// DeleteSearchDomainResponse is returned by DeleteSearchDomain on success. +type DeleteSearchDomainResponse struct { + // Delete a repository or view. + DeleteSearchDomain DeleteSearchDomainDeleteSearchDomainBooleanResultType `json:"deleteSearchDomain"` +} + +// GetDeleteSearchDomain returns DeleteSearchDomainResponse.DeleteSearchDomain, and is useful for accessing the field via an interface. +func (v *DeleteSearchDomainResponse) GetDeleteSearchDomain() DeleteSearchDomainDeleteSearchDomainBooleanResultType { + return v.DeleteSearchDomain +} + +// DisableS3ArchivingResponse is returned by DisableS3Archiving on success. +type DisableS3ArchivingResponse struct { + // Disables the archiving job for the repository. + S3DisableArchiving DisableS3ArchivingS3DisableArchivingBooleanResultType `json:"s3DisableArchiving"` +} + +// GetS3DisableArchiving returns DisableS3ArchivingResponse.S3DisableArchiving, and is useful for accessing the field via an interface. +func (v *DisableS3ArchivingResponse) GetS3DisableArchiving() DisableS3ArchivingS3DisableArchivingBooleanResultType { + return v.S3DisableArchiving +} + +// DisableS3ArchivingS3DisableArchivingBooleanResultType includes the requested fields of the GraphQL type BooleanResultType. +type DisableS3ArchivingS3DisableArchivingBooleanResultType struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns DisableS3ArchivingS3DisableArchivingBooleanResultType.Typename, and is useful for accessing the field via an interface. +func (v *DisableS3ArchivingS3DisableArchivingBooleanResultType) GetTypename() *string { + return v.Typename +} + +// EnableS3ArchivingResponse is returned by EnableS3Archiving on success. +type EnableS3ArchivingResponse struct { + // Enables the archiving job for the repository. + S3EnableArchiving EnableS3ArchivingS3EnableArchivingBooleanResultType `json:"s3EnableArchiving"` +} + +// GetS3EnableArchiving returns EnableS3ArchivingResponse.S3EnableArchiving, and is useful for accessing the field via an interface. +func (v *EnableS3ArchivingResponse) GetS3EnableArchiving() EnableS3ArchivingS3EnableArchivingBooleanResultType { + return v.S3EnableArchiving +} + +// EnableS3ArchivingS3EnableArchivingBooleanResultType includes the requested fields of the GraphQL type BooleanResultType. +type EnableS3ArchivingS3EnableArchivingBooleanResultType struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns EnableS3ArchivingS3EnableArchivingBooleanResultType.Typename, and is useful for accessing the field via an interface. +func (v *EnableS3ArchivingS3EnableArchivingBooleanResultType) GetTypename() *string { + return v.Typename +} + +// Asserts that a given field has an expected value after having been parsed. +type FieldHasValueInput struct { + // Asserts that a given field has an expected value after having been parsed. + FieldName string `json:"fieldName"` + // Asserts that a given field has an expected value after having been parsed. + ExpectedValue string `json:"expectedValue"` +} + +// GetFieldName returns FieldHasValueInput.FieldName, and is useful for accessing the field via an interface. +func (v *FieldHasValueInput) GetFieldName() string { return v.FieldName } + +// GetExpectedValue returns FieldHasValueInput.ExpectedValue, and is useful for accessing the field via an interface. +func (v *FieldHasValueInput) GetExpectedValue() string { return v.ExpectedValue } + +// FilterAlertDetails includes the GraphQL fields of FilterAlert requested by the fragment FilterAlertDetails. +// The GraphQL type's documentation follows. +// +// A filter alert. +type FilterAlertDetails struct { + // Id of the filter alert. + Id string `json:"id"` + // Name of the filter alert. + Name string `json:"name"` + // Description of the filter alert. + Description *string `json:"description"` + // LogScale query to execute. + QueryString string `json:"queryString"` + // Throttle time in seconds. + ThrottleTimeSeconds *int64 `json:"throttleTimeSeconds"` + // A field to throttle on. Can only be set if throttleTimeSeconds is set. + ThrottleField *string `json:"throttleField"` + // Labels attached to the filter alert. + Labels []string `json:"labels"` + // Flag indicating whether the filter alert is enabled. + Enabled bool `json:"enabled"` + // List of ids for actions to fire on query result. + Actions []SharedActionNameType `json:"-"` + // Ownership of the query run by this alert + QueryOwnership SharedQueryOwnershipType `json:"-"` +} + +// GetId returns FilterAlertDetails.Id, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetId() string { return v.Id } + +// GetName returns FilterAlertDetails.Name, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetName() string { return v.Name } + +// GetDescription returns FilterAlertDetails.Description, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetDescription() *string { return v.Description } + +// GetQueryString returns FilterAlertDetails.QueryString, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetQueryString() string { return v.QueryString } + +// GetThrottleTimeSeconds returns FilterAlertDetails.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetThrottleTimeSeconds() *int64 { return v.ThrottleTimeSeconds } + +// GetThrottleField returns FilterAlertDetails.ThrottleField, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetThrottleField() *string { return v.ThrottleField } + +// GetLabels returns FilterAlertDetails.Labels, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetLabels() []string { return v.Labels } + +// GetEnabled returns FilterAlertDetails.Enabled, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetEnabled() bool { return v.Enabled } + +// GetActions returns FilterAlertDetails.Actions, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetActions() []SharedActionNameType { return v.Actions } + +// GetQueryOwnership returns FilterAlertDetails.QueryOwnership, and is useful for accessing the field via an interface. +func (v *FilterAlertDetails) GetQueryOwnership() SharedQueryOwnershipType { return v.QueryOwnership } + +func (v *FilterAlertDetails) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *FilterAlertDetails + Actions []json.RawMessage `json:"actions"` + QueryOwnership json.RawMessage `json:"queryOwnership"` + graphql.NoUnmarshalJSON + } + firstPass.FilterAlertDetails = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Actions + src := firstPass.Actions + *dst = make( + []SharedActionNameType, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedActionNameType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal FilterAlertDetails.Actions: %w", err) + } + } + } + } + + { + dst := &v.QueryOwnership + src := firstPass.QueryOwnership + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedQueryOwnershipType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal FilterAlertDetails.QueryOwnership: %w", err) + } + } + } + return nil +} + +type __premarshalFilterAlertDetails struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + ThrottleTimeSeconds *int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *FilterAlertDetails) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *FilterAlertDetails) __premarshalJSON() (*__premarshalFilterAlertDetails, error) { + var retval __premarshalFilterAlertDetails + + retval.Id = v.Id + retval.Name = v.Name + retval.Description = v.Description + retval.QueryString = v.QueryString + retval.ThrottleTimeSeconds = v.ThrottleTimeSeconds + retval.ThrottleField = v.ThrottleField + retval.Labels = v.Labels + retval.Enabled = v.Enabled + { + + dst := &retval.Actions + src := v.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal FilterAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal FilterAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// GetActionByIDResponse is returned by GetActionByID on success. +type GetActionByIDResponse struct { + SearchDomain GetActionByIDSearchDomain `json:"-"` +} + +// GetSearchDomain returns GetActionByIDResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *GetActionByIDResponse) GetSearchDomain() GetActionByIDSearchDomain { return v.SearchDomain } + +func (v *GetActionByIDResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetActionByIDSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetActionByIDResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalGetActionByIDResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *GetActionByIDResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDResponse) __premarshalJSON() (*__premarshalGetActionByIDResponse, error) { + var retval __premarshalGetActionByIDResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalGetActionByIDSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetActionByIDResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// GetActionByIDSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// GetActionByIDSearchDomain is implemented by the following types: +// GetActionByIDSearchDomainRepository +// GetActionByIDSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type GetActionByIDSearchDomain interface { + implementsGraphQLInterfaceGetActionByIDSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetAction returns the interface-field "action" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetAction() GetActionByIDSearchDomainAction +} + +func (v *GetActionByIDSearchDomainRepository) implementsGraphQLInterfaceGetActionByIDSearchDomain() {} +func (v *GetActionByIDSearchDomainView) implementsGraphQLInterfaceGetActionByIDSearchDomain() {} + +func __unmarshalGetActionByIDSearchDomain(b []byte, v *GetActionByIDSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(GetActionByIDSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(GetActionByIDSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetActionByIDSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalGetActionByIDSearchDomain(v *GetActionByIDSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetActionByIDSearchDomainRepository: + typename = "Repository" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainRepository + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainView: + typename = "View" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainView + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetActionByIDSearchDomain: "%T"`, v) + } +} + +// GetActionByIDSearchDomainAction includes the requested fields of the GraphQL interface Action. +// +// GetActionByIDSearchDomainAction is implemented by the following types: +// GetActionByIDSearchDomainActionEmailAction +// GetActionByIDSearchDomainActionHumioRepoAction +// GetActionByIDSearchDomainActionOpsGenieAction +// GetActionByIDSearchDomainActionPagerDutyAction +// GetActionByIDSearchDomainActionSlackAction +// GetActionByIDSearchDomainActionSlackPostMessageAction +// GetActionByIDSearchDomainActionUploadFileAction +// GetActionByIDSearchDomainActionVictorOpsAction +// GetActionByIDSearchDomainActionWebhookAction +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type GetActionByIDSearchDomainAction interface { + implementsGraphQLInterfaceGetActionByIDSearchDomainAction() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + ActionDetails +} + +func (v *GetActionByIDSearchDomainActionEmailAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionHumioRepoAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionOpsGenieAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionPagerDutyAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionSlackAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionUploadFileAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionVictorOpsAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} +func (v *GetActionByIDSearchDomainActionWebhookAction) implementsGraphQLInterfaceGetActionByIDSearchDomainAction() { +} + +func __unmarshalGetActionByIDSearchDomainAction(b []byte, v *GetActionByIDSearchDomainAction) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "EmailAction": + *v = new(GetActionByIDSearchDomainActionEmailAction) + return json.Unmarshal(b, *v) + case "HumioRepoAction": + *v = new(GetActionByIDSearchDomainActionHumioRepoAction) + return json.Unmarshal(b, *v) + case "OpsGenieAction": + *v = new(GetActionByIDSearchDomainActionOpsGenieAction) + return json.Unmarshal(b, *v) + case "PagerDutyAction": + *v = new(GetActionByIDSearchDomainActionPagerDutyAction) + return json.Unmarshal(b, *v) + case "SlackAction": + *v = new(GetActionByIDSearchDomainActionSlackAction) + return json.Unmarshal(b, *v) + case "SlackPostMessageAction": + *v = new(GetActionByIDSearchDomainActionSlackPostMessageAction) + return json.Unmarshal(b, *v) + case "UploadFileAction": + *v = new(GetActionByIDSearchDomainActionUploadFileAction) + return json.Unmarshal(b, *v) + case "VictorOpsAction": + *v = new(GetActionByIDSearchDomainActionVictorOpsAction) + return json.Unmarshal(b, *v) + case "WebhookAction": + *v = new(GetActionByIDSearchDomainActionWebhookAction) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Action.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetActionByIDSearchDomainAction: "%v"`, tn.TypeName) + } +} + +func __marshalGetActionByIDSearchDomainAction(v *GetActionByIDSearchDomainAction) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetActionByIDSearchDomainActionEmailAction: + typename = "EmailAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionEmailAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionHumioRepoAction: + typename = "HumioRepoAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionHumioRepoAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionOpsGenieAction: + typename = "OpsGenieAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionOpsGenieAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionPagerDutyAction: + typename = "PagerDutyAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionPagerDutyAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionSlackAction: + typename = "SlackAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionSlackAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionSlackPostMessageAction: + typename = "SlackPostMessageAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionSlackPostMessageAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionUploadFileAction: + typename = "UploadFileAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionUploadFileAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionVictorOpsAction: + typename = "VictorOpsAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionVictorOpsAction + }{typename, premarshaled} + return json.Marshal(result) + case *GetActionByIDSearchDomainActionWebhookAction: + typename = "WebhookAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalGetActionByIDSearchDomainActionWebhookAction + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetActionByIDSearchDomainAction: "%T"`, v) + } +} + +// GetActionByIDSearchDomainActionEmailAction includes the requested fields of the GraphQL type EmailAction. +// The GraphQL type's documentation follows. +// +// An email action. +type GetActionByIDSearchDomainActionEmailAction struct { + Typename *string `json:"__typename"` + ActionDetailsEmailAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionEmailAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionEmailAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetId() string { + return v.ActionDetailsEmailAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionEmailAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetName() string { + return v.ActionDetailsEmailAction.Name +} + +// GetRecipients returns GetActionByIDSearchDomainActionEmailAction.Recipients, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetRecipients() []string { + return v.ActionDetailsEmailAction.Recipients +} + +// GetSubjectTemplate returns GetActionByIDSearchDomainActionEmailAction.SubjectTemplate, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetSubjectTemplate() *string { + return v.ActionDetailsEmailAction.SubjectTemplate +} + +// GetEmailBodyTemplate returns GetActionByIDSearchDomainActionEmailAction.EmailBodyTemplate, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetEmailBodyTemplate() *string { + return v.ActionDetailsEmailAction.EmailBodyTemplate +} + +// GetUseProxy returns GetActionByIDSearchDomainActionEmailAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionEmailAction) GetUseProxy() bool { + return v.ActionDetailsEmailAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionEmailAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionEmailAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionEmailAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsEmailAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionEmailAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Recipients []string `json:"recipients"` + + SubjectTemplate *string `json:"subjectTemplate"` + + EmailBodyTemplate *string `json:"emailBodyTemplate"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionEmailAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionEmailAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionEmailAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionEmailAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsEmailAction.Id + retval.Name = v.ActionDetailsEmailAction.Name + retval.Recipients = v.ActionDetailsEmailAction.Recipients + retval.SubjectTemplate = v.ActionDetailsEmailAction.SubjectTemplate + retval.EmailBodyTemplate = v.ActionDetailsEmailAction.EmailBodyTemplate + retval.UseProxy = v.ActionDetailsEmailAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainActionHumioRepoAction includes the requested fields of the GraphQL type HumioRepoAction. +// The GraphQL type's documentation follows. +// +// A LogScale repository action. +type GetActionByIDSearchDomainActionHumioRepoAction struct { + Typename *string `json:"__typename"` + ActionDetailsHumioRepoAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionHumioRepoAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionHumioRepoAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionHumioRepoAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionHumioRepoAction) GetId() string { + return v.ActionDetailsHumioRepoAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionHumioRepoAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionHumioRepoAction) GetName() string { + return v.ActionDetailsHumioRepoAction.Name +} + +// GetIngestToken returns GetActionByIDSearchDomainActionHumioRepoAction.IngestToken, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionHumioRepoAction) GetIngestToken() string { + return v.ActionDetailsHumioRepoAction.IngestToken +} + +func (v *GetActionByIDSearchDomainActionHumioRepoAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionHumioRepoAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionHumioRepoAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsHumioRepoAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionHumioRepoAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + IngestToken string `json:"ingestToken"` +} + +func (v *GetActionByIDSearchDomainActionHumioRepoAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionHumioRepoAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionHumioRepoAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionHumioRepoAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsHumioRepoAction.Id + retval.Name = v.ActionDetailsHumioRepoAction.Name + retval.IngestToken = v.ActionDetailsHumioRepoAction.IngestToken + return &retval, nil +} + +// GetActionByIDSearchDomainActionOpsGenieAction includes the requested fields of the GraphQL type OpsGenieAction. +// The GraphQL type's documentation follows. +// +// An OpsGenie action +type GetActionByIDSearchDomainActionOpsGenieAction struct { + Typename *string `json:"__typename"` + ActionDetailsOpsGenieAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionOpsGenieAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionOpsGenieAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionOpsGenieAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionOpsGenieAction) GetId() string { + return v.ActionDetailsOpsGenieAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionOpsGenieAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionOpsGenieAction) GetName() string { + return v.ActionDetailsOpsGenieAction.Name +} + +// GetApiUrl returns GetActionByIDSearchDomainActionOpsGenieAction.ApiUrl, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionOpsGenieAction) GetApiUrl() string { + return v.ActionDetailsOpsGenieAction.ApiUrl +} + +// GetGenieKey returns GetActionByIDSearchDomainActionOpsGenieAction.GenieKey, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionOpsGenieAction) GetGenieKey() string { + return v.ActionDetailsOpsGenieAction.GenieKey +} + +// GetUseProxy returns GetActionByIDSearchDomainActionOpsGenieAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionOpsGenieAction) GetUseProxy() bool { + return v.ActionDetailsOpsGenieAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionOpsGenieAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionOpsGenieAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionOpsGenieAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsOpsGenieAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionOpsGenieAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + ApiUrl string `json:"apiUrl"` + + GenieKey string `json:"genieKey"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionOpsGenieAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionOpsGenieAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionOpsGenieAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionOpsGenieAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsOpsGenieAction.Id + retval.Name = v.ActionDetailsOpsGenieAction.Name + retval.ApiUrl = v.ActionDetailsOpsGenieAction.ApiUrl + retval.GenieKey = v.ActionDetailsOpsGenieAction.GenieKey + retval.UseProxy = v.ActionDetailsOpsGenieAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainActionPagerDutyAction includes the requested fields of the GraphQL type PagerDutyAction. +// The GraphQL type's documentation follows. +// +// A PagerDuty action. +type GetActionByIDSearchDomainActionPagerDutyAction struct { + Typename *string `json:"__typename"` + ActionDetailsPagerDutyAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionPagerDutyAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionPagerDutyAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionPagerDutyAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionPagerDutyAction) GetId() string { + return v.ActionDetailsPagerDutyAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionPagerDutyAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionPagerDutyAction) GetName() string { + return v.ActionDetailsPagerDutyAction.Name +} + +// GetSeverity returns GetActionByIDSearchDomainActionPagerDutyAction.Severity, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionPagerDutyAction) GetSeverity() string { + return v.ActionDetailsPagerDutyAction.Severity +} + +// GetRoutingKey returns GetActionByIDSearchDomainActionPagerDutyAction.RoutingKey, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionPagerDutyAction) GetRoutingKey() string { + return v.ActionDetailsPagerDutyAction.RoutingKey +} + +// GetUseProxy returns GetActionByIDSearchDomainActionPagerDutyAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionPagerDutyAction) GetUseProxy() bool { + return v.ActionDetailsPagerDutyAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionPagerDutyAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionPagerDutyAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionPagerDutyAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsPagerDutyAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionPagerDutyAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Severity string `json:"severity"` + + RoutingKey string `json:"routingKey"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionPagerDutyAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionPagerDutyAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionPagerDutyAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionPagerDutyAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsPagerDutyAction.Id + retval.Name = v.ActionDetailsPagerDutyAction.Name + retval.Severity = v.ActionDetailsPagerDutyAction.Severity + retval.RoutingKey = v.ActionDetailsPagerDutyAction.RoutingKey + retval.UseProxy = v.ActionDetailsPagerDutyAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainActionSlackAction includes the requested fields of the GraphQL type SlackAction. +// The GraphQL type's documentation follows. +// +// A Slack action +type GetActionByIDSearchDomainActionSlackAction struct { + Typename *string `json:"__typename"` + ActionDetailsSlackAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionSlackAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionSlackAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackAction) GetId() string { + return v.ActionDetailsSlackAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionSlackAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackAction) GetName() string { + return v.ActionDetailsSlackAction.Name +} + +// GetUrl returns GetActionByIDSearchDomainActionSlackAction.Url, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackAction) GetUrl() string { + return v.ActionDetailsSlackAction.Url +} + +// GetFields returns GetActionByIDSearchDomainActionSlackAction.Fields, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackAction) GetFields() []ActionDetailsFieldsSlackFieldEntry { + return v.ActionDetailsSlackAction.Fields +} + +// GetUseProxy returns GetActionByIDSearchDomainActionSlackAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackAction) GetUseProxy() bool { + return v.ActionDetailsSlackAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionSlackAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionSlackAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionSlackAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsSlackAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionSlackAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Url string `json:"url"` + + Fields []ActionDetailsFieldsSlackFieldEntry `json:"fields"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionSlackAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionSlackAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionSlackAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionSlackAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsSlackAction.Id + retval.Name = v.ActionDetailsSlackAction.Name + retval.Url = v.ActionDetailsSlackAction.Url + retval.Fields = v.ActionDetailsSlackAction.Fields + retval.UseProxy = v.ActionDetailsSlackAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainActionSlackPostMessageAction includes the requested fields of the GraphQL type SlackPostMessageAction. +// The GraphQL type's documentation follows. +// +// A slack post-message action. +type GetActionByIDSearchDomainActionSlackPostMessageAction struct { + Typename *string `json:"__typename"` + ActionDetailsSlackPostMessageAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionSlackPostMessageAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetTypename() *string { + return v.Typename +} + +// GetId returns GetActionByIDSearchDomainActionSlackPostMessageAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetId() string { + return v.ActionDetailsSlackPostMessageAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionSlackPostMessageAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetName() string { + return v.ActionDetailsSlackPostMessageAction.Name +} + +// GetApiToken returns GetActionByIDSearchDomainActionSlackPostMessageAction.ApiToken, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetApiToken() string { + return v.ActionDetailsSlackPostMessageAction.ApiToken +} + +// GetChannels returns GetActionByIDSearchDomainActionSlackPostMessageAction.Channels, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetChannels() []string { + return v.ActionDetailsSlackPostMessageAction.Channels +} + +// GetFields returns GetActionByIDSearchDomainActionSlackPostMessageAction.Fields, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetFields() []ActionDetailsFieldsSlackFieldEntry { + return v.ActionDetailsSlackPostMessageAction.Fields +} + +// GetUseProxy returns GetActionByIDSearchDomainActionSlackPostMessageAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) GetUseProxy() bool { + return v.ActionDetailsSlackPostMessageAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionSlackPostMessageAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionSlackPostMessageAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsSlackPostMessageAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionSlackPostMessageAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + ApiToken string `json:"apiToken"` + + Channels []string `json:"channels"` + + Fields []ActionDetailsFieldsSlackFieldEntry `json:"fields"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionSlackPostMessageAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionSlackPostMessageAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionSlackPostMessageAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsSlackPostMessageAction.Id + retval.Name = v.ActionDetailsSlackPostMessageAction.Name + retval.ApiToken = v.ActionDetailsSlackPostMessageAction.ApiToken + retval.Channels = v.ActionDetailsSlackPostMessageAction.Channels + retval.Fields = v.ActionDetailsSlackPostMessageAction.Fields + retval.UseProxy = v.ActionDetailsSlackPostMessageAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainActionUploadFileAction includes the requested fields of the GraphQL type UploadFileAction. +// The GraphQL type's documentation follows. +// +// An upload file action. +type GetActionByIDSearchDomainActionUploadFileAction struct { + Typename *string `json:"__typename"` + ActionDetailsUploadFileAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionUploadFileAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionUploadFileAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionUploadFileAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionUploadFileAction) GetId() string { + return v.ActionDetailsUploadFileAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionUploadFileAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionUploadFileAction) GetName() string { + return v.ActionDetailsUploadFileAction.Name +} + +func (v *GetActionByIDSearchDomainActionUploadFileAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionUploadFileAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionUploadFileAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsUploadFileAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionUploadFileAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` +} + +func (v *GetActionByIDSearchDomainActionUploadFileAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionUploadFileAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionUploadFileAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionUploadFileAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsUploadFileAction.Id + retval.Name = v.ActionDetailsUploadFileAction.Name + return &retval, nil +} + +// GetActionByIDSearchDomainActionVictorOpsAction includes the requested fields of the GraphQL type VictorOpsAction. +// The GraphQL type's documentation follows. +// +// A VictorOps action. +type GetActionByIDSearchDomainActionVictorOpsAction struct { + Typename *string `json:"__typename"` + ActionDetailsVictorOpsAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionVictorOpsAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionVictorOpsAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionVictorOpsAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionVictorOpsAction) GetId() string { + return v.ActionDetailsVictorOpsAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionVictorOpsAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionVictorOpsAction) GetName() string { + return v.ActionDetailsVictorOpsAction.Name +} + +// GetMessageType returns GetActionByIDSearchDomainActionVictorOpsAction.MessageType, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionVictorOpsAction) GetMessageType() string { + return v.ActionDetailsVictorOpsAction.MessageType +} + +// GetNotifyUrl returns GetActionByIDSearchDomainActionVictorOpsAction.NotifyUrl, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionVictorOpsAction) GetNotifyUrl() string { + return v.ActionDetailsVictorOpsAction.NotifyUrl +} + +// GetUseProxy returns GetActionByIDSearchDomainActionVictorOpsAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionVictorOpsAction) GetUseProxy() bool { + return v.ActionDetailsVictorOpsAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionVictorOpsAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionVictorOpsAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionVictorOpsAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsVictorOpsAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionVictorOpsAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + MessageType string `json:"messageType"` + + NotifyUrl string `json:"notifyUrl"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionVictorOpsAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionVictorOpsAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionVictorOpsAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionVictorOpsAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsVictorOpsAction.Id + retval.Name = v.ActionDetailsVictorOpsAction.Name + retval.MessageType = v.ActionDetailsVictorOpsAction.MessageType + retval.NotifyUrl = v.ActionDetailsVictorOpsAction.NotifyUrl + retval.UseProxy = v.ActionDetailsVictorOpsAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainActionWebhookAction includes the requested fields of the GraphQL type WebhookAction. +// The GraphQL type's documentation follows. +// +// A webhook action +type GetActionByIDSearchDomainActionWebhookAction struct { + Typename *string `json:"__typename"` + ActionDetailsWebhookAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainActionWebhookAction.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetTypename() *string { return v.Typename } + +// GetId returns GetActionByIDSearchDomainActionWebhookAction.Id, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetId() string { + return v.ActionDetailsWebhookAction.Id +} + +// GetName returns GetActionByIDSearchDomainActionWebhookAction.Name, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetName() string { + return v.ActionDetailsWebhookAction.Name +} + +// GetMethod returns GetActionByIDSearchDomainActionWebhookAction.Method, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetMethod() string { + return v.ActionDetailsWebhookAction.Method +} + +// GetUrl returns GetActionByIDSearchDomainActionWebhookAction.Url, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetUrl() string { + return v.ActionDetailsWebhookAction.Url +} + +// GetHeaders returns GetActionByIDSearchDomainActionWebhookAction.Headers, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetHeaders() []ActionDetailsHeadersHttpHeaderEntry { + return v.ActionDetailsWebhookAction.Headers +} + +// GetWebhookBodyTemplate returns GetActionByIDSearchDomainActionWebhookAction.WebhookBodyTemplate, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetWebhookBodyTemplate() string { + return v.ActionDetailsWebhookAction.WebhookBodyTemplate +} + +// GetIgnoreSSL returns GetActionByIDSearchDomainActionWebhookAction.IgnoreSSL, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetIgnoreSSL() bool { + return v.ActionDetailsWebhookAction.IgnoreSSL +} + +// GetUseProxy returns GetActionByIDSearchDomainActionWebhookAction.UseProxy, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainActionWebhookAction) GetUseProxy() bool { + return v.ActionDetailsWebhookAction.UseProxy +} + +func (v *GetActionByIDSearchDomainActionWebhookAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainActionWebhookAction + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainActionWebhookAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsWebhookAction) + if err != nil { + return err + } + return nil +} + +type __premarshalGetActionByIDSearchDomainActionWebhookAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Method string `json:"method"` + + Url string `json:"url"` + + Headers []ActionDetailsHeadersHttpHeaderEntry `json:"headers"` + + WebhookBodyTemplate string `json:"WebhookBodyTemplate"` + + IgnoreSSL bool `json:"ignoreSSL"` + + UseProxy bool `json:"useProxy"` +} + +func (v *GetActionByIDSearchDomainActionWebhookAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainActionWebhookAction) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainActionWebhookAction, error) { + var retval __premarshalGetActionByIDSearchDomainActionWebhookAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsWebhookAction.Id + retval.Name = v.ActionDetailsWebhookAction.Name + retval.Method = v.ActionDetailsWebhookAction.Method + retval.Url = v.ActionDetailsWebhookAction.Url + retval.Headers = v.ActionDetailsWebhookAction.Headers + retval.WebhookBodyTemplate = v.ActionDetailsWebhookAction.WebhookBodyTemplate + retval.IgnoreSSL = v.ActionDetailsWebhookAction.IgnoreSSL + retval.UseProxy = v.ActionDetailsWebhookAction.UseProxy + return &retval, nil +} + +// GetActionByIDSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetActionByIDSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Action GetActionByIDSearchDomainAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetAction returns GetActionByIDSearchDomainRepository.Action, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainRepository) GetAction() GetActionByIDSearchDomainAction { + return v.Action +} + +func (v *GetActionByIDSearchDomainRepository) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainRepository + Action json.RawMessage `json:"action"` + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainRepository = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Action + src := firstPass.Action + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetActionByIDSearchDomainAction( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetActionByIDSearchDomainRepository.Action: %w", err) + } + } + } + return nil +} + +type __premarshalGetActionByIDSearchDomainRepository struct { + Typename *string `json:"__typename"` + + Action json.RawMessage `json:"action"` +} + +func (v *GetActionByIDSearchDomainRepository) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainRepository) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainRepository, error) { + var retval __premarshalGetActionByIDSearchDomainRepository + + retval.Typename = v.Typename + { + + dst := &retval.Action + src := v.Action + var err error + *dst, err = __marshalGetActionByIDSearchDomainAction( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetActionByIDSearchDomainRepository.Action: %w", err) + } + } + return &retval, nil +} + +// GetActionByIDSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type GetActionByIDSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Action GetActionByIDSearchDomainAction `json:"-"` +} + +// GetTypename returns GetActionByIDSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainView) GetTypename() *string { return v.Typename } + +// GetAction returns GetActionByIDSearchDomainView.Action, and is useful for accessing the field via an interface. +func (v *GetActionByIDSearchDomainView) GetAction() GetActionByIDSearchDomainAction { return v.Action } + +func (v *GetActionByIDSearchDomainView) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetActionByIDSearchDomainView + Action json.RawMessage `json:"action"` + graphql.NoUnmarshalJSON + } + firstPass.GetActionByIDSearchDomainView = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Action + src := firstPass.Action + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetActionByIDSearchDomainAction( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetActionByIDSearchDomainView.Action: %w", err) + } + } + } + return nil +} + +type __premarshalGetActionByIDSearchDomainView struct { + Typename *string `json:"__typename"` + + Action json.RawMessage `json:"action"` +} + +func (v *GetActionByIDSearchDomainView) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetActionByIDSearchDomainView) __premarshalJSON() (*__premarshalGetActionByIDSearchDomainView, error) { + var retval __premarshalGetActionByIDSearchDomainView + + retval.Typename = v.Typename + { + + dst := &retval.Action + src := v.Action + var err error + *dst, err = __marshalGetActionByIDSearchDomainAction( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetActionByIDSearchDomainView.Action: %w", err) + } + } + return &retval, nil +} + +// GetAggregateAlertByIDResponse is returned by GetAggregateAlertByID on success. +type GetAggregateAlertByIDResponse struct { + SearchDomain GetAggregateAlertByIDSearchDomain `json:"-"` +} + +// GetSearchDomain returns GetAggregateAlertByIDResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDResponse) GetSearchDomain() GetAggregateAlertByIDSearchDomain { + return v.SearchDomain +} + +func (v *GetAggregateAlertByIDResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetAggregateAlertByIDResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.GetAggregateAlertByIDResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetAggregateAlertByIDSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetAggregateAlertByIDResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalGetAggregateAlertByIDResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *GetAggregateAlertByIDResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetAggregateAlertByIDResponse) __premarshalJSON() (*__premarshalGetAggregateAlertByIDResponse, error) { + var retval __premarshalGetAggregateAlertByIDResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalGetAggregateAlertByIDSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetAggregateAlertByIDResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// GetAggregateAlertByIDSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// GetAggregateAlertByIDSearchDomain is implemented by the following types: +// GetAggregateAlertByIDSearchDomainRepository +// GetAggregateAlertByIDSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type GetAggregateAlertByIDSearchDomain interface { + implementsGraphQLInterfaceGetAggregateAlertByIDSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetAggregateAlert returns the interface-field "aggregateAlert" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetAggregateAlert() GetAggregateAlertByIDSearchDomainAggregateAlert +} + +func (v *GetAggregateAlertByIDSearchDomainRepository) implementsGraphQLInterfaceGetAggregateAlertByIDSearchDomain() { +} +func (v *GetAggregateAlertByIDSearchDomainView) implementsGraphQLInterfaceGetAggregateAlertByIDSearchDomain() { +} + +func __unmarshalGetAggregateAlertByIDSearchDomain(b []byte, v *GetAggregateAlertByIDSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(GetAggregateAlertByIDSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(GetAggregateAlertByIDSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetAggregateAlertByIDSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalGetAggregateAlertByIDSearchDomain(v *GetAggregateAlertByIDSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetAggregateAlertByIDSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *GetAggregateAlertByIDSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *GetAggregateAlertByIDSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *GetAggregateAlertByIDSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetAggregateAlertByIDSearchDomain: "%T"`, v) + } +} + +// GetAggregateAlertByIDSearchDomainAggregateAlert includes the requested fields of the GraphQL type AggregateAlert. +// The GraphQL type's documentation follows. +// +// An aggregate alert. +type GetAggregateAlertByIDSearchDomainAggregateAlert struct { + AggregateAlertDetails `json:"-"` +} + +// GetId returns GetAggregateAlertByIDSearchDomainAggregateAlert.Id, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetId() string { + return v.AggregateAlertDetails.Id +} + +// GetName returns GetAggregateAlertByIDSearchDomainAggregateAlert.Name, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetName() string { + return v.AggregateAlertDetails.Name +} + +// GetDescription returns GetAggregateAlertByIDSearchDomainAggregateAlert.Description, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetDescription() *string { + return v.AggregateAlertDetails.Description +} + +// GetQueryString returns GetAggregateAlertByIDSearchDomainAggregateAlert.QueryString, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetQueryString() string { + return v.AggregateAlertDetails.QueryString +} + +// GetSearchIntervalSeconds returns GetAggregateAlertByIDSearchDomainAggregateAlert.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetSearchIntervalSeconds() int64 { + return v.AggregateAlertDetails.SearchIntervalSeconds +} + +// GetThrottleTimeSeconds returns GetAggregateAlertByIDSearchDomainAggregateAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetThrottleTimeSeconds() int64 { + return v.AggregateAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns GetAggregateAlertByIDSearchDomainAggregateAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetThrottleField() *string { + return v.AggregateAlertDetails.ThrottleField +} + +// GetLabels returns GetAggregateAlertByIDSearchDomainAggregateAlert.Labels, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetLabels() []string { + return v.AggregateAlertDetails.Labels +} + +// GetEnabled returns GetAggregateAlertByIDSearchDomainAggregateAlert.Enabled, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetEnabled() bool { + return v.AggregateAlertDetails.Enabled +} + +// GetTriggerMode returns GetAggregateAlertByIDSearchDomainAggregateAlert.TriggerMode, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetTriggerMode() TriggerMode { + return v.AggregateAlertDetails.TriggerMode +} + +// GetQueryTimestampType returns GetAggregateAlertByIDSearchDomainAggregateAlert.QueryTimestampType, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetQueryTimestampType() QueryTimestampType { + return v.AggregateAlertDetails.QueryTimestampType +} + +// GetActions returns GetAggregateAlertByIDSearchDomainAggregateAlert.Actions, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetActions() []SharedActionNameType { + return v.AggregateAlertDetails.Actions +} + +// GetQueryOwnership returns GetAggregateAlertByIDSearchDomainAggregateAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AggregateAlertDetails.QueryOwnership +} + +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetAggregateAlertByIDSearchDomainAggregateAlert + graphql.NoUnmarshalJSON + } + firstPass.GetAggregateAlertByIDSearchDomainAggregateAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AggregateAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalGetAggregateAlertByIDSearchDomainAggregateAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + SearchIntervalSeconds int64 `json:"searchIntervalSeconds"` + + ThrottleTimeSeconds int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + TriggerMode TriggerMode `json:"triggerMode"` + + QueryTimestampType QueryTimestampType `json:"queryTimestampType"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetAggregateAlertByIDSearchDomainAggregateAlert) __premarshalJSON() (*__premarshalGetAggregateAlertByIDSearchDomainAggregateAlert, error) { + var retval __premarshalGetAggregateAlertByIDSearchDomainAggregateAlert + + retval.Id = v.AggregateAlertDetails.Id + retval.Name = v.AggregateAlertDetails.Name + retval.Description = v.AggregateAlertDetails.Description + retval.QueryString = v.AggregateAlertDetails.QueryString + retval.SearchIntervalSeconds = v.AggregateAlertDetails.SearchIntervalSeconds + retval.ThrottleTimeSeconds = v.AggregateAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.AggregateAlertDetails.ThrottleField + retval.Labels = v.AggregateAlertDetails.Labels + retval.Enabled = v.AggregateAlertDetails.Enabled + retval.TriggerMode = v.AggregateAlertDetails.TriggerMode + retval.QueryTimestampType = v.AggregateAlertDetails.QueryTimestampType + { + + dst := &retval.Actions + src := v.AggregateAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetAggregateAlertByIDSearchDomainAggregateAlert.AggregateAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AggregateAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetAggregateAlertByIDSearchDomainAggregateAlert.AggregateAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// GetAggregateAlertByIDSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetAggregateAlertByIDSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + AggregateAlert GetAggregateAlertByIDSearchDomainAggregateAlert `json:"aggregateAlert"` +} + +// GetTypename returns GetAggregateAlertByIDSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetAggregateAlert returns GetAggregateAlertByIDSearchDomainRepository.AggregateAlert, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainRepository) GetAggregateAlert() GetAggregateAlertByIDSearchDomainAggregateAlert { + return v.AggregateAlert +} + +// GetAggregateAlertByIDSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type GetAggregateAlertByIDSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + AggregateAlert GetAggregateAlertByIDSearchDomainAggregateAlert `json:"aggregateAlert"` +} + +// GetTypename returns GetAggregateAlertByIDSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainView) GetTypename() *string { return v.Typename } + +// GetAggregateAlert returns GetAggregateAlertByIDSearchDomainView.AggregateAlert, and is useful for accessing the field via an interface. +func (v *GetAggregateAlertByIDSearchDomainView) GetAggregateAlert() GetAggregateAlertByIDSearchDomainAggregateAlert { + return v.AggregateAlert +} + +// GetClusterCluster includes the requested fields of the GraphQL type Cluster. +// The GraphQL type's documentation follows. +// +// Information about the LogScale cluster. +type GetClusterCluster struct { + Nodes []GetClusterClusterNodesClusterNode `json:"nodes"` +} + +// GetNodes returns GetClusterCluster.Nodes, and is useful for accessing the field via an interface. +func (v *GetClusterCluster) GetNodes() []GetClusterClusterNodesClusterNode { return v.Nodes } + +// GetClusterClusterNodesClusterNode includes the requested fields of the GraphQL type ClusterNode. +// The GraphQL type's documentation follows. +// +// A node in the a LogScale Cluster. +type GetClusterClusterNodesClusterNode struct { + Id int `json:"id"` + Zone *string `json:"zone"` +} + +// GetId returns GetClusterClusterNodesClusterNode.Id, and is useful for accessing the field via an interface. +func (v *GetClusterClusterNodesClusterNode) GetId() int { return v.Id } + +// GetZone returns GetClusterClusterNodesClusterNode.Zone, and is useful for accessing the field via an interface. +func (v *GetClusterClusterNodesClusterNode) GetZone() *string { return v.Zone } + +// GetClusterResponse is returned by GetCluster on success. +type GetClusterResponse struct { + // This is used to retrieve information about a cluster. + Cluster GetClusterCluster `json:"cluster"` +} + +// GetCluster returns GetClusterResponse.Cluster, and is useful for accessing the field via an interface. +func (v *GetClusterResponse) GetCluster() GetClusterCluster { return v.Cluster } + +// GetFilterAlertByIDResponse is returned by GetFilterAlertByID on success. +type GetFilterAlertByIDResponse struct { + SearchDomain GetFilterAlertByIDSearchDomain `json:"-"` +} + +// GetSearchDomain returns GetFilterAlertByIDResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDResponse) GetSearchDomain() GetFilterAlertByIDSearchDomain { + return v.SearchDomain +} + +func (v *GetFilterAlertByIDResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetFilterAlertByIDResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.GetFilterAlertByIDResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetFilterAlertByIDSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetFilterAlertByIDResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalGetFilterAlertByIDResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *GetFilterAlertByIDResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetFilterAlertByIDResponse) __premarshalJSON() (*__premarshalGetFilterAlertByIDResponse, error) { + var retval __premarshalGetFilterAlertByIDResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalGetFilterAlertByIDSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetFilterAlertByIDResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// GetFilterAlertByIDSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// GetFilterAlertByIDSearchDomain is implemented by the following types: +// GetFilterAlertByIDSearchDomainRepository +// GetFilterAlertByIDSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type GetFilterAlertByIDSearchDomain interface { + implementsGraphQLInterfaceGetFilterAlertByIDSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetFilterAlert returns the interface-field "filterAlert" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetFilterAlert() GetFilterAlertByIDSearchDomainFilterAlert +} + +func (v *GetFilterAlertByIDSearchDomainRepository) implementsGraphQLInterfaceGetFilterAlertByIDSearchDomain() { +} +func (v *GetFilterAlertByIDSearchDomainView) implementsGraphQLInterfaceGetFilterAlertByIDSearchDomain() { +} + +func __unmarshalGetFilterAlertByIDSearchDomain(b []byte, v *GetFilterAlertByIDSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(GetFilterAlertByIDSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(GetFilterAlertByIDSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetFilterAlertByIDSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalGetFilterAlertByIDSearchDomain(v *GetFilterAlertByIDSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetFilterAlertByIDSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *GetFilterAlertByIDSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *GetFilterAlertByIDSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *GetFilterAlertByIDSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetFilterAlertByIDSearchDomain: "%T"`, v) + } +} + +// GetFilterAlertByIDSearchDomainFilterAlert includes the requested fields of the GraphQL type FilterAlert. +// The GraphQL type's documentation follows. +// +// A filter alert. +type GetFilterAlertByIDSearchDomainFilterAlert struct { + FilterAlertDetails `json:"-"` +} + +// GetId returns GetFilterAlertByIDSearchDomainFilterAlert.Id, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetId() string { return v.FilterAlertDetails.Id } + +// GetName returns GetFilterAlertByIDSearchDomainFilterAlert.Name, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetName() string { + return v.FilterAlertDetails.Name +} + +// GetDescription returns GetFilterAlertByIDSearchDomainFilterAlert.Description, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetDescription() *string { + return v.FilterAlertDetails.Description +} + +// GetQueryString returns GetFilterAlertByIDSearchDomainFilterAlert.QueryString, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetQueryString() string { + return v.FilterAlertDetails.QueryString +} + +// GetThrottleTimeSeconds returns GetFilterAlertByIDSearchDomainFilterAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetThrottleTimeSeconds() *int64 { + return v.FilterAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns GetFilterAlertByIDSearchDomainFilterAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetThrottleField() *string { + return v.FilterAlertDetails.ThrottleField +} + +// GetLabels returns GetFilterAlertByIDSearchDomainFilterAlert.Labels, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetLabels() []string { + return v.FilterAlertDetails.Labels +} + +// GetEnabled returns GetFilterAlertByIDSearchDomainFilterAlert.Enabled, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetEnabled() bool { + return v.FilterAlertDetails.Enabled +} + +// GetActions returns GetFilterAlertByIDSearchDomainFilterAlert.Actions, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetActions() []SharedActionNameType { + return v.FilterAlertDetails.Actions +} + +// GetQueryOwnership returns GetFilterAlertByIDSearchDomainFilterAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainFilterAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.FilterAlertDetails.QueryOwnership +} + +func (v *GetFilterAlertByIDSearchDomainFilterAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetFilterAlertByIDSearchDomainFilterAlert + graphql.NoUnmarshalJSON + } + firstPass.GetFilterAlertByIDSearchDomainFilterAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FilterAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalGetFilterAlertByIDSearchDomainFilterAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + ThrottleTimeSeconds *int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *GetFilterAlertByIDSearchDomainFilterAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetFilterAlertByIDSearchDomainFilterAlert) __premarshalJSON() (*__premarshalGetFilterAlertByIDSearchDomainFilterAlert, error) { + var retval __premarshalGetFilterAlertByIDSearchDomainFilterAlert + + retval.Id = v.FilterAlertDetails.Id + retval.Name = v.FilterAlertDetails.Name + retval.Description = v.FilterAlertDetails.Description + retval.QueryString = v.FilterAlertDetails.QueryString + retval.ThrottleTimeSeconds = v.FilterAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.FilterAlertDetails.ThrottleField + retval.Labels = v.FilterAlertDetails.Labels + retval.Enabled = v.FilterAlertDetails.Enabled + { + + dst := &retval.Actions + src := v.FilterAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetFilterAlertByIDSearchDomainFilterAlert.FilterAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.FilterAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetFilterAlertByIDSearchDomainFilterAlert.FilterAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// GetFilterAlertByIDSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetFilterAlertByIDSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + FilterAlert GetFilterAlertByIDSearchDomainFilterAlert `json:"filterAlert"` +} + +// GetTypename returns GetFilterAlertByIDSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetFilterAlert returns GetFilterAlertByIDSearchDomainRepository.FilterAlert, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainRepository) GetFilterAlert() GetFilterAlertByIDSearchDomainFilterAlert { + return v.FilterAlert +} + +// GetFilterAlertByIDSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type GetFilterAlertByIDSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + FilterAlert GetFilterAlertByIDSearchDomainFilterAlert `json:"filterAlert"` +} + +// GetTypename returns GetFilterAlertByIDSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainView) GetTypename() *string { return v.Typename } + +// GetFilterAlert returns GetFilterAlertByIDSearchDomainView.FilterAlert, and is useful for accessing the field via an interface. +func (v *GetFilterAlertByIDSearchDomainView) GetFilterAlert() GetFilterAlertByIDSearchDomainFilterAlert { + return v.FilterAlert +} + +// GetLicenseInstalledLicense includes the requested fields of the GraphQL interface License. +// +// GetLicenseInstalledLicense is implemented by the following types: +// GetLicenseInstalledLicenseOnPremLicense +// GetLicenseInstalledLicenseTrialLicense +// The GraphQL type's documentation follows. +// +// Represents information about the LogScale instance. +type GetLicenseInstalledLicense interface { + implementsGraphQLInterfaceGetLicenseInstalledLicense() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string +} + +func (v *GetLicenseInstalledLicenseOnPremLicense) implementsGraphQLInterfaceGetLicenseInstalledLicense() { +} +func (v *GetLicenseInstalledLicenseTrialLicense) implementsGraphQLInterfaceGetLicenseInstalledLicense() { +} + +func __unmarshalGetLicenseInstalledLicense(b []byte, v *GetLicenseInstalledLicense) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "OnPremLicense": + *v = new(GetLicenseInstalledLicenseOnPremLicense) + return json.Unmarshal(b, *v) + case "TrialLicense": + *v = new(GetLicenseInstalledLicenseTrialLicense) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing License.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetLicenseInstalledLicense: "%v"`, tn.TypeName) + } +} + +func __marshalGetLicenseInstalledLicense(v *GetLicenseInstalledLicense) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetLicenseInstalledLicenseOnPremLicense: + typename = "OnPremLicense" + + result := struct { + TypeName string `json:"__typename"` + *GetLicenseInstalledLicenseOnPremLicense + }{typename, v} + return json.Marshal(result) + case *GetLicenseInstalledLicenseTrialLicense: + typename = "TrialLicense" + + result := struct { + TypeName string `json:"__typename"` + *GetLicenseInstalledLicenseTrialLicense + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetLicenseInstalledLicense: "%T"`, v) + } +} + +// GetLicenseInstalledLicenseOnPremLicense includes the requested fields of the GraphQL type OnPremLicense. +// The GraphQL type's documentation follows. +// +// Represents information about a LogScale License. +type GetLicenseInstalledLicenseOnPremLicense struct { + Typename *string `json:"__typename"` + // license id. + Uid string `json:"uid"` + // The time at which the license expires. + ExpiresAt time.Time `json:"expiresAt"` +} + +// GetTypename returns GetLicenseInstalledLicenseOnPremLicense.Typename, and is useful for accessing the field via an interface. +func (v *GetLicenseInstalledLicenseOnPremLicense) GetTypename() *string { return v.Typename } + +// GetUid returns GetLicenseInstalledLicenseOnPremLicense.Uid, and is useful for accessing the field via an interface. +func (v *GetLicenseInstalledLicenseOnPremLicense) GetUid() string { return v.Uid } + +// GetExpiresAt returns GetLicenseInstalledLicenseOnPremLicense.ExpiresAt, and is useful for accessing the field via an interface. +func (v *GetLicenseInstalledLicenseOnPremLicense) GetExpiresAt() time.Time { return v.ExpiresAt } + +// GetLicenseInstalledLicenseTrialLicense includes the requested fields of the GraphQL type TrialLicense. +// The GraphQL type's documentation follows. +// +// Represents information about an on-going trial of LogScale. +type GetLicenseInstalledLicenseTrialLicense struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns GetLicenseInstalledLicenseTrialLicense.Typename, and is useful for accessing the field via an interface. +func (v *GetLicenseInstalledLicenseTrialLicense) GetTypename() *string { return v.Typename } + +// GetLicenseResponse is returned by GetLicense on success. +type GetLicenseResponse struct { + // This returns information about the license for the LogScale instance, if any license installed. + InstalledLicense *GetLicenseInstalledLicense `json:"-"` +} + +// GetInstalledLicense returns GetLicenseResponse.InstalledLicense, and is useful for accessing the field via an interface. +func (v *GetLicenseResponse) GetInstalledLicense() *GetLicenseInstalledLicense { + return v.InstalledLicense +} + +func (v *GetLicenseResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetLicenseResponse + InstalledLicense json.RawMessage `json:"installedLicense"` + graphql.NoUnmarshalJSON + } + firstPass.GetLicenseResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.InstalledLicense + src := firstPass.InstalledLicense + if len(src) != 0 && string(src) != "null" { + *dst = new(GetLicenseInstalledLicense) + err = __unmarshalGetLicenseInstalledLicense( + src, *dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetLicenseResponse.InstalledLicense: %w", err) + } + } + } + return nil +} + +type __premarshalGetLicenseResponse struct { + InstalledLicense json.RawMessage `json:"installedLicense"` +} + +func (v *GetLicenseResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetLicenseResponse) __premarshalJSON() (*__premarshalGetLicenseResponse, error) { + var retval __premarshalGetLicenseResponse + + { + + dst := &retval.InstalledLicense + src := v.InstalledLicense + if src != nil { + var err error + *dst, err = __marshalGetLicenseInstalledLicense( + src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetLicenseResponse.InstalledLicense: %w", err) + } + } + } + return &retval, nil +} + +// GetParserByIDRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetParserByIDRepository struct { + // A parser on the repository. + Parser *GetParserByIDRepositoryParser `json:"parser"` +} + +// GetParser returns GetParserByIDRepository.Parser, and is useful for accessing the field via an interface. +func (v *GetParserByIDRepository) GetParser() *GetParserByIDRepositoryParser { return v.Parser } + +// GetParserByIDRepositoryParser includes the requested fields of the GraphQL type Parser. +// The GraphQL type's documentation follows. +// +// A configured parser for incoming data. +type GetParserByIDRepositoryParser struct { + ParserDetails `json:"-"` +} + +// GetId returns GetParserByIDRepositoryParser.Id, and is useful for accessing the field via an interface. +func (v *GetParserByIDRepositoryParser) GetId() string { return v.ParserDetails.Id } + +// GetName returns GetParserByIDRepositoryParser.Name, and is useful for accessing the field via an interface. +func (v *GetParserByIDRepositoryParser) GetName() string { return v.ParserDetails.Name } + +// GetScript returns GetParserByIDRepositoryParser.Script, and is useful for accessing the field via an interface. +func (v *GetParserByIDRepositoryParser) GetScript() string { return v.ParserDetails.Script } + +// GetFieldsToTag returns GetParserByIDRepositoryParser.FieldsToTag, and is useful for accessing the field via an interface. +func (v *GetParserByIDRepositoryParser) GetFieldsToTag() []string { return v.ParserDetails.FieldsToTag } + +// GetTestCases returns GetParserByIDRepositoryParser.TestCases, and is useful for accessing the field via an interface. +func (v *GetParserByIDRepositoryParser) GetTestCases() []ParserDetailsTestCasesParserTestCase { + return v.ParserDetails.TestCases +} + +func (v *GetParserByIDRepositoryParser) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetParserByIDRepositoryParser + graphql.NoUnmarshalJSON + } + firstPass.GetParserByIDRepositoryParser = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ParserDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalGetParserByIDRepositoryParser struct { + Id string `json:"id"` + + Name string `json:"name"` + + Script string `json:"script"` + + FieldsToTag []string `json:"fieldsToTag"` + + TestCases []ParserDetailsTestCasesParserTestCase `json:"testCases"` +} + +func (v *GetParserByIDRepositoryParser) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetParserByIDRepositoryParser) __premarshalJSON() (*__premarshalGetParserByIDRepositoryParser, error) { + var retval __premarshalGetParserByIDRepositoryParser + + retval.Id = v.ParserDetails.Id + retval.Name = v.ParserDetails.Name + retval.Script = v.ParserDetails.Script + retval.FieldsToTag = v.ParserDetails.FieldsToTag + retval.TestCases = v.ParserDetails.TestCases + return &retval, nil +} + +// GetParserByIDResponse is returned by GetParserByID on success. +type GetParserByIDResponse struct { + // Lookup a given repository by name. + Repository GetParserByIDRepository `json:"repository"` +} + +// GetRepository returns GetParserByIDResponse.Repository, and is useful for accessing the field via an interface. +func (v *GetParserByIDResponse) GetRepository() GetParserByIDRepository { return v.Repository } + +// GetRepositoryRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetRepositoryRepository struct { + RepositoryDetails `json:"-"` +} + +// GetId returns GetRepositoryRepository.Id, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetId() string { return v.RepositoryDetails.Id } + +// GetName returns GetRepositoryRepository.Name, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetName() string { return v.RepositoryDetails.Name } + +// GetDescription returns GetRepositoryRepository.Description, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetDescription() *string { return v.RepositoryDetails.Description } + +// GetTimeBasedRetention returns GetRepositoryRepository.TimeBasedRetention, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetTimeBasedRetention() *float64 { + return v.RepositoryDetails.TimeBasedRetention +} + +// GetIngestSizeBasedRetention returns GetRepositoryRepository.IngestSizeBasedRetention, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetIngestSizeBasedRetention() *float64 { + return v.RepositoryDetails.IngestSizeBasedRetention +} + +// GetStorageSizeBasedRetention returns GetRepositoryRepository.StorageSizeBasedRetention, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetStorageSizeBasedRetention() *float64 { + return v.RepositoryDetails.StorageSizeBasedRetention +} + +// GetCompressedByteSize returns GetRepositoryRepository.CompressedByteSize, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetCompressedByteSize() int64 { + return v.RepositoryDetails.CompressedByteSize +} + +// GetAutomaticSearch returns GetRepositoryRepository.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetAutomaticSearch() bool { + return v.RepositoryDetails.AutomaticSearch +} + +// GetS3ArchivingConfiguration returns GetRepositoryRepository.S3ArchivingConfiguration, and is useful for accessing the field via an interface. +func (v *GetRepositoryRepository) GetS3ArchivingConfiguration() *RepositoryDetailsS3ArchivingConfigurationS3Configuration { + return v.RepositoryDetails.S3ArchivingConfiguration +} + +func (v *GetRepositoryRepository) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetRepositoryRepository + graphql.NoUnmarshalJSON + } + firstPass.GetRepositoryRepository = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.RepositoryDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalGetRepositoryRepository struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + TimeBasedRetention *float64 `json:"timeBasedRetention"` + + IngestSizeBasedRetention *float64 `json:"ingestSizeBasedRetention"` + + StorageSizeBasedRetention *float64 `json:"storageSizeBasedRetention"` + + CompressedByteSize int64 `json:"compressedByteSize"` + + AutomaticSearch bool `json:"automaticSearch"` + + S3ArchivingConfiguration *RepositoryDetailsS3ArchivingConfigurationS3Configuration `json:"s3ArchivingConfiguration"` +} + +func (v *GetRepositoryRepository) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetRepositoryRepository) __premarshalJSON() (*__premarshalGetRepositoryRepository, error) { + var retval __premarshalGetRepositoryRepository + + retval.Id = v.RepositoryDetails.Id + retval.Name = v.RepositoryDetails.Name + retval.Description = v.RepositoryDetails.Description + retval.TimeBasedRetention = v.RepositoryDetails.TimeBasedRetention + retval.IngestSizeBasedRetention = v.RepositoryDetails.IngestSizeBasedRetention + retval.StorageSizeBasedRetention = v.RepositoryDetails.StorageSizeBasedRetention + retval.CompressedByteSize = v.RepositoryDetails.CompressedByteSize + retval.AutomaticSearch = v.RepositoryDetails.AutomaticSearch + retval.S3ArchivingConfiguration = v.RepositoryDetails.S3ArchivingConfiguration + return &retval, nil +} + +// GetRepositoryResponse is returned by GetRepository on success. +type GetRepositoryResponse struct { + // Lookup a given repository by name. + Repository GetRepositoryRepository `json:"repository"` +} + +// GetRepository returns GetRepositoryResponse.Repository, and is useful for accessing the field via an interface. +func (v *GetRepositoryResponse) GetRepository() GetRepositoryRepository { return v.Repository } + +// GetScheduledSearchByIDResponse is returned by GetScheduledSearchByID on success. +type GetScheduledSearchByIDResponse struct { + SearchDomain GetScheduledSearchByIDSearchDomain `json:"-"` +} + +// GetSearchDomain returns GetScheduledSearchByIDResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDResponse) GetSearchDomain() GetScheduledSearchByIDSearchDomain { + return v.SearchDomain +} + +func (v *GetScheduledSearchByIDResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetScheduledSearchByIDResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.GetScheduledSearchByIDResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetScheduledSearchByIDSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetScheduledSearchByIDResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalGetScheduledSearchByIDResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *GetScheduledSearchByIDResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetScheduledSearchByIDResponse) __premarshalJSON() (*__premarshalGetScheduledSearchByIDResponse, error) { + var retval __premarshalGetScheduledSearchByIDResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalGetScheduledSearchByIDSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetScheduledSearchByIDResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// GetScheduledSearchByIDSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// GetScheduledSearchByIDSearchDomain is implemented by the following types: +// GetScheduledSearchByIDSearchDomainRepository +// GetScheduledSearchByIDSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type GetScheduledSearchByIDSearchDomain interface { + implementsGraphQLInterfaceGetScheduledSearchByIDSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetScheduledSearch returns the interface-field "scheduledSearch" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetScheduledSearch() GetScheduledSearchByIDSearchDomainScheduledSearch +} + +func (v *GetScheduledSearchByIDSearchDomainRepository) implementsGraphQLInterfaceGetScheduledSearchByIDSearchDomain() { +} +func (v *GetScheduledSearchByIDSearchDomainView) implementsGraphQLInterfaceGetScheduledSearchByIDSearchDomain() { +} + +func __unmarshalGetScheduledSearchByIDSearchDomain(b []byte, v *GetScheduledSearchByIDSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(GetScheduledSearchByIDSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(GetScheduledSearchByIDSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetScheduledSearchByIDSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalGetScheduledSearchByIDSearchDomain(v *GetScheduledSearchByIDSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetScheduledSearchByIDSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *GetScheduledSearchByIDSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *GetScheduledSearchByIDSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *GetScheduledSearchByIDSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetScheduledSearchByIDSearchDomain: "%T"`, v) + } +} + +// GetScheduledSearchByIDSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetScheduledSearchByIDSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + ScheduledSearch GetScheduledSearchByIDSearchDomainScheduledSearch `json:"scheduledSearch"` +} + +// GetTypename returns GetScheduledSearchByIDSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetScheduledSearch returns GetScheduledSearchByIDSearchDomainRepository.ScheduledSearch, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainRepository) GetScheduledSearch() GetScheduledSearchByIDSearchDomainScheduledSearch { + return v.ScheduledSearch +} + +// GetScheduledSearchByIDSearchDomainScheduledSearch includes the requested fields of the GraphQL type ScheduledSearch. +// The GraphQL type's documentation follows. +// +// Information about a scheduled search +type GetScheduledSearchByIDSearchDomainScheduledSearch struct { + ScheduledSearchDetails `json:"-"` +} + +// GetId returns GetScheduledSearchByIDSearchDomainScheduledSearch.Id, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetId() string { + return v.ScheduledSearchDetails.Id +} + +// GetName returns GetScheduledSearchByIDSearchDomainScheduledSearch.Name, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetName() string { + return v.ScheduledSearchDetails.Name +} + +// GetDescription returns GetScheduledSearchByIDSearchDomainScheduledSearch.Description, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetDescription() *string { + return v.ScheduledSearchDetails.Description +} + +// GetQueryString returns GetScheduledSearchByIDSearchDomainScheduledSearch.QueryString, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetQueryString() string { + return v.ScheduledSearchDetails.QueryString +} + +// GetStart returns GetScheduledSearchByIDSearchDomainScheduledSearch.Start, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetStart() string { + return v.ScheduledSearchDetails.Start +} + +// GetEnd returns GetScheduledSearchByIDSearchDomainScheduledSearch.End, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetEnd() string { + return v.ScheduledSearchDetails.End +} + +// GetTimeZone returns GetScheduledSearchByIDSearchDomainScheduledSearch.TimeZone, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetTimeZone() string { + return v.ScheduledSearchDetails.TimeZone +} + +// GetSchedule returns GetScheduledSearchByIDSearchDomainScheduledSearch.Schedule, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetSchedule() string { + return v.ScheduledSearchDetails.Schedule +} + +// GetBackfillLimit returns GetScheduledSearchByIDSearchDomainScheduledSearch.BackfillLimit, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetBackfillLimit() int { + return v.ScheduledSearchDetails.BackfillLimit +} + +// GetEnabled returns GetScheduledSearchByIDSearchDomainScheduledSearch.Enabled, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetEnabled() bool { + return v.ScheduledSearchDetails.Enabled +} + +// GetLabels returns GetScheduledSearchByIDSearchDomainScheduledSearch.Labels, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetLabels() []string { + return v.ScheduledSearchDetails.Labels +} + +// GetActionsV2 returns GetScheduledSearchByIDSearchDomainScheduledSearch.ActionsV2, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetActionsV2() []SharedActionNameType { + return v.ScheduledSearchDetails.ActionsV2 +} + +// GetQueryOwnership returns GetScheduledSearchByIDSearchDomainScheduledSearch.QueryOwnership, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) GetQueryOwnership() SharedQueryOwnershipType { + return v.ScheduledSearchDetails.QueryOwnership +} + +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetScheduledSearchByIDSearchDomainScheduledSearch + graphql.NoUnmarshalJSON + } + firstPass.GetScheduledSearchByIDSearchDomainScheduledSearch = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ScheduledSearchDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalGetScheduledSearchByIDSearchDomainScheduledSearch struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + Start string `json:"start"` + + End string `json:"end"` + + TimeZone string `json:"timeZone"` + + Schedule string `json:"schedule"` + + BackfillLimit int `json:"backfillLimit"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetScheduledSearchByIDSearchDomainScheduledSearch) __premarshalJSON() (*__premarshalGetScheduledSearchByIDSearchDomainScheduledSearch, error) { + var retval __premarshalGetScheduledSearchByIDSearchDomainScheduledSearch + + retval.Id = v.ScheduledSearchDetails.Id + retval.Name = v.ScheduledSearchDetails.Name + retval.Description = v.ScheduledSearchDetails.Description + retval.QueryString = v.ScheduledSearchDetails.QueryString + retval.Start = v.ScheduledSearchDetails.Start + retval.End = v.ScheduledSearchDetails.End + retval.TimeZone = v.ScheduledSearchDetails.TimeZone + retval.Schedule = v.ScheduledSearchDetails.Schedule + retval.BackfillLimit = v.ScheduledSearchDetails.BackfillLimit + retval.Enabled = v.ScheduledSearchDetails.Enabled + retval.Labels = v.ScheduledSearchDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.ScheduledSearchDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetScheduledSearchByIDSearchDomainScheduledSearch.ScheduledSearchDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.ScheduledSearchDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetScheduledSearchByIDSearchDomainScheduledSearch.ScheduledSearchDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// GetScheduledSearchByIDSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type GetScheduledSearchByIDSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + ScheduledSearch GetScheduledSearchByIDSearchDomainScheduledSearch `json:"scheduledSearch"` +} + +// GetTypename returns GetScheduledSearchByIDSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainView) GetTypename() *string { return v.Typename } + +// GetScheduledSearch returns GetScheduledSearchByIDSearchDomainView.ScheduledSearch, and is useful for accessing the field via an interface. +func (v *GetScheduledSearchByIDSearchDomainView) GetScheduledSearch() GetScheduledSearchByIDSearchDomainScheduledSearch { + return v.ScheduledSearch +} + +// GetSearchDomainResponse is returned by GetSearchDomain on success. +type GetSearchDomainResponse struct { + SearchDomain GetSearchDomainSearchDomain `json:"-"` +} + +// GetSearchDomain returns GetSearchDomainResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *GetSearchDomainResponse) GetSearchDomain() GetSearchDomainSearchDomain { + return v.SearchDomain +} + +func (v *GetSearchDomainResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetSearchDomainResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.GetSearchDomainResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalGetSearchDomainSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal GetSearchDomainResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalGetSearchDomainResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *GetSearchDomainResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetSearchDomainResponse) __premarshalJSON() (*__premarshalGetSearchDomainResponse, error) { + var retval __premarshalGetSearchDomainResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalGetSearchDomainSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal GetSearchDomainResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// GetSearchDomainSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// GetSearchDomainSearchDomain is implemented by the following types: +// GetSearchDomainSearchDomainRepository +// GetSearchDomainSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type GetSearchDomainSearchDomain interface { + implementsGraphQLInterfaceGetSearchDomainSearchDomain() + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetId() string + // GetName returns the interface-field "name" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetName() string + // GetDescription returns the interface-field "description" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetDescription() *string + // GetAutomaticSearch returns the interface-field "automaticSearch" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetAutomaticSearch() bool + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string +} + +func (v *GetSearchDomainSearchDomainRepository) implementsGraphQLInterfaceGetSearchDomainSearchDomain() { +} +func (v *GetSearchDomainSearchDomainView) implementsGraphQLInterfaceGetSearchDomainSearchDomain() {} + +func __unmarshalGetSearchDomainSearchDomain(b []byte, v *GetSearchDomainSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(GetSearchDomainSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(GetSearchDomainSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for GetSearchDomainSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalGetSearchDomainSearchDomain(v *GetSearchDomainSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *GetSearchDomainSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *GetSearchDomainSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *GetSearchDomainSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *GetSearchDomainSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for GetSearchDomainSearchDomain: "%T"`, v) + } +} + +// GetSearchDomainSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetSearchDomainSearchDomainRepository struct { + // Common interface for Repositories and Views. + Id string `json:"id"` + // Common interface for Repositories and Views. + Name string `json:"name"` + // Common interface for Repositories and Views. + Description *string `json:"description"` + // Common interface for Repositories and Views. + AutomaticSearch bool `json:"automaticSearch"` + Typename *string `json:"__typename"` +} + +// GetId returns GetSearchDomainSearchDomainRepository.Id, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainRepository) GetId() string { return v.Id } + +// GetName returns GetSearchDomainSearchDomainRepository.Name, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainRepository) GetName() string { return v.Name } + +// GetDescription returns GetSearchDomainSearchDomainRepository.Description, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainRepository) GetDescription() *string { return v.Description } + +// GetAutomaticSearch returns GetSearchDomainSearchDomainRepository.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainRepository) GetAutomaticSearch() bool { return v.AutomaticSearch } + +// GetTypename returns GetSearchDomainSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetSearchDomainSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type GetSearchDomainSearchDomainView struct { + // Common interface for Repositories and Views. + Id string `json:"id"` + // Common interface for Repositories and Views. + Name string `json:"name"` + // Common interface for Repositories and Views. + Description *string `json:"description"` + // Common interface for Repositories and Views. + AutomaticSearch bool `json:"automaticSearch"` + Connections []GetSearchDomainSearchDomainViewConnectionsViewConnection `json:"connections"` + Typename *string `json:"__typename"` +} + +// GetId returns GetSearchDomainSearchDomainView.Id, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainView) GetId() string { return v.Id } + +// GetName returns GetSearchDomainSearchDomainView.Name, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainView) GetName() string { return v.Name } + +// GetDescription returns GetSearchDomainSearchDomainView.Description, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainView) GetDescription() *string { return v.Description } + +// GetAutomaticSearch returns GetSearchDomainSearchDomainView.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainView) GetAutomaticSearch() bool { return v.AutomaticSearch } + +// GetConnections returns GetSearchDomainSearchDomainView.Connections, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainView) GetConnections() []GetSearchDomainSearchDomainViewConnectionsViewConnection { + return v.Connections +} + +// GetTypename returns GetSearchDomainSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainView) GetTypename() *string { return v.Typename } + +// GetSearchDomainSearchDomainViewConnectionsViewConnection includes the requested fields of the GraphQL type ViewConnection. +// The GraphQL type's documentation follows. +// +// Represents the connection between a view and an underlying repository. +type GetSearchDomainSearchDomainViewConnectionsViewConnection struct { + // The underlying repository + Repository GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository `json:"repository"` + // The filter applied to all results from the repository. + Filter string `json:"filter"` +} + +// GetRepository returns GetSearchDomainSearchDomainViewConnectionsViewConnection.Repository, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainViewConnectionsViewConnection) GetRepository() GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository { + return v.Repository +} + +// GetFilter returns GetSearchDomainSearchDomainViewConnectionsViewConnection.Filter, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainViewConnectionsViewConnection) GetFilter() string { + return v.Filter +} + +// GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository struct { + Name string `json:"name"` +} + +// GetName returns GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository.Name, and is useful for accessing the field via an interface. +func (v *GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository) GetName() string { + return v.Name +} + +// GetUsernameResponse is returned by GetUsername on success. +type GetUsernameResponse struct { + // The currently authenticated user's account. + Viewer GetUsernameViewerAccount `json:"viewer"` +} + +// GetViewer returns GetUsernameResponse.Viewer, and is useful for accessing the field via an interface. +func (v *GetUsernameResponse) GetViewer() GetUsernameViewerAccount { return v.Viewer } + +// GetUsernameViewerAccount includes the requested fields of the GraphQL type Account. +// The GraphQL type's documentation follows. +// +// A user account. +type GetUsernameViewerAccount struct { + Username string `json:"username"` +} + +// GetUsername returns GetUsernameViewerAccount.Username, and is useful for accessing the field via an interface. +func (v *GetUsernameViewerAccount) GetUsername() string { return v.Username } + +// GetUsersByUsernameResponse is returned by GetUsersByUsername on success. +type GetUsersByUsernameResponse struct { + // Requires manage cluster permission; Returns all users in the system. + Users []GetUsersByUsernameUsersUser `json:"users"` +} + +// GetUsers returns GetUsersByUsernameResponse.Users, and is useful for accessing the field via an interface. +func (v *GetUsersByUsernameResponse) GetUsers() []GetUsersByUsernameUsersUser { return v.Users } + +// GetUsersByUsernameUsersUser includes the requested fields of the GraphQL type User. +// The GraphQL type's documentation follows. +// +// A user profile. +type GetUsersByUsernameUsersUser struct { + UserDetails `json:"-"` +} + +// GetId returns GetUsersByUsernameUsersUser.Id, and is useful for accessing the field via an interface. +func (v *GetUsersByUsernameUsersUser) GetId() string { return v.UserDetails.Id } + +// GetUsername returns GetUsersByUsernameUsersUser.Username, and is useful for accessing the field via an interface. +func (v *GetUsersByUsernameUsersUser) GetUsername() string { return v.UserDetails.Username } + +// GetIsRoot returns GetUsersByUsernameUsersUser.IsRoot, and is useful for accessing the field via an interface. +func (v *GetUsersByUsernameUsersUser) GetIsRoot() bool { return v.UserDetails.IsRoot } + +func (v *GetUsersByUsernameUsersUser) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *GetUsersByUsernameUsersUser + graphql.NoUnmarshalJSON + } + firstPass.GetUsersByUsernameUsersUser = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.UserDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalGetUsersByUsernameUsersUser struct { + Id string `json:"id"` + + Username string `json:"username"` + + IsRoot bool `json:"isRoot"` +} + +func (v *GetUsersByUsernameUsersUser) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *GetUsersByUsernameUsersUser) __premarshalJSON() (*__premarshalGetUsersByUsernameUsersUser, error) { + var retval __premarshalGetUsersByUsernameUsersUser + + retval.Id = v.UserDetails.Id + retval.Username = v.UserDetails.Username + retval.IsRoot = v.UserDetails.IsRoot + return &retval, nil +} + +// Http(s) Header entry. +type HttpHeaderEntryInput struct { + // Http(s) Header entry. + Header string `json:"header"` + // Http(s) Header entry. + Value string `json:"value"` +} + +// GetHeader returns HttpHeaderEntryInput.Header, and is useful for accessing the field via an interface. +func (v *HttpHeaderEntryInput) GetHeader() string { return v.Header } + +// GetValue returns HttpHeaderEntryInput.Value, and is useful for accessing the field via an interface. +func (v *HttpHeaderEntryInput) GetValue() string { return v.Value } + +// IngestTokenDetails includes the GraphQL fields of IngestToken requested by the fragment IngestTokenDetails. +// The GraphQL type's documentation follows. +// +// An API ingest token used for sending data to LogScale. +type IngestTokenDetails struct { + Name string `json:"name"` + Token string `json:"token"` + Parser *IngestTokenDetailsParser `json:"parser"` +} + +// GetName returns IngestTokenDetails.Name, and is useful for accessing the field via an interface. +func (v *IngestTokenDetails) GetName() string { return v.Name } + +// GetToken returns IngestTokenDetails.Token, and is useful for accessing the field via an interface. +func (v *IngestTokenDetails) GetToken() string { return v.Token } + +// GetParser returns IngestTokenDetails.Parser, and is useful for accessing the field via an interface. +func (v *IngestTokenDetails) GetParser() *IngestTokenDetailsParser { return v.Parser } + +// IngestTokenDetailsParser includes the requested fields of the GraphQL type Parser. +// The GraphQL type's documentation follows. +// +// A configured parser for incoming data. +type IngestTokenDetailsParser struct { + // Name of the parser. + Name string `json:"name"` +} + +// GetName returns IngestTokenDetailsParser.Name, and is useful for accessing the field via an interface. +func (v *IngestTokenDetailsParser) GetName() string { return v.Name } + +// The version of the LogScale query language to use. +type LanguageVersionEnum string + +const ( + LanguageVersionEnumLegacy LanguageVersionEnum = "legacy" + LanguageVersionEnumXdr1 LanguageVersionEnum = "xdr1" + LanguageVersionEnumXdrdetects1 LanguageVersionEnum = "xdrdetects1" + LanguageVersionEnumFilteralert LanguageVersionEnum = "filteralert" + LanguageVersionEnumFederated1 LanguageVersionEnum = "federated1" +) + +// ListActionsResponse is returned by ListActions on success. +type ListActionsResponse struct { + SearchDomain ListActionsSearchDomain `json:"-"` +} + +// GetSearchDomain returns ListActionsResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *ListActionsResponse) GetSearchDomain() ListActionsSearchDomain { return v.SearchDomain } + +func (v *ListActionsResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.ListActionsResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListActionsSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListActionsResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalListActionsResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *ListActionsResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsResponse) __premarshalJSON() (*__premarshalListActionsResponse, error) { + var retval __premarshalListActionsResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalListActionsSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListActionsResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// ListActionsSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// ListActionsSearchDomain is implemented by the following types: +// ListActionsSearchDomainRepository +// ListActionsSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type ListActionsSearchDomain interface { + implementsGraphQLInterfaceListActionsSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetActions returns the interface-field "actions" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetActions() []ListActionsSearchDomainActionsAction +} + +func (v *ListActionsSearchDomainRepository) implementsGraphQLInterfaceListActionsSearchDomain() {} +func (v *ListActionsSearchDomainView) implementsGraphQLInterfaceListActionsSearchDomain() {} + +func __unmarshalListActionsSearchDomain(b []byte, v *ListActionsSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(ListActionsSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(ListActionsSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListActionsSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalListActionsSearchDomain(v *ListActionsSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListActionsSearchDomainRepository: + typename = "Repository" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainRepository + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainView: + typename = "View" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainView + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListActionsSearchDomain: "%T"`, v) + } +} + +// ListActionsSearchDomainActionsAction includes the requested fields of the GraphQL interface Action. +// +// ListActionsSearchDomainActionsAction is implemented by the following types: +// ListActionsSearchDomainActionsEmailAction +// ListActionsSearchDomainActionsHumioRepoAction +// ListActionsSearchDomainActionsOpsGenieAction +// ListActionsSearchDomainActionsPagerDutyAction +// ListActionsSearchDomainActionsSlackAction +// ListActionsSearchDomainActionsSlackPostMessageAction +// ListActionsSearchDomainActionsUploadFileAction +// ListActionsSearchDomainActionsVictorOpsAction +// ListActionsSearchDomainActionsWebhookAction +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type ListActionsSearchDomainActionsAction interface { + implementsGraphQLInterfaceListActionsSearchDomainActionsAction() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + ActionDetails +} + +func (v *ListActionsSearchDomainActionsEmailAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsHumioRepoAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsOpsGenieAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsPagerDutyAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsSlackAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsUploadFileAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsVictorOpsAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} +func (v *ListActionsSearchDomainActionsWebhookAction) implementsGraphQLInterfaceListActionsSearchDomainActionsAction() { +} + +func __unmarshalListActionsSearchDomainActionsAction(b []byte, v *ListActionsSearchDomainActionsAction) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "EmailAction": + *v = new(ListActionsSearchDomainActionsEmailAction) + return json.Unmarshal(b, *v) + case "HumioRepoAction": + *v = new(ListActionsSearchDomainActionsHumioRepoAction) + return json.Unmarshal(b, *v) + case "OpsGenieAction": + *v = new(ListActionsSearchDomainActionsOpsGenieAction) + return json.Unmarshal(b, *v) + case "PagerDutyAction": + *v = new(ListActionsSearchDomainActionsPagerDutyAction) + return json.Unmarshal(b, *v) + case "SlackAction": + *v = new(ListActionsSearchDomainActionsSlackAction) + return json.Unmarshal(b, *v) + case "SlackPostMessageAction": + *v = new(ListActionsSearchDomainActionsSlackPostMessageAction) + return json.Unmarshal(b, *v) + case "UploadFileAction": + *v = new(ListActionsSearchDomainActionsUploadFileAction) + return json.Unmarshal(b, *v) + case "VictorOpsAction": + *v = new(ListActionsSearchDomainActionsVictorOpsAction) + return json.Unmarshal(b, *v) + case "WebhookAction": + *v = new(ListActionsSearchDomainActionsWebhookAction) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Action.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListActionsSearchDomainActionsAction: "%v"`, tn.TypeName) + } +} + +func __marshalListActionsSearchDomainActionsAction(v *ListActionsSearchDomainActionsAction) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListActionsSearchDomainActionsEmailAction: + typename = "EmailAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsEmailAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsHumioRepoAction: + typename = "HumioRepoAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsHumioRepoAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsOpsGenieAction: + typename = "OpsGenieAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsOpsGenieAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsPagerDutyAction: + typename = "PagerDutyAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsPagerDutyAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsSlackAction: + typename = "SlackAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsSlackAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsSlackPostMessageAction: + typename = "SlackPostMessageAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsSlackPostMessageAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsUploadFileAction: + typename = "UploadFileAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsUploadFileAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsVictorOpsAction: + typename = "VictorOpsAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsVictorOpsAction + }{typename, premarshaled} + return json.Marshal(result) + case *ListActionsSearchDomainActionsWebhookAction: + typename = "WebhookAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalListActionsSearchDomainActionsWebhookAction + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListActionsSearchDomainActionsAction: "%T"`, v) + } +} + +// ListActionsSearchDomainActionsEmailAction includes the requested fields of the GraphQL type EmailAction. +// The GraphQL type's documentation follows. +// +// An email action. +type ListActionsSearchDomainActionsEmailAction struct { + Typename *string `json:"__typename"` + ActionDetailsEmailAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsEmailAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsEmailAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetId() string { + return v.ActionDetailsEmailAction.Id +} + +// GetName returns ListActionsSearchDomainActionsEmailAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetName() string { + return v.ActionDetailsEmailAction.Name +} + +// GetRecipients returns ListActionsSearchDomainActionsEmailAction.Recipients, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetRecipients() []string { + return v.ActionDetailsEmailAction.Recipients +} + +// GetSubjectTemplate returns ListActionsSearchDomainActionsEmailAction.SubjectTemplate, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetSubjectTemplate() *string { + return v.ActionDetailsEmailAction.SubjectTemplate +} + +// GetEmailBodyTemplate returns ListActionsSearchDomainActionsEmailAction.EmailBodyTemplate, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetEmailBodyTemplate() *string { + return v.ActionDetailsEmailAction.EmailBodyTemplate +} + +// GetUseProxy returns ListActionsSearchDomainActionsEmailAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsEmailAction) GetUseProxy() bool { + return v.ActionDetailsEmailAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsEmailAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsEmailAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsEmailAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsEmailAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsEmailAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Recipients []string `json:"recipients"` + + SubjectTemplate *string `json:"subjectTemplate"` + + EmailBodyTemplate *string `json:"emailBodyTemplate"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsEmailAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsEmailAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsEmailAction, error) { + var retval __premarshalListActionsSearchDomainActionsEmailAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsEmailAction.Id + retval.Name = v.ActionDetailsEmailAction.Name + retval.Recipients = v.ActionDetailsEmailAction.Recipients + retval.SubjectTemplate = v.ActionDetailsEmailAction.SubjectTemplate + retval.EmailBodyTemplate = v.ActionDetailsEmailAction.EmailBodyTemplate + retval.UseProxy = v.ActionDetailsEmailAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainActionsHumioRepoAction includes the requested fields of the GraphQL type HumioRepoAction. +// The GraphQL type's documentation follows. +// +// A LogScale repository action. +type ListActionsSearchDomainActionsHumioRepoAction struct { + Typename *string `json:"__typename"` + ActionDetailsHumioRepoAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsHumioRepoAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsHumioRepoAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsHumioRepoAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsHumioRepoAction) GetId() string { + return v.ActionDetailsHumioRepoAction.Id +} + +// GetName returns ListActionsSearchDomainActionsHumioRepoAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsHumioRepoAction) GetName() string { + return v.ActionDetailsHumioRepoAction.Name +} + +// GetIngestToken returns ListActionsSearchDomainActionsHumioRepoAction.IngestToken, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsHumioRepoAction) GetIngestToken() string { + return v.ActionDetailsHumioRepoAction.IngestToken +} + +func (v *ListActionsSearchDomainActionsHumioRepoAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsHumioRepoAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsHumioRepoAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsHumioRepoAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsHumioRepoAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + IngestToken string `json:"ingestToken"` +} + +func (v *ListActionsSearchDomainActionsHumioRepoAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsHumioRepoAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsHumioRepoAction, error) { + var retval __premarshalListActionsSearchDomainActionsHumioRepoAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsHumioRepoAction.Id + retval.Name = v.ActionDetailsHumioRepoAction.Name + retval.IngestToken = v.ActionDetailsHumioRepoAction.IngestToken + return &retval, nil +} + +// ListActionsSearchDomainActionsOpsGenieAction includes the requested fields of the GraphQL type OpsGenieAction. +// The GraphQL type's documentation follows. +// +// An OpsGenie action +type ListActionsSearchDomainActionsOpsGenieAction struct { + Typename *string `json:"__typename"` + ActionDetailsOpsGenieAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsOpsGenieAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsOpsGenieAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsOpsGenieAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsOpsGenieAction) GetId() string { + return v.ActionDetailsOpsGenieAction.Id +} + +// GetName returns ListActionsSearchDomainActionsOpsGenieAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsOpsGenieAction) GetName() string { + return v.ActionDetailsOpsGenieAction.Name +} + +// GetApiUrl returns ListActionsSearchDomainActionsOpsGenieAction.ApiUrl, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsOpsGenieAction) GetApiUrl() string { + return v.ActionDetailsOpsGenieAction.ApiUrl +} + +// GetGenieKey returns ListActionsSearchDomainActionsOpsGenieAction.GenieKey, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsOpsGenieAction) GetGenieKey() string { + return v.ActionDetailsOpsGenieAction.GenieKey +} + +// GetUseProxy returns ListActionsSearchDomainActionsOpsGenieAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsOpsGenieAction) GetUseProxy() bool { + return v.ActionDetailsOpsGenieAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsOpsGenieAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsOpsGenieAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsOpsGenieAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsOpsGenieAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsOpsGenieAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + ApiUrl string `json:"apiUrl"` + + GenieKey string `json:"genieKey"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsOpsGenieAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsOpsGenieAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsOpsGenieAction, error) { + var retval __premarshalListActionsSearchDomainActionsOpsGenieAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsOpsGenieAction.Id + retval.Name = v.ActionDetailsOpsGenieAction.Name + retval.ApiUrl = v.ActionDetailsOpsGenieAction.ApiUrl + retval.GenieKey = v.ActionDetailsOpsGenieAction.GenieKey + retval.UseProxy = v.ActionDetailsOpsGenieAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainActionsPagerDutyAction includes the requested fields of the GraphQL type PagerDutyAction. +// The GraphQL type's documentation follows. +// +// A PagerDuty action. +type ListActionsSearchDomainActionsPagerDutyAction struct { + Typename *string `json:"__typename"` + ActionDetailsPagerDutyAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsPagerDutyAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsPagerDutyAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsPagerDutyAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsPagerDutyAction) GetId() string { + return v.ActionDetailsPagerDutyAction.Id +} + +// GetName returns ListActionsSearchDomainActionsPagerDutyAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsPagerDutyAction) GetName() string { + return v.ActionDetailsPagerDutyAction.Name +} + +// GetSeverity returns ListActionsSearchDomainActionsPagerDutyAction.Severity, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsPagerDutyAction) GetSeverity() string { + return v.ActionDetailsPagerDutyAction.Severity +} + +// GetRoutingKey returns ListActionsSearchDomainActionsPagerDutyAction.RoutingKey, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsPagerDutyAction) GetRoutingKey() string { + return v.ActionDetailsPagerDutyAction.RoutingKey +} + +// GetUseProxy returns ListActionsSearchDomainActionsPagerDutyAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsPagerDutyAction) GetUseProxy() bool { + return v.ActionDetailsPagerDutyAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsPagerDutyAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsPagerDutyAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsPagerDutyAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsPagerDutyAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsPagerDutyAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Severity string `json:"severity"` + + RoutingKey string `json:"routingKey"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsPagerDutyAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsPagerDutyAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsPagerDutyAction, error) { + var retval __premarshalListActionsSearchDomainActionsPagerDutyAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsPagerDutyAction.Id + retval.Name = v.ActionDetailsPagerDutyAction.Name + retval.Severity = v.ActionDetailsPagerDutyAction.Severity + retval.RoutingKey = v.ActionDetailsPagerDutyAction.RoutingKey + retval.UseProxy = v.ActionDetailsPagerDutyAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainActionsSlackAction includes the requested fields of the GraphQL type SlackAction. +// The GraphQL type's documentation follows. +// +// A Slack action +type ListActionsSearchDomainActionsSlackAction struct { + Typename *string `json:"__typename"` + ActionDetailsSlackAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsSlackAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsSlackAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackAction) GetId() string { + return v.ActionDetailsSlackAction.Id +} + +// GetName returns ListActionsSearchDomainActionsSlackAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackAction) GetName() string { + return v.ActionDetailsSlackAction.Name +} + +// GetUrl returns ListActionsSearchDomainActionsSlackAction.Url, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackAction) GetUrl() string { + return v.ActionDetailsSlackAction.Url +} + +// GetFields returns ListActionsSearchDomainActionsSlackAction.Fields, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackAction) GetFields() []ActionDetailsFieldsSlackFieldEntry { + return v.ActionDetailsSlackAction.Fields +} + +// GetUseProxy returns ListActionsSearchDomainActionsSlackAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackAction) GetUseProxy() bool { + return v.ActionDetailsSlackAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsSlackAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsSlackAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsSlackAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsSlackAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsSlackAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Url string `json:"url"` + + Fields []ActionDetailsFieldsSlackFieldEntry `json:"fields"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsSlackAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsSlackAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsSlackAction, error) { + var retval __premarshalListActionsSearchDomainActionsSlackAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsSlackAction.Id + retval.Name = v.ActionDetailsSlackAction.Name + retval.Url = v.ActionDetailsSlackAction.Url + retval.Fields = v.ActionDetailsSlackAction.Fields + retval.UseProxy = v.ActionDetailsSlackAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainActionsSlackPostMessageAction includes the requested fields of the GraphQL type SlackPostMessageAction. +// The GraphQL type's documentation follows. +// +// A slack post-message action. +type ListActionsSearchDomainActionsSlackPostMessageAction struct { + Typename *string `json:"__typename"` + ActionDetailsSlackPostMessageAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsSlackPostMessageAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetTypename() *string { + return v.Typename +} + +// GetId returns ListActionsSearchDomainActionsSlackPostMessageAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetId() string { + return v.ActionDetailsSlackPostMessageAction.Id +} + +// GetName returns ListActionsSearchDomainActionsSlackPostMessageAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetName() string { + return v.ActionDetailsSlackPostMessageAction.Name +} + +// GetApiToken returns ListActionsSearchDomainActionsSlackPostMessageAction.ApiToken, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetApiToken() string { + return v.ActionDetailsSlackPostMessageAction.ApiToken +} + +// GetChannels returns ListActionsSearchDomainActionsSlackPostMessageAction.Channels, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetChannels() []string { + return v.ActionDetailsSlackPostMessageAction.Channels +} + +// GetFields returns ListActionsSearchDomainActionsSlackPostMessageAction.Fields, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetFields() []ActionDetailsFieldsSlackFieldEntry { + return v.ActionDetailsSlackPostMessageAction.Fields +} + +// GetUseProxy returns ListActionsSearchDomainActionsSlackPostMessageAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) GetUseProxy() bool { + return v.ActionDetailsSlackPostMessageAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsSlackPostMessageAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsSlackPostMessageAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsSlackPostMessageAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsSlackPostMessageAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + ApiToken string `json:"apiToken"` + + Channels []string `json:"channels"` + + Fields []ActionDetailsFieldsSlackFieldEntry `json:"fields"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsSlackPostMessageAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsSlackPostMessageAction, error) { + var retval __premarshalListActionsSearchDomainActionsSlackPostMessageAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsSlackPostMessageAction.Id + retval.Name = v.ActionDetailsSlackPostMessageAction.Name + retval.ApiToken = v.ActionDetailsSlackPostMessageAction.ApiToken + retval.Channels = v.ActionDetailsSlackPostMessageAction.Channels + retval.Fields = v.ActionDetailsSlackPostMessageAction.Fields + retval.UseProxy = v.ActionDetailsSlackPostMessageAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainActionsUploadFileAction includes the requested fields of the GraphQL type UploadFileAction. +// The GraphQL type's documentation follows. +// +// An upload file action. +type ListActionsSearchDomainActionsUploadFileAction struct { + Typename *string `json:"__typename"` + ActionDetailsUploadFileAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsUploadFileAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsUploadFileAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsUploadFileAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsUploadFileAction) GetId() string { + return v.ActionDetailsUploadFileAction.Id +} + +// GetName returns ListActionsSearchDomainActionsUploadFileAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsUploadFileAction) GetName() string { + return v.ActionDetailsUploadFileAction.Name +} + +func (v *ListActionsSearchDomainActionsUploadFileAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsUploadFileAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsUploadFileAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsUploadFileAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsUploadFileAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` +} + +func (v *ListActionsSearchDomainActionsUploadFileAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsUploadFileAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsUploadFileAction, error) { + var retval __premarshalListActionsSearchDomainActionsUploadFileAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsUploadFileAction.Id + retval.Name = v.ActionDetailsUploadFileAction.Name + return &retval, nil +} + +// ListActionsSearchDomainActionsVictorOpsAction includes the requested fields of the GraphQL type VictorOpsAction. +// The GraphQL type's documentation follows. +// +// A VictorOps action. +type ListActionsSearchDomainActionsVictorOpsAction struct { + Typename *string `json:"__typename"` + ActionDetailsVictorOpsAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsVictorOpsAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsVictorOpsAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsVictorOpsAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsVictorOpsAction) GetId() string { + return v.ActionDetailsVictorOpsAction.Id +} + +// GetName returns ListActionsSearchDomainActionsVictorOpsAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsVictorOpsAction) GetName() string { + return v.ActionDetailsVictorOpsAction.Name +} + +// GetMessageType returns ListActionsSearchDomainActionsVictorOpsAction.MessageType, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsVictorOpsAction) GetMessageType() string { + return v.ActionDetailsVictorOpsAction.MessageType +} + +// GetNotifyUrl returns ListActionsSearchDomainActionsVictorOpsAction.NotifyUrl, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsVictorOpsAction) GetNotifyUrl() string { + return v.ActionDetailsVictorOpsAction.NotifyUrl +} + +// GetUseProxy returns ListActionsSearchDomainActionsVictorOpsAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsVictorOpsAction) GetUseProxy() bool { + return v.ActionDetailsVictorOpsAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsVictorOpsAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsVictorOpsAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsVictorOpsAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsVictorOpsAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsVictorOpsAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + MessageType string `json:"messageType"` + + NotifyUrl string `json:"notifyUrl"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsVictorOpsAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsVictorOpsAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsVictorOpsAction, error) { + var retval __premarshalListActionsSearchDomainActionsVictorOpsAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsVictorOpsAction.Id + retval.Name = v.ActionDetailsVictorOpsAction.Name + retval.MessageType = v.ActionDetailsVictorOpsAction.MessageType + retval.NotifyUrl = v.ActionDetailsVictorOpsAction.NotifyUrl + retval.UseProxy = v.ActionDetailsVictorOpsAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainActionsWebhookAction includes the requested fields of the GraphQL type WebhookAction. +// The GraphQL type's documentation follows. +// +// A webhook action +type ListActionsSearchDomainActionsWebhookAction struct { + Typename *string `json:"__typename"` + ActionDetailsWebhookAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainActionsWebhookAction.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetTypename() *string { return v.Typename } + +// GetId returns ListActionsSearchDomainActionsWebhookAction.Id, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetId() string { + return v.ActionDetailsWebhookAction.Id +} + +// GetName returns ListActionsSearchDomainActionsWebhookAction.Name, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetName() string { + return v.ActionDetailsWebhookAction.Name +} + +// GetMethod returns ListActionsSearchDomainActionsWebhookAction.Method, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetMethod() string { + return v.ActionDetailsWebhookAction.Method +} + +// GetUrl returns ListActionsSearchDomainActionsWebhookAction.Url, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetUrl() string { + return v.ActionDetailsWebhookAction.Url +} + +// GetHeaders returns ListActionsSearchDomainActionsWebhookAction.Headers, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetHeaders() []ActionDetailsHeadersHttpHeaderEntry { + return v.ActionDetailsWebhookAction.Headers +} + +// GetWebhookBodyTemplate returns ListActionsSearchDomainActionsWebhookAction.WebhookBodyTemplate, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetWebhookBodyTemplate() string { + return v.ActionDetailsWebhookAction.WebhookBodyTemplate +} + +// GetIgnoreSSL returns ListActionsSearchDomainActionsWebhookAction.IgnoreSSL, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetIgnoreSSL() bool { + return v.ActionDetailsWebhookAction.IgnoreSSL +} + +// GetUseProxy returns ListActionsSearchDomainActionsWebhookAction.UseProxy, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainActionsWebhookAction) GetUseProxy() bool { + return v.ActionDetailsWebhookAction.UseProxy +} + +func (v *ListActionsSearchDomainActionsWebhookAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainActionsWebhookAction + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainActionsWebhookAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionDetailsWebhookAction) + if err != nil { + return err + } + return nil +} + +type __premarshalListActionsSearchDomainActionsWebhookAction struct { + Typename *string `json:"__typename"` + + Id string `json:"id"` + + Name string `json:"name"` + + Method string `json:"method"` + + Url string `json:"url"` + + Headers []ActionDetailsHeadersHttpHeaderEntry `json:"headers"` + + WebhookBodyTemplate string `json:"WebhookBodyTemplate"` + + IgnoreSSL bool `json:"ignoreSSL"` + + UseProxy bool `json:"useProxy"` +} + +func (v *ListActionsSearchDomainActionsWebhookAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainActionsWebhookAction) __premarshalJSON() (*__premarshalListActionsSearchDomainActionsWebhookAction, error) { + var retval __premarshalListActionsSearchDomainActionsWebhookAction + + retval.Typename = v.Typename + retval.Id = v.ActionDetailsWebhookAction.Id + retval.Name = v.ActionDetailsWebhookAction.Name + retval.Method = v.ActionDetailsWebhookAction.Method + retval.Url = v.ActionDetailsWebhookAction.Url + retval.Headers = v.ActionDetailsWebhookAction.Headers + retval.WebhookBodyTemplate = v.ActionDetailsWebhookAction.WebhookBodyTemplate + retval.IgnoreSSL = v.ActionDetailsWebhookAction.IgnoreSSL + retval.UseProxy = v.ActionDetailsWebhookAction.UseProxy + return &retval, nil +} + +// ListActionsSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListActionsSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Actions []ListActionsSearchDomainActionsAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetActions returns ListActionsSearchDomainRepository.Actions, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainRepository) GetActions() []ListActionsSearchDomainActionsAction { + return v.Actions +} + +func (v *ListActionsSearchDomainRepository) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainRepository + Actions []json.RawMessage `json:"actions"` + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainRepository = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Actions + src := firstPass.Actions + *dst = make( + []ListActionsSearchDomainActionsAction, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListActionsSearchDomainActionsAction( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListActionsSearchDomainRepository.Actions: %w", err) + } + } + } + } + return nil +} + +type __premarshalListActionsSearchDomainRepository struct { + Typename *string `json:"__typename"` + + Actions []json.RawMessage `json:"actions"` +} + +func (v *ListActionsSearchDomainRepository) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainRepository) __premarshalJSON() (*__premarshalListActionsSearchDomainRepository, error) { + var retval __premarshalListActionsSearchDomainRepository + + retval.Typename = v.Typename + { + + dst := &retval.Actions + src := v.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalListActionsSearchDomainActionsAction( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListActionsSearchDomainRepository.Actions: %w", err) + } + } + } + return &retval, nil +} + +// ListActionsSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type ListActionsSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Actions []ListActionsSearchDomainActionsAction `json:"-"` +} + +// GetTypename returns ListActionsSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainView) GetTypename() *string { return v.Typename } + +// GetActions returns ListActionsSearchDomainView.Actions, and is useful for accessing the field via an interface. +func (v *ListActionsSearchDomainView) GetActions() []ListActionsSearchDomainActionsAction { + return v.Actions +} + +func (v *ListActionsSearchDomainView) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListActionsSearchDomainView + Actions []json.RawMessage `json:"actions"` + graphql.NoUnmarshalJSON + } + firstPass.ListActionsSearchDomainView = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Actions + src := firstPass.Actions + *dst = make( + []ListActionsSearchDomainActionsAction, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListActionsSearchDomainActionsAction( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListActionsSearchDomainView.Actions: %w", err) + } + } + } + } + return nil +} + +type __premarshalListActionsSearchDomainView struct { + Typename *string `json:"__typename"` + + Actions []json.RawMessage `json:"actions"` +} + +func (v *ListActionsSearchDomainView) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListActionsSearchDomainView) __premarshalJSON() (*__premarshalListActionsSearchDomainView, error) { + var retval __premarshalListActionsSearchDomainView + + retval.Typename = v.Typename + { + + dst := &retval.Actions + src := v.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalListActionsSearchDomainActionsAction( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListActionsSearchDomainView.Actions: %w", err) + } + } + } + return &retval, nil +} + +// ListAggregateAlertsResponse is returned by ListAggregateAlerts on success. +type ListAggregateAlertsResponse struct { + SearchDomain ListAggregateAlertsSearchDomain `json:"-"` +} + +// GetSearchDomain returns ListAggregateAlertsResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsResponse) GetSearchDomain() ListAggregateAlertsSearchDomain { + return v.SearchDomain +} + +func (v *ListAggregateAlertsResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListAggregateAlertsResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.ListAggregateAlertsResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListAggregateAlertsSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListAggregateAlertsResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalListAggregateAlertsResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *ListAggregateAlertsResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListAggregateAlertsResponse) __premarshalJSON() (*__premarshalListAggregateAlertsResponse, error) { + var retval __premarshalListAggregateAlertsResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalListAggregateAlertsSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListAggregateAlertsResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// ListAggregateAlertsSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// ListAggregateAlertsSearchDomain is implemented by the following types: +// ListAggregateAlertsSearchDomainRepository +// ListAggregateAlertsSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type ListAggregateAlertsSearchDomain interface { + implementsGraphQLInterfaceListAggregateAlertsSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetAggregateAlerts returns the interface-field "aggregateAlerts" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetAggregateAlerts() []ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert +} + +func (v *ListAggregateAlertsSearchDomainRepository) implementsGraphQLInterfaceListAggregateAlertsSearchDomain() { +} +func (v *ListAggregateAlertsSearchDomainView) implementsGraphQLInterfaceListAggregateAlertsSearchDomain() { +} + +func __unmarshalListAggregateAlertsSearchDomain(b []byte, v *ListAggregateAlertsSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(ListAggregateAlertsSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(ListAggregateAlertsSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListAggregateAlertsSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalListAggregateAlertsSearchDomain(v *ListAggregateAlertsSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListAggregateAlertsSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *ListAggregateAlertsSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *ListAggregateAlertsSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *ListAggregateAlertsSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListAggregateAlertsSearchDomain: "%T"`, v) + } +} + +// ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert includes the requested fields of the GraphQL type AggregateAlert. +// The GraphQL type's documentation follows. +// +// An aggregate alert. +type ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert struct { + AggregateAlertDetails `json:"-"` +} + +// GetId returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.Id, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetId() string { + return v.AggregateAlertDetails.Id +} + +// GetName returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.Name, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetName() string { + return v.AggregateAlertDetails.Name +} + +// GetDescription returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.Description, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetDescription() *string { + return v.AggregateAlertDetails.Description +} + +// GetQueryString returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.QueryString, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetQueryString() string { + return v.AggregateAlertDetails.QueryString +} + +// GetSearchIntervalSeconds returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetSearchIntervalSeconds() int64 { + return v.AggregateAlertDetails.SearchIntervalSeconds +} + +// GetThrottleTimeSeconds returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetThrottleTimeSeconds() int64 { + return v.AggregateAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetThrottleField() *string { + return v.AggregateAlertDetails.ThrottleField +} + +// GetLabels returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.Labels, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetLabels() []string { + return v.AggregateAlertDetails.Labels +} + +// GetEnabled returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.Enabled, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetEnabled() bool { + return v.AggregateAlertDetails.Enabled +} + +// GetTriggerMode returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.TriggerMode, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetTriggerMode() TriggerMode { + return v.AggregateAlertDetails.TriggerMode +} + +// GetQueryTimestampType returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.QueryTimestampType, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetQueryTimestampType() QueryTimestampType { + return v.AggregateAlertDetails.QueryTimestampType +} + +// GetActions returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.Actions, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetActions() []SharedActionNameType { + return v.AggregateAlertDetails.Actions +} + +// GetQueryOwnership returns ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AggregateAlertDetails.QueryOwnership +} + +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert + graphql.NoUnmarshalJSON + } + firstPass.ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AggregateAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + SearchIntervalSeconds int64 `json:"searchIntervalSeconds"` + + ThrottleTimeSeconds int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + TriggerMode TriggerMode `json:"triggerMode"` + + QueryTimestampType QueryTimestampType `json:"queryTimestampType"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert) __premarshalJSON() (*__premarshalListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert, error) { + var retval __premarshalListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert + + retval.Id = v.AggregateAlertDetails.Id + retval.Name = v.AggregateAlertDetails.Name + retval.Description = v.AggregateAlertDetails.Description + retval.QueryString = v.AggregateAlertDetails.QueryString + retval.SearchIntervalSeconds = v.AggregateAlertDetails.SearchIntervalSeconds + retval.ThrottleTimeSeconds = v.AggregateAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.AggregateAlertDetails.ThrottleField + retval.Labels = v.AggregateAlertDetails.Labels + retval.Enabled = v.AggregateAlertDetails.Enabled + retval.TriggerMode = v.AggregateAlertDetails.TriggerMode + retval.QueryTimestampType = v.AggregateAlertDetails.QueryTimestampType + { + + dst := &retval.Actions + src := v.AggregateAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.AggregateAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AggregateAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert.AggregateAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// ListAggregateAlertsSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListAggregateAlertsSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + AggregateAlerts []ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert `json:"aggregateAlerts"` +} + +// GetTypename returns ListAggregateAlertsSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetAggregateAlerts returns ListAggregateAlertsSearchDomainRepository.AggregateAlerts, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainRepository) GetAggregateAlerts() []ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert { + return v.AggregateAlerts +} + +// ListAggregateAlertsSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type ListAggregateAlertsSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + AggregateAlerts []ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert `json:"aggregateAlerts"` +} + +// GetTypename returns ListAggregateAlertsSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainView) GetTypename() *string { return v.Typename } + +// GetAggregateAlerts returns ListAggregateAlertsSearchDomainView.AggregateAlerts, and is useful for accessing the field via an interface. +func (v *ListAggregateAlertsSearchDomainView) GetAggregateAlerts() []ListAggregateAlertsSearchDomainAggregateAlertsAggregateAlert { + return v.AggregateAlerts +} + +// ListAlertsResponse is returned by ListAlerts on success. +type ListAlertsResponse struct { + SearchDomain ListAlertsSearchDomain `json:"-"` +} + +// GetSearchDomain returns ListAlertsResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *ListAlertsResponse) GetSearchDomain() ListAlertsSearchDomain { return v.SearchDomain } + +func (v *ListAlertsResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListAlertsResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.ListAlertsResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListAlertsSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListAlertsResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalListAlertsResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *ListAlertsResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListAlertsResponse) __premarshalJSON() (*__premarshalListAlertsResponse, error) { + var retval __premarshalListAlertsResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalListAlertsSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListAlertsResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// ListAlertsSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// ListAlertsSearchDomain is implemented by the following types: +// ListAlertsSearchDomainRepository +// ListAlertsSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type ListAlertsSearchDomain interface { + implementsGraphQLInterfaceListAlertsSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetAlerts returns the interface-field "alerts" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetAlerts() []ListAlertsSearchDomainAlertsAlert +} + +func (v *ListAlertsSearchDomainRepository) implementsGraphQLInterfaceListAlertsSearchDomain() {} +func (v *ListAlertsSearchDomainView) implementsGraphQLInterfaceListAlertsSearchDomain() {} + +func __unmarshalListAlertsSearchDomain(b []byte, v *ListAlertsSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(ListAlertsSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(ListAlertsSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListAlertsSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalListAlertsSearchDomain(v *ListAlertsSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListAlertsSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *ListAlertsSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *ListAlertsSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *ListAlertsSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListAlertsSearchDomain: "%T"`, v) + } +} + +// ListAlertsSearchDomainAlertsAlert includes the requested fields of the GraphQL type Alert. +// The GraphQL type's documentation follows. +// +// An alert. +type ListAlertsSearchDomainAlertsAlert struct { + AlertDetails `json:"-"` +} + +// GetId returns ListAlertsSearchDomainAlertsAlert.Id, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetId() string { return v.AlertDetails.Id } + +// GetName returns ListAlertsSearchDomainAlertsAlert.Name, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetName() string { return v.AlertDetails.Name } + +// GetQueryString returns ListAlertsSearchDomainAlertsAlert.QueryString, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetQueryString() string { + return v.AlertDetails.QueryString +} + +// GetQueryStart returns ListAlertsSearchDomainAlertsAlert.QueryStart, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetQueryStart() string { return v.AlertDetails.QueryStart } + +// GetThrottleField returns ListAlertsSearchDomainAlertsAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetThrottleField() *string { + return v.AlertDetails.ThrottleField +} + +// GetDescription returns ListAlertsSearchDomainAlertsAlert.Description, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetDescription() *string { + return v.AlertDetails.Description +} + +// GetThrottleTimeMillis returns ListAlertsSearchDomainAlertsAlert.ThrottleTimeMillis, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetThrottleTimeMillis() int64 { + return v.AlertDetails.ThrottleTimeMillis +} + +// GetEnabled returns ListAlertsSearchDomainAlertsAlert.Enabled, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetEnabled() bool { return v.AlertDetails.Enabled } + +// GetLabels returns ListAlertsSearchDomainAlertsAlert.Labels, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetLabels() []string { return v.AlertDetails.Labels } + +// GetActionsV2 returns ListAlertsSearchDomainAlertsAlert.ActionsV2, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetActionsV2() []SharedActionNameType { + return v.AlertDetails.ActionsV2 +} + +// GetQueryOwnership returns ListAlertsSearchDomainAlertsAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainAlertsAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AlertDetails.QueryOwnership +} + +func (v *ListAlertsSearchDomainAlertsAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListAlertsSearchDomainAlertsAlert + graphql.NoUnmarshalJSON + } + firstPass.ListAlertsSearchDomainAlertsAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalListAlertsSearchDomainAlertsAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + QueryString string `json:"queryString"` + + QueryStart string `json:"queryStart"` + + ThrottleField *string `json:"throttleField"` + + Description *string `json:"description"` + + ThrottleTimeMillis int64 `json:"throttleTimeMillis"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *ListAlertsSearchDomainAlertsAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListAlertsSearchDomainAlertsAlert) __premarshalJSON() (*__premarshalListAlertsSearchDomainAlertsAlert, error) { + var retval __premarshalListAlertsSearchDomainAlertsAlert + + retval.Id = v.AlertDetails.Id + retval.Name = v.AlertDetails.Name + retval.QueryString = v.AlertDetails.QueryString + retval.QueryStart = v.AlertDetails.QueryStart + retval.ThrottleField = v.AlertDetails.ThrottleField + retval.Description = v.AlertDetails.Description + retval.ThrottleTimeMillis = v.AlertDetails.ThrottleTimeMillis + retval.Enabled = v.AlertDetails.Enabled + retval.Labels = v.AlertDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.AlertDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListAlertsSearchDomainAlertsAlert.AlertDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListAlertsSearchDomainAlertsAlert.AlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// ListAlertsSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListAlertsSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Alerts []ListAlertsSearchDomainAlertsAlert `json:"alerts"` +} + +// GetTypename returns ListAlertsSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetAlerts returns ListAlertsSearchDomainRepository.Alerts, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainRepository) GetAlerts() []ListAlertsSearchDomainAlertsAlert { + return v.Alerts +} + +// ListAlertsSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type ListAlertsSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Alerts []ListAlertsSearchDomainAlertsAlert `json:"alerts"` +} + +// GetTypename returns ListAlertsSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainView) GetTypename() *string { return v.Typename } + +// GetAlerts returns ListAlertsSearchDomainView.Alerts, and is useful for accessing the field via an interface. +func (v *ListAlertsSearchDomainView) GetAlerts() []ListAlertsSearchDomainAlertsAlert { return v.Alerts } + +// ListFilterAlertsResponse is returned by ListFilterAlerts on success. +type ListFilterAlertsResponse struct { + SearchDomain ListFilterAlertsSearchDomain `json:"-"` +} + +// GetSearchDomain returns ListFilterAlertsResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsResponse) GetSearchDomain() ListFilterAlertsSearchDomain { + return v.SearchDomain +} + +func (v *ListFilterAlertsResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListFilterAlertsResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.ListFilterAlertsResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListFilterAlertsSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListFilterAlertsResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalListFilterAlertsResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *ListFilterAlertsResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListFilterAlertsResponse) __premarshalJSON() (*__premarshalListFilterAlertsResponse, error) { + var retval __premarshalListFilterAlertsResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalListFilterAlertsSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListFilterAlertsResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// ListFilterAlertsSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// ListFilterAlertsSearchDomain is implemented by the following types: +// ListFilterAlertsSearchDomainRepository +// ListFilterAlertsSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type ListFilterAlertsSearchDomain interface { + implementsGraphQLInterfaceListFilterAlertsSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetFilterAlerts returns the interface-field "filterAlerts" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetFilterAlerts() []ListFilterAlertsSearchDomainFilterAlertsFilterAlert +} + +func (v *ListFilterAlertsSearchDomainRepository) implementsGraphQLInterfaceListFilterAlertsSearchDomain() { +} +func (v *ListFilterAlertsSearchDomainView) implementsGraphQLInterfaceListFilterAlertsSearchDomain() {} + +func __unmarshalListFilterAlertsSearchDomain(b []byte, v *ListFilterAlertsSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(ListFilterAlertsSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(ListFilterAlertsSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListFilterAlertsSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalListFilterAlertsSearchDomain(v *ListFilterAlertsSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListFilterAlertsSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *ListFilterAlertsSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *ListFilterAlertsSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *ListFilterAlertsSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListFilterAlertsSearchDomain: "%T"`, v) + } +} + +// ListFilterAlertsSearchDomainFilterAlertsFilterAlert includes the requested fields of the GraphQL type FilterAlert. +// The GraphQL type's documentation follows. +// +// A filter alert. +type ListFilterAlertsSearchDomainFilterAlertsFilterAlert struct { + FilterAlertDetails `json:"-"` +} + +// GetId returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.Id, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetId() string { + return v.FilterAlertDetails.Id +} + +// GetName returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.Name, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetName() string { + return v.FilterAlertDetails.Name +} + +// GetDescription returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.Description, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetDescription() *string { + return v.FilterAlertDetails.Description +} + +// GetQueryString returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.QueryString, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetQueryString() string { + return v.FilterAlertDetails.QueryString +} + +// GetThrottleTimeSeconds returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetThrottleTimeSeconds() *int64 { + return v.FilterAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetThrottleField() *string { + return v.FilterAlertDetails.ThrottleField +} + +// GetLabels returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.Labels, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetLabels() []string { + return v.FilterAlertDetails.Labels +} + +// GetEnabled returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.Enabled, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetEnabled() bool { + return v.FilterAlertDetails.Enabled +} + +// GetActions returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.Actions, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetActions() []SharedActionNameType { + return v.FilterAlertDetails.Actions +} + +// GetQueryOwnership returns ListFilterAlertsSearchDomainFilterAlertsFilterAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.FilterAlertDetails.QueryOwnership +} + +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListFilterAlertsSearchDomainFilterAlertsFilterAlert + graphql.NoUnmarshalJSON + } + firstPass.ListFilterAlertsSearchDomainFilterAlertsFilterAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FilterAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalListFilterAlertsSearchDomainFilterAlertsFilterAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + ThrottleTimeSeconds *int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListFilterAlertsSearchDomainFilterAlertsFilterAlert) __premarshalJSON() (*__premarshalListFilterAlertsSearchDomainFilterAlertsFilterAlert, error) { + var retval __premarshalListFilterAlertsSearchDomainFilterAlertsFilterAlert + + retval.Id = v.FilterAlertDetails.Id + retval.Name = v.FilterAlertDetails.Name + retval.Description = v.FilterAlertDetails.Description + retval.QueryString = v.FilterAlertDetails.QueryString + retval.ThrottleTimeSeconds = v.FilterAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.FilterAlertDetails.ThrottleField + retval.Labels = v.FilterAlertDetails.Labels + retval.Enabled = v.FilterAlertDetails.Enabled + { + + dst := &retval.Actions + src := v.FilterAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListFilterAlertsSearchDomainFilterAlertsFilterAlert.FilterAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.FilterAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListFilterAlertsSearchDomainFilterAlertsFilterAlert.FilterAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// ListFilterAlertsSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListFilterAlertsSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + FilterAlerts []ListFilterAlertsSearchDomainFilterAlertsFilterAlert `json:"filterAlerts"` +} + +// GetTypename returns ListFilterAlertsSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetFilterAlerts returns ListFilterAlertsSearchDomainRepository.FilterAlerts, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainRepository) GetFilterAlerts() []ListFilterAlertsSearchDomainFilterAlertsFilterAlert { + return v.FilterAlerts +} + +// ListFilterAlertsSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type ListFilterAlertsSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + FilterAlerts []ListFilterAlertsSearchDomainFilterAlertsFilterAlert `json:"filterAlerts"` +} + +// GetTypename returns ListFilterAlertsSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainView) GetTypename() *string { return v.Typename } + +// GetFilterAlerts returns ListFilterAlertsSearchDomainView.FilterAlerts, and is useful for accessing the field via an interface. +func (v *ListFilterAlertsSearchDomainView) GetFilterAlerts() []ListFilterAlertsSearchDomainFilterAlertsFilterAlert { + return v.FilterAlerts +} + +// ListIngestTokensRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListIngestTokensRepository struct { + IngestTokens []ListIngestTokensRepositoryIngestTokensIngestToken `json:"ingestTokens"` +} + +// GetIngestTokens returns ListIngestTokensRepository.IngestTokens, and is useful for accessing the field via an interface. +func (v *ListIngestTokensRepository) GetIngestTokens() []ListIngestTokensRepositoryIngestTokensIngestToken { + return v.IngestTokens +} + +// ListIngestTokensRepositoryIngestTokensIngestToken includes the requested fields of the GraphQL type IngestToken. +// The GraphQL type's documentation follows. +// +// An API ingest token used for sending data to LogScale. +type ListIngestTokensRepositoryIngestTokensIngestToken struct { + IngestTokenDetails `json:"-"` +} + +// GetName returns ListIngestTokensRepositoryIngestTokensIngestToken.Name, and is useful for accessing the field via an interface. +func (v *ListIngestTokensRepositoryIngestTokensIngestToken) GetName() string { + return v.IngestTokenDetails.Name +} + +// GetToken returns ListIngestTokensRepositoryIngestTokensIngestToken.Token, and is useful for accessing the field via an interface. +func (v *ListIngestTokensRepositoryIngestTokensIngestToken) GetToken() string { + return v.IngestTokenDetails.Token +} + +// GetParser returns ListIngestTokensRepositoryIngestTokensIngestToken.Parser, and is useful for accessing the field via an interface. +func (v *ListIngestTokensRepositoryIngestTokensIngestToken) GetParser() *IngestTokenDetailsParser { + return v.IngestTokenDetails.Parser +} + +func (v *ListIngestTokensRepositoryIngestTokensIngestToken) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListIngestTokensRepositoryIngestTokensIngestToken + graphql.NoUnmarshalJSON + } + firstPass.ListIngestTokensRepositoryIngestTokensIngestToken = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.IngestTokenDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalListIngestTokensRepositoryIngestTokensIngestToken struct { + Name string `json:"name"` + + Token string `json:"token"` + + Parser *IngestTokenDetailsParser `json:"parser"` +} + +func (v *ListIngestTokensRepositoryIngestTokensIngestToken) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListIngestTokensRepositoryIngestTokensIngestToken) __premarshalJSON() (*__premarshalListIngestTokensRepositoryIngestTokensIngestToken, error) { + var retval __premarshalListIngestTokensRepositoryIngestTokensIngestToken + + retval.Name = v.IngestTokenDetails.Name + retval.Token = v.IngestTokenDetails.Token + retval.Parser = v.IngestTokenDetails.Parser + return &retval, nil +} + +// ListIngestTokensResponse is returned by ListIngestTokens on success. +type ListIngestTokensResponse struct { + // Lookup a given repository by name. + Repository ListIngestTokensRepository `json:"repository"` +} + +// GetRepository returns ListIngestTokensResponse.Repository, and is useful for accessing the field via an interface. +func (v *ListIngestTokensResponse) GetRepository() ListIngestTokensRepository { return v.Repository } + +// ListParsersRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListParsersRepository struct { + // Saved parsers. + Parsers []ListParsersRepositoryParsersParser `json:"parsers"` +} + +// GetParsers returns ListParsersRepository.Parsers, and is useful for accessing the field via an interface. +func (v *ListParsersRepository) GetParsers() []ListParsersRepositoryParsersParser { return v.Parsers } + +// ListParsersRepositoryParsersParser includes the requested fields of the GraphQL type Parser. +// The GraphQL type's documentation follows. +// +// A configured parser for incoming data. +type ListParsersRepositoryParsersParser struct { + // The id of the parser. + Id string `json:"id"` + // Name of the parser. + Name string `json:"name"` +} + +// GetId returns ListParsersRepositoryParsersParser.Id, and is useful for accessing the field via an interface. +func (v *ListParsersRepositoryParsersParser) GetId() string { return v.Id } + +// GetName returns ListParsersRepositoryParsersParser.Name, and is useful for accessing the field via an interface. +func (v *ListParsersRepositoryParsersParser) GetName() string { return v.Name } + +// ListParsersResponse is returned by ListParsers on success. +type ListParsersResponse struct { + // Lookup a given repository by name. + Repository ListParsersRepository `json:"repository"` +} + +// GetRepository returns ListParsersResponse.Repository, and is useful for accessing the field via an interface. +func (v *ListParsersResponse) GetRepository() ListParsersRepository { return v.Repository } + +// ListRepositoriesRepositoriesRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListRepositoriesRepositoriesRepository struct { + Id string `json:"id"` + Name string `json:"name"` + // Total size of data. Size is measured as the size after compression. + CompressedByteSize int64 `json:"compressedByteSize"` +} + +// GetId returns ListRepositoriesRepositoriesRepository.Id, and is useful for accessing the field via an interface. +func (v *ListRepositoriesRepositoriesRepository) GetId() string { return v.Id } + +// GetName returns ListRepositoriesRepositoriesRepository.Name, and is useful for accessing the field via an interface. +func (v *ListRepositoriesRepositoriesRepository) GetName() string { return v.Name } + +// GetCompressedByteSize returns ListRepositoriesRepositoriesRepository.CompressedByteSize, and is useful for accessing the field via an interface. +func (v *ListRepositoriesRepositoriesRepository) GetCompressedByteSize() int64 { + return v.CompressedByteSize +} + +// ListRepositoriesResponse is returned by ListRepositories on success. +type ListRepositoriesResponse struct { + Repositories []ListRepositoriesRepositoriesRepository `json:"repositories"` +} + +// GetRepositories returns ListRepositoriesResponse.Repositories, and is useful for accessing the field via an interface. +func (v *ListRepositoriesResponse) GetRepositories() []ListRepositoriesRepositoriesRepository { + return v.Repositories +} + +// ListScheduledSearchesResponse is returned by ListScheduledSearches on success. +type ListScheduledSearchesResponse struct { + SearchDomain ListScheduledSearchesSearchDomain `json:"-"` +} + +// GetSearchDomain returns ListScheduledSearchesResponse.SearchDomain, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesResponse) GetSearchDomain() ListScheduledSearchesSearchDomain { + return v.SearchDomain +} + +func (v *ListScheduledSearchesResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListScheduledSearchesResponse + SearchDomain json.RawMessage `json:"searchDomain"` + graphql.NoUnmarshalJSON + } + firstPass.ListScheduledSearchesResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomain + src := firstPass.SearchDomain + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListScheduledSearchesSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListScheduledSearchesResponse.SearchDomain: %w", err) + } + } + } + return nil +} + +type __premarshalListScheduledSearchesResponse struct { + SearchDomain json.RawMessage `json:"searchDomain"` +} + +func (v *ListScheduledSearchesResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListScheduledSearchesResponse) __premarshalJSON() (*__premarshalListScheduledSearchesResponse, error) { + var retval __premarshalListScheduledSearchesResponse + + { + + dst := &retval.SearchDomain + src := v.SearchDomain + var err error + *dst, err = __marshalListScheduledSearchesSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListScheduledSearchesResponse.SearchDomain: %w", err) + } + } + return &retval, nil +} + +// ListScheduledSearchesSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// ListScheduledSearchesSearchDomain is implemented by the following types: +// ListScheduledSearchesSearchDomainRepository +// ListScheduledSearchesSearchDomainView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type ListScheduledSearchesSearchDomain interface { + implementsGraphQLInterfaceListScheduledSearchesSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetScheduledSearches returns the interface-field "scheduledSearches" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetScheduledSearches() []ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch +} + +func (v *ListScheduledSearchesSearchDomainRepository) implementsGraphQLInterfaceListScheduledSearchesSearchDomain() { +} +func (v *ListScheduledSearchesSearchDomainView) implementsGraphQLInterfaceListScheduledSearchesSearchDomain() { +} + +func __unmarshalListScheduledSearchesSearchDomain(b []byte, v *ListScheduledSearchesSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(ListScheduledSearchesSearchDomainRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(ListScheduledSearchesSearchDomainView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListScheduledSearchesSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalListScheduledSearchesSearchDomain(v *ListScheduledSearchesSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListScheduledSearchesSearchDomainRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *ListScheduledSearchesSearchDomainRepository + }{typename, v} + return json.Marshal(result) + case *ListScheduledSearchesSearchDomainView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *ListScheduledSearchesSearchDomainView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListScheduledSearchesSearchDomain: "%T"`, v) + } +} + +// ListScheduledSearchesSearchDomainRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListScheduledSearchesSearchDomainRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + ScheduledSearches []ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch `json:"scheduledSearches"` +} + +// GetTypename returns ListScheduledSearchesSearchDomainRepository.Typename, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainRepository) GetTypename() *string { return v.Typename } + +// GetScheduledSearches returns ListScheduledSearchesSearchDomainRepository.ScheduledSearches, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainRepository) GetScheduledSearches() []ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch { + return v.ScheduledSearches +} + +// ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch includes the requested fields of the GraphQL type ScheduledSearch. +// The GraphQL type's documentation follows. +// +// Information about a scheduled search +type ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch struct { + ScheduledSearchDetails `json:"-"` +} + +// GetId returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Id, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetId() string { + return v.ScheduledSearchDetails.Id +} + +// GetName returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Name, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetName() string { + return v.ScheduledSearchDetails.Name +} + +// GetDescription returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Description, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetDescription() *string { + return v.ScheduledSearchDetails.Description +} + +// GetQueryString returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.QueryString, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetQueryString() string { + return v.ScheduledSearchDetails.QueryString +} + +// GetStart returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Start, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetStart() string { + return v.ScheduledSearchDetails.Start +} + +// GetEnd returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.End, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetEnd() string { + return v.ScheduledSearchDetails.End +} + +// GetTimeZone returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.TimeZone, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetTimeZone() string { + return v.ScheduledSearchDetails.TimeZone +} + +// GetSchedule returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Schedule, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetSchedule() string { + return v.ScheduledSearchDetails.Schedule +} + +// GetBackfillLimit returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.BackfillLimit, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetBackfillLimit() int { + return v.ScheduledSearchDetails.BackfillLimit +} + +// GetEnabled returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Enabled, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetEnabled() bool { + return v.ScheduledSearchDetails.Enabled +} + +// GetLabels returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.Labels, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetLabels() []string { + return v.ScheduledSearchDetails.Labels +} + +// GetActionsV2 returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.ActionsV2, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetActionsV2() []SharedActionNameType { + return v.ScheduledSearchDetails.ActionsV2 +} + +// GetQueryOwnership returns ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.QueryOwnership, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) GetQueryOwnership() SharedQueryOwnershipType { + return v.ScheduledSearchDetails.QueryOwnership +} + +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch + graphql.NoUnmarshalJSON + } + firstPass.ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ScheduledSearchDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + Start string `json:"start"` + + End string `json:"end"` + + TimeZone string `json:"timeZone"` + + Schedule string `json:"schedule"` + + BackfillLimit int `json:"backfillLimit"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch) __premarshalJSON() (*__premarshalListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch, error) { + var retval __premarshalListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch + + retval.Id = v.ScheduledSearchDetails.Id + retval.Name = v.ScheduledSearchDetails.Name + retval.Description = v.ScheduledSearchDetails.Description + retval.QueryString = v.ScheduledSearchDetails.QueryString + retval.Start = v.ScheduledSearchDetails.Start + retval.End = v.ScheduledSearchDetails.End + retval.TimeZone = v.ScheduledSearchDetails.TimeZone + retval.Schedule = v.ScheduledSearchDetails.Schedule + retval.BackfillLimit = v.ScheduledSearchDetails.BackfillLimit + retval.Enabled = v.ScheduledSearchDetails.Enabled + retval.Labels = v.ScheduledSearchDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.ScheduledSearchDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.ScheduledSearchDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.ScheduledSearchDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch.ScheduledSearchDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// ListScheduledSearchesSearchDomainView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type ListScheduledSearchesSearchDomainView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + ScheduledSearches []ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch `json:"scheduledSearches"` +} + +// GetTypename returns ListScheduledSearchesSearchDomainView.Typename, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainView) GetTypename() *string { return v.Typename } + +// GetScheduledSearches returns ListScheduledSearchesSearchDomainView.ScheduledSearches, and is useful for accessing the field via an interface. +func (v *ListScheduledSearchesSearchDomainView) GetScheduledSearches() []ListScheduledSearchesSearchDomainScheduledSearchesScheduledSearch { + return v.ScheduledSearches +} + +// ListSearchDomainsResponse is returned by ListSearchDomains on success. +type ListSearchDomainsResponse struct { + SearchDomains []ListSearchDomainsSearchDomainsSearchDomain `json:"-"` +} + +// GetSearchDomains returns ListSearchDomainsResponse.SearchDomains, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsResponse) GetSearchDomains() []ListSearchDomainsSearchDomainsSearchDomain { + return v.SearchDomains +} + +func (v *ListSearchDomainsResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ListSearchDomainsResponse + SearchDomains []json.RawMessage `json:"searchDomains"` + graphql.NoUnmarshalJSON + } + firstPass.ListSearchDomainsResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.SearchDomains + src := firstPass.SearchDomains + *dst = make( + []ListSearchDomainsSearchDomainsSearchDomain, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalListSearchDomainsSearchDomainsSearchDomain( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ListSearchDomainsResponse.SearchDomains: %w", err) + } + } + } + } + return nil +} + +type __premarshalListSearchDomainsResponse struct { + SearchDomains []json.RawMessage `json:"searchDomains"` +} + +func (v *ListSearchDomainsResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ListSearchDomainsResponse) __premarshalJSON() (*__premarshalListSearchDomainsResponse, error) { + var retval __premarshalListSearchDomainsResponse + + { + + dst := &retval.SearchDomains + src := v.SearchDomains + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalListSearchDomainsSearchDomainsSearchDomain( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ListSearchDomainsResponse.SearchDomains: %w", err) + } + } + } + return &retval, nil +} + +// ListSearchDomainsSearchDomainsRepository includes the requested fields of the GraphQL type Repository. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type ListSearchDomainsSearchDomainsRepository struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Name string `json:"name"` + // Common interface for Repositories and Views. + AutomaticSearch bool `json:"automaticSearch"` +} + +// GetTypename returns ListSearchDomainsSearchDomainsRepository.Typename, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsSearchDomainsRepository) GetTypename() *string { return v.Typename } + +// GetName returns ListSearchDomainsSearchDomainsRepository.Name, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsSearchDomainsRepository) GetName() string { return v.Name } + +// GetAutomaticSearch returns ListSearchDomainsSearchDomainsRepository.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsSearchDomainsRepository) GetAutomaticSearch() bool { + return v.AutomaticSearch +} + +// ListSearchDomainsSearchDomainsSearchDomain includes the requested fields of the GraphQL interface SearchDomain. +// +// ListSearchDomainsSearchDomainsSearchDomain is implemented by the following types: +// ListSearchDomainsSearchDomainsRepository +// ListSearchDomainsSearchDomainsView +// The GraphQL type's documentation follows. +// +// Common interface for Repositories and Views. +type ListSearchDomainsSearchDomainsSearchDomain interface { + implementsGraphQLInterfaceListSearchDomainsSearchDomainsSearchDomain() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + // GetName returns the interface-field "name" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetName() string + // GetAutomaticSearch returns the interface-field "automaticSearch" from its implementation. + // The GraphQL interface field's documentation follows. + // + // Common interface for Repositories and Views. + GetAutomaticSearch() bool +} + +func (v *ListSearchDomainsSearchDomainsRepository) implementsGraphQLInterfaceListSearchDomainsSearchDomainsSearchDomain() { +} +func (v *ListSearchDomainsSearchDomainsView) implementsGraphQLInterfaceListSearchDomainsSearchDomainsSearchDomain() { +} + +func __unmarshalListSearchDomainsSearchDomainsSearchDomain(b []byte, v *ListSearchDomainsSearchDomainsSearchDomain) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Repository": + *v = new(ListSearchDomainsSearchDomainsRepository) + return json.Unmarshal(b, *v) + case "View": + *v = new(ListSearchDomainsSearchDomainsView) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing SearchDomain.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ListSearchDomainsSearchDomainsSearchDomain: "%v"`, tn.TypeName) + } +} + +func __marshalListSearchDomainsSearchDomainsSearchDomain(v *ListSearchDomainsSearchDomainsSearchDomain) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ListSearchDomainsSearchDomainsRepository: + typename = "Repository" + + result := struct { + TypeName string `json:"__typename"` + *ListSearchDomainsSearchDomainsRepository + }{typename, v} + return json.Marshal(result) + case *ListSearchDomainsSearchDomainsView: + typename = "View" + + result := struct { + TypeName string `json:"__typename"` + *ListSearchDomainsSearchDomainsView + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ListSearchDomainsSearchDomainsSearchDomain: "%T"`, v) + } +} + +// ListSearchDomainsSearchDomainsView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type ListSearchDomainsSearchDomainsView struct { + Typename *string `json:"__typename"` + // Common interface for Repositories and Views. + Name string `json:"name"` + // Common interface for Repositories and Views. + AutomaticSearch bool `json:"automaticSearch"` +} + +// GetTypename returns ListSearchDomainsSearchDomainsView.Typename, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsSearchDomainsView) GetTypename() *string { return v.Typename } + +// GetName returns ListSearchDomainsSearchDomainsView.Name, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsSearchDomainsView) GetName() string { return v.Name } + +// GetAutomaticSearch returns ListSearchDomainsSearchDomainsView.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *ListSearchDomainsSearchDomainsView) GetAutomaticSearch() bool { return v.AutomaticSearch } + +// ParserDetails includes the GraphQL fields of Parser requested by the fragment ParserDetails. +// The GraphQL type's documentation follows. +// +// A configured parser for incoming data. +type ParserDetails struct { + // The id of the parser. + Id string `json:"id"` + // Name of the parser. + Name string `json:"name"` + // The parser script that is executed for every incoming event. + Script string `json:"script"` + // Fields that are used as tags. + FieldsToTag []string `json:"fieldsToTag"` + // Test cases that can be used to help verify that the parser works as expected. + TestCases []ParserDetailsTestCasesParserTestCase `json:"testCases"` +} + +// GetId returns ParserDetails.Id, and is useful for accessing the field via an interface. +func (v *ParserDetails) GetId() string { return v.Id } + +// GetName returns ParserDetails.Name, and is useful for accessing the field via an interface. +func (v *ParserDetails) GetName() string { return v.Name } + +// GetScript returns ParserDetails.Script, and is useful for accessing the field via an interface. +func (v *ParserDetails) GetScript() string { return v.Script } + +// GetFieldsToTag returns ParserDetails.FieldsToTag, and is useful for accessing the field via an interface. +func (v *ParserDetails) GetFieldsToTag() []string { return v.FieldsToTag } + +// GetTestCases returns ParserDetails.TestCases, and is useful for accessing the field via an interface. +func (v *ParserDetails) GetTestCases() []ParserDetailsTestCasesParserTestCase { return v.TestCases } + +// ParserDetailsTestCasesParserTestCase includes the requested fields of the GraphQL type ParserTestCase. +// The GraphQL type's documentation follows. +// +// A test case for a parser. +type ParserDetailsTestCasesParserTestCase struct { + // The event to parse and test on. + Event ParserDetailsTestCasesParserTestCaseEventParserTestEvent `json:"event"` + // Assertions on the shape of the test case output events. The list consists of key-value pairs to be treated as a map-construct, where the index of the output event is the key, and the assertions are the value. + OutputAssertions []ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput `json:"outputAssertions"` +} + +// GetEvent returns ParserDetailsTestCasesParserTestCase.Event, and is useful for accessing the field via an interface. +func (v *ParserDetailsTestCasesParserTestCase) GetEvent() ParserDetailsTestCasesParserTestCaseEventParserTestEvent { + return v.Event +} + +// GetOutputAssertions returns ParserDetailsTestCasesParserTestCase.OutputAssertions, and is useful for accessing the field via an interface. +func (v *ParserDetailsTestCasesParserTestCase) GetOutputAssertions() []ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput { + return v.OutputAssertions +} + +// ParserDetailsTestCasesParserTestCaseEventParserTestEvent includes the requested fields of the GraphQL type ParserTestEvent. +// The GraphQL type's documentation follows. +// +// An event for a parser to parse during testing. +type ParserDetailsTestCasesParserTestCaseEventParserTestEvent struct { + // The contents of the `@rawstring` field when the event begins parsing. + RawString string `json:"rawString"` +} + +// GetRawString returns ParserDetailsTestCasesParserTestCaseEventParserTestEvent.RawString, and is useful for accessing the field via an interface. +func (v *ParserDetailsTestCasesParserTestCaseEventParserTestEvent) GetRawString() string { + return v.RawString +} + +// ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput includes the requested fields of the GraphQL type ParserTestCaseAssertionsForOutput. +// The GraphQL type's documentation follows. +// +// Assertions on the shape of the given output event. It is a key-value pair, where the index of the output event is the key, and the assertions are the value. +type ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput.Typename, and is useful for accessing the field via an interface. +func (v *ParserDetailsTestCasesParserTestCaseOutputAssertionsParserTestCaseAssertionsForOutput) GetTypename() *string { + return v.Typename +} + +// Assertions on the shape of a given test case output event. It is a key-pair value, where the index of the output event is the key, and the assertions are the value. +type ParserTestCaseAssertionsForOutputInput struct { + // Assertions on the shape of a given test case output event. It is a key-pair value, where the index of the output event is the key, and the assertions are the value. + OutputEventIndex int `json:"outputEventIndex"` + // Assertions on the shape of a given test case output event. It is a key-pair value, where the index of the output event is the key, and the assertions are the value. + Assertions ParserTestCaseOutputAssertionsInput `json:"assertions"` +} + +// GetOutputEventIndex returns ParserTestCaseAssertionsForOutputInput.OutputEventIndex, and is useful for accessing the field via an interface. +func (v *ParserTestCaseAssertionsForOutputInput) GetOutputEventIndex() int { return v.OutputEventIndex } + +// GetAssertions returns ParserTestCaseAssertionsForOutputInput.Assertions, and is useful for accessing the field via an interface. +func (v *ParserTestCaseAssertionsForOutputInput) GetAssertions() ParserTestCaseOutputAssertionsInput { + return v.Assertions +} + +// A test case for a parser. +type ParserTestCaseInput struct { + // A test case for a parser. + Event ParserTestEventInput `json:"event"` + // A test case for a parser. + OutputAssertions []ParserTestCaseAssertionsForOutputInput `json:"outputAssertions"` +} + +// GetEvent returns ParserTestCaseInput.Event, and is useful for accessing the field via an interface. +func (v *ParserTestCaseInput) GetEvent() ParserTestEventInput { return v.Event } + +// GetOutputAssertions returns ParserTestCaseInput.OutputAssertions, and is useful for accessing the field via an interface. +func (v *ParserTestCaseInput) GetOutputAssertions() []ParserTestCaseAssertionsForOutputInput { + return v.OutputAssertions +} + +// Assertions on the shape of a given test case output event. +type ParserTestCaseOutputAssertionsInput struct { + // Assertions on the shape of a given test case output event. + FieldsNotPresent []string `json:"fieldsNotPresent"` + // Assertions on the shape of a given test case output event. + FieldsHaveValues []FieldHasValueInput `json:"fieldsHaveValues"` +} + +// GetFieldsNotPresent returns ParserTestCaseOutputAssertionsInput.FieldsNotPresent, and is useful for accessing the field via an interface. +func (v *ParserTestCaseOutputAssertionsInput) GetFieldsNotPresent() []string { + return v.FieldsNotPresent +} + +// GetFieldsHaveValues returns ParserTestCaseOutputAssertionsInput.FieldsHaveValues, and is useful for accessing the field via an interface. +func (v *ParserTestCaseOutputAssertionsInput) GetFieldsHaveValues() []FieldHasValueInput { + return v.FieldsHaveValues +} + +// An event for a parser to parse during testing. +type ParserTestEventInput struct { + // An event for a parser to parse during testing. + RawString string `json:"rawString"` +} + +// GetRawString returns ParserTestEventInput.RawString, and is useful for accessing the field via an interface. +func (v *ParserTestEventInput) GetRawString() string { return v.RawString } + +// QueryOwnership includes the GraphQL fields of QueryOwnership requested by the fragment QueryOwnership. +// The GraphQL type's documentation follows. +// +// # Query ownership +// +// QueryOwnership is implemented by the following types: +// QueryOwnershipOrganizationOwnership +// QueryOwnershipUserOwnership +type QueryOwnership interface { + implementsGraphQLInterfaceQueryOwnership() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string +} + +func (v *QueryOwnershipOrganizationOwnership) implementsGraphQLInterfaceQueryOwnership() {} +func (v *QueryOwnershipUserOwnership) implementsGraphQLInterfaceQueryOwnership() {} + +func __unmarshalQueryOwnership(b []byte, v *QueryOwnership) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "OrganizationOwnership": + *v = new(QueryOwnershipOrganizationOwnership) + return json.Unmarshal(b, *v) + case "UserOwnership": + *v = new(QueryOwnershipUserOwnership) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing QueryOwnership.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for QueryOwnership: "%v"`, tn.TypeName) + } +} + +func __marshalQueryOwnership(v *QueryOwnership) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *QueryOwnershipOrganizationOwnership: + typename = "OrganizationOwnership" + + result := struct { + TypeName string `json:"__typename"` + *QueryOwnershipOrganizationOwnership + }{typename, v} + return json.Marshal(result) + case *QueryOwnershipUserOwnership: + typename = "UserOwnership" + + result := struct { + TypeName string `json:"__typename"` + *QueryOwnershipUserOwnership + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for QueryOwnership: "%T"`, v) + } +} + +// QueryOwnership includes the GraphQL fields of OrganizationOwnership requested by the fragment QueryOwnership. +// The GraphQL type's documentation follows. +// +// Query ownership +type QueryOwnershipOrganizationOwnership struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns QueryOwnershipOrganizationOwnership.Typename, and is useful for accessing the field via an interface. +func (v *QueryOwnershipOrganizationOwnership) GetTypename() *string { return v.Typename } + +// The type of query ownership +type QueryOwnershipType string + +const ( + // Queries run on behalf of user + QueryOwnershipTypeUser QueryOwnershipType = "User" + // Queries run on behalf of the organization + QueryOwnershipTypeOrganization QueryOwnershipType = "Organization" +) + +// QueryOwnership includes the GraphQL fields of UserOwnership requested by the fragment QueryOwnership. +// The GraphQL type's documentation follows. +// +// Query ownership +type QueryOwnershipUserOwnership struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns QueryOwnershipUserOwnership.Typename, and is useful for accessing the field via an interface. +func (v *QueryOwnershipUserOwnership) GetTypename() *string { return v.Typename } + +// Timestamp type to use for a query. +type QueryTimestampType string + +const ( + // Use @timestamp for the query. + QueryTimestampTypeEventtimestamp QueryTimestampType = "EventTimestamp" + // Use @ingesttimestamp for the query. + QueryTimestampTypeIngesttimestamp QueryTimestampType = "IngestTimestamp" +) + +// RemoveIngestTokenRemoveIngestTokenBooleanResultType includes the requested fields of the GraphQL type BooleanResultType. +type RemoveIngestTokenRemoveIngestTokenBooleanResultType struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns RemoveIngestTokenRemoveIngestTokenBooleanResultType.Typename, and is useful for accessing the field via an interface. +func (v *RemoveIngestTokenRemoveIngestTokenBooleanResultType) GetTypename() *string { + return v.Typename +} + +// RemoveIngestTokenResponse is returned by RemoveIngestToken on success. +type RemoveIngestTokenResponse struct { + // Remove an Ingest Token. + RemoveIngestToken RemoveIngestTokenRemoveIngestTokenBooleanResultType `json:"removeIngestToken"` +} + +// GetRemoveIngestToken returns RemoveIngestTokenResponse.RemoveIngestToken, and is useful for accessing the field via an interface. +func (v *RemoveIngestTokenResponse) GetRemoveIngestToken() RemoveIngestTokenRemoveIngestTokenBooleanResultType { + return v.RemoveIngestToken +} + +// RepositoryDetails includes the GraphQL fields of Repository requested by the fragment RepositoryDetails. +// The GraphQL type's documentation follows. +// +// A repository stores ingested data, configures parsers and data retention policies. +type RepositoryDetails struct { + Id string `json:"id"` + Name string `json:"name"` + Description *string `json:"description"` + // The maximum time (in days) to keep data. Data old than this will be deleted. + TimeBasedRetention *float64 `json:"timeBasedRetention"` + // Retention (in Gigabytes) based on the size of data when it arrives to LogScale, that is before parsing and compression. LogScale will keep `at most` this amount of data. + IngestSizeBasedRetention *float64 `json:"ingestSizeBasedRetention"` + // Retention (in Gigabytes) based on the size of data when in storage, that is, after parsing and compression. LogScale will keep `at least` this amount of data, but as close to this number as possible. + StorageSizeBasedRetention *float64 `json:"storageSizeBasedRetention"` + // Total size of data. Size is measured as the size after compression. + CompressedByteSize int64 `json:"compressedByteSize"` + AutomaticSearch bool `json:"automaticSearch"` + // Configuration for S3 archiving. E.g. bucket name and region. + S3ArchivingConfiguration *RepositoryDetailsS3ArchivingConfigurationS3Configuration `json:"s3ArchivingConfiguration"` +} + +// GetId returns RepositoryDetails.Id, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetId() string { return v.Id } + +// GetName returns RepositoryDetails.Name, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetName() string { return v.Name } + +// GetDescription returns RepositoryDetails.Description, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetDescription() *string { return v.Description } + +// GetTimeBasedRetention returns RepositoryDetails.TimeBasedRetention, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetTimeBasedRetention() *float64 { return v.TimeBasedRetention } + +// GetIngestSizeBasedRetention returns RepositoryDetails.IngestSizeBasedRetention, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetIngestSizeBasedRetention() *float64 { return v.IngestSizeBasedRetention } + +// GetStorageSizeBasedRetention returns RepositoryDetails.StorageSizeBasedRetention, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetStorageSizeBasedRetention() *float64 { + return v.StorageSizeBasedRetention +} + +// GetCompressedByteSize returns RepositoryDetails.CompressedByteSize, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetCompressedByteSize() int64 { return v.CompressedByteSize } + +// GetAutomaticSearch returns RepositoryDetails.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetAutomaticSearch() bool { return v.AutomaticSearch } + +// GetS3ArchivingConfiguration returns RepositoryDetails.S3ArchivingConfiguration, and is useful for accessing the field via an interface. +func (v *RepositoryDetails) GetS3ArchivingConfiguration() *RepositoryDetailsS3ArchivingConfigurationS3Configuration { + return v.S3ArchivingConfiguration +} + +// RepositoryDetailsS3ArchivingConfigurationS3Configuration includes the requested fields of the GraphQL type S3Configuration. +// The GraphQL type's documentation follows. +// +// Configuration for S3 archiving. E.g. bucket name and region. +type RepositoryDetailsS3ArchivingConfigurationS3Configuration struct { + // S3 bucket name for storing archived data. Example: acme-bucket. + Bucket string `json:"bucket"` + // The region the S3 bucket belongs to. Example: eu-central-1. + Region string `json:"region"` + // Whether the archiving has been disabled. + Disabled *bool `json:"disabled"` + // The format to store the archived data in on S3. + Format *S3ArchivingFormat `json:"format"` +} + +// GetBucket returns RepositoryDetailsS3ArchivingConfigurationS3Configuration.Bucket, and is useful for accessing the field via an interface. +func (v *RepositoryDetailsS3ArchivingConfigurationS3Configuration) GetBucket() string { + return v.Bucket +} + +// GetRegion returns RepositoryDetailsS3ArchivingConfigurationS3Configuration.Region, and is useful for accessing the field via an interface. +func (v *RepositoryDetailsS3ArchivingConfigurationS3Configuration) GetRegion() string { + return v.Region +} + +// GetDisabled returns RepositoryDetailsS3ArchivingConfigurationS3Configuration.Disabled, and is useful for accessing the field via an interface. +func (v *RepositoryDetailsS3ArchivingConfigurationS3Configuration) GetDisabled() *bool { + return v.Disabled +} + +// GetFormat returns RepositoryDetailsS3ArchivingConfigurationS3Configuration.Format, and is useful for accessing the field via an interface. +func (v *RepositoryDetailsS3ArchivingConfigurationS3Configuration) GetFormat() *S3ArchivingFormat { + return v.Format +} + +// RotateTokenByIDResponse is returned by RotateTokenByID on success. +type RotateTokenByIDResponse struct { + // Rotate a token + RotateToken string `json:"rotateToken"` +} + +// GetRotateToken returns RotateTokenByIDResponse.RotateToken, and is useful for accessing the field via an interface. +func (v *RotateTokenByIDResponse) GetRotateToken() string { return v.RotateToken } + +// The format to store archived segments in on AWS S3. +type S3ArchivingFormat string + +const ( + S3ArchivingFormatRaw S3ArchivingFormat = "RAW" + S3ArchivingFormatNdjson S3ArchivingFormat = "NDJSON" +) + +// ScheduledSearchDetails includes the GraphQL fields of ScheduledSearch requested by the fragment ScheduledSearchDetails. +// The GraphQL type's documentation follows. +// +// Information about a scheduled search +type ScheduledSearchDetails struct { + // Id of the scheduled search. + Id string `json:"id"` + // Name of the scheduled search. + Name string `json:"name"` + // Description of the scheduled search. + Description *string `json:"description"` + // LogScale query to execute. + QueryString string `json:"queryString"` + // Start of the relative time interval for the query. + Start string `json:"start"` + // End of the relative time interval for the query. + End string `json:"end"` + // Time zone of the schedule. Currently this field only supports UTC offsets like 'UTC', 'UTC-01' or 'UTC+12:45'. + TimeZone string `json:"timeZone"` + // Cron pattern describing the schedule to execute the query on. + Schedule string `json:"schedule"` + // User-defined limit, which caps the number of missed searches to backfill, e.g. in the event of a shutdown. + BackfillLimit int `json:"backfillLimit"` + // Flag indicating whether the scheduled search is enabled. + Enabled bool `json:"enabled"` + // Labels added to the scheduled search. + Labels []string `json:"labels"` + // List of actions to fire on query result. + ActionsV2 []SharedActionNameType `json:"-"` + // Ownership of the query run by this scheduled search + QueryOwnership SharedQueryOwnershipType `json:"-"` +} + +// GetId returns ScheduledSearchDetails.Id, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetId() string { return v.Id } + +// GetName returns ScheduledSearchDetails.Name, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetName() string { return v.Name } + +// GetDescription returns ScheduledSearchDetails.Description, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetDescription() *string { return v.Description } + +// GetQueryString returns ScheduledSearchDetails.QueryString, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetQueryString() string { return v.QueryString } + +// GetStart returns ScheduledSearchDetails.Start, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetStart() string { return v.Start } + +// GetEnd returns ScheduledSearchDetails.End, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetEnd() string { return v.End } + +// GetTimeZone returns ScheduledSearchDetails.TimeZone, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetTimeZone() string { return v.TimeZone } + +// GetSchedule returns ScheduledSearchDetails.Schedule, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetSchedule() string { return v.Schedule } + +// GetBackfillLimit returns ScheduledSearchDetails.BackfillLimit, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetBackfillLimit() int { return v.BackfillLimit } + +// GetEnabled returns ScheduledSearchDetails.Enabled, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetEnabled() bool { return v.Enabled } + +// GetLabels returns ScheduledSearchDetails.Labels, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetLabels() []string { return v.Labels } + +// GetActionsV2 returns ScheduledSearchDetails.ActionsV2, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetActionsV2() []SharedActionNameType { return v.ActionsV2 } + +// GetQueryOwnership returns ScheduledSearchDetails.QueryOwnership, and is useful for accessing the field via an interface. +func (v *ScheduledSearchDetails) GetQueryOwnership() SharedQueryOwnershipType { + return v.QueryOwnership +} + +func (v *ScheduledSearchDetails) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ScheduledSearchDetails + ActionsV2 []json.RawMessage `json:"actionsV2"` + QueryOwnership json.RawMessage `json:"queryOwnership"` + graphql.NoUnmarshalJSON + } + firstPass.ScheduledSearchDetails = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.ActionsV2 + src := firstPass.ActionsV2 + *dst = make( + []SharedActionNameType, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedActionNameType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ScheduledSearchDetails.ActionsV2: %w", err) + } + } + } + } + + { + dst := &v.QueryOwnership + src := firstPass.QueryOwnership + if len(src) != 0 && string(src) != "null" { + err = __unmarshalSharedQueryOwnershipType( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal ScheduledSearchDetails.QueryOwnership: %w", err) + } + } + } + return nil +} + +type __premarshalScheduledSearchDetails struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + Start string `json:"start"` + + End string `json:"end"` + + TimeZone string `json:"timeZone"` + + Schedule string `json:"schedule"` + + BackfillLimit int `json:"backfillLimit"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *ScheduledSearchDetails) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ScheduledSearchDetails) __premarshalJSON() (*__premarshalScheduledSearchDetails, error) { + var retval __premarshalScheduledSearchDetails + + retval.Id = v.Id + retval.Name = v.Name + retval.Description = v.Description + retval.QueryString = v.QueryString + retval.Start = v.Start + retval.End = v.End + retval.TimeZone = v.TimeZone + retval.Schedule = v.Schedule + retval.BackfillLimit = v.BackfillLimit + retval.Enabled = v.Enabled + retval.Labels = v.Labels + { + + dst := &retval.ActionsV2 + src := v.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ScheduledSearchDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal ScheduledSearchDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// SetAutomaticSearchingResponse is returned by SetAutomaticSearching on success. +type SetAutomaticSearchingResponse struct { + // Automatically search when arriving at the search page + SetAutomaticSearching SetAutomaticSearchingSetAutomaticSearching `json:"setAutomaticSearching"` +} + +// GetSetAutomaticSearching returns SetAutomaticSearchingResponse.SetAutomaticSearching, and is useful for accessing the field via an interface. +func (v *SetAutomaticSearchingResponse) GetSetAutomaticSearching() SetAutomaticSearchingSetAutomaticSearching { + return v.SetAutomaticSearching +} + +// SetAutomaticSearchingSetAutomaticSearching includes the requested fields of the GraphQL type setAutomaticSearching. +type SetAutomaticSearchingSetAutomaticSearching struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns SetAutomaticSearchingSetAutomaticSearching.Typename, and is useful for accessing the field via an interface. +func (v *SetAutomaticSearchingSetAutomaticSearching) GetTypename() *string { return v.Typename } + +// SharedActionNameType includes the requested fields of the GraphQL interface Action. +// +// SharedActionNameType is implemented by the following types: +// SharedActionNameTypeEmailAction +// SharedActionNameTypeHumioRepoAction +// SharedActionNameTypeOpsGenieAction +// SharedActionNameTypePagerDutyAction +// SharedActionNameTypeSlackAction +// SharedActionNameTypeSlackPostMessageAction +// SharedActionNameTypeUploadFileAction +// SharedActionNameTypeVictorOpsAction +// SharedActionNameTypeWebhookAction +// The GraphQL type's documentation follows. +// +// An action that can be invoked from a trigger. +type SharedActionNameType interface { + implementsGraphQLInterfaceSharedActionNameType() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + ActionName +} + +func (v *SharedActionNameTypeEmailAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypeHumioRepoAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypeOpsGenieAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypePagerDutyAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypeSlackAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypeSlackPostMessageAction) implementsGraphQLInterfaceSharedActionNameType() { +} +func (v *SharedActionNameTypeUploadFileAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypeVictorOpsAction) implementsGraphQLInterfaceSharedActionNameType() {} +func (v *SharedActionNameTypeWebhookAction) implementsGraphQLInterfaceSharedActionNameType() {} + +func __unmarshalSharedActionNameType(b []byte, v *SharedActionNameType) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "EmailAction": + *v = new(SharedActionNameTypeEmailAction) + return json.Unmarshal(b, *v) + case "HumioRepoAction": + *v = new(SharedActionNameTypeHumioRepoAction) + return json.Unmarshal(b, *v) + case "OpsGenieAction": + *v = new(SharedActionNameTypeOpsGenieAction) + return json.Unmarshal(b, *v) + case "PagerDutyAction": + *v = new(SharedActionNameTypePagerDutyAction) + return json.Unmarshal(b, *v) + case "SlackAction": + *v = new(SharedActionNameTypeSlackAction) + return json.Unmarshal(b, *v) + case "SlackPostMessageAction": + *v = new(SharedActionNameTypeSlackPostMessageAction) + return json.Unmarshal(b, *v) + case "UploadFileAction": + *v = new(SharedActionNameTypeUploadFileAction) + return json.Unmarshal(b, *v) + case "VictorOpsAction": + *v = new(SharedActionNameTypeVictorOpsAction) + return json.Unmarshal(b, *v) + case "WebhookAction": + *v = new(SharedActionNameTypeWebhookAction) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Action.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for SharedActionNameType: "%v"`, tn.TypeName) + } +} + +func __marshalSharedActionNameType(v *SharedActionNameType) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *SharedActionNameTypeEmailAction: + typename = "EmailAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeEmailAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeHumioRepoAction: + typename = "HumioRepoAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeHumioRepoAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeOpsGenieAction: + typename = "OpsGenieAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeOpsGenieAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypePagerDutyAction: + typename = "PagerDutyAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypePagerDutyAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeSlackAction: + typename = "SlackAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeSlackAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeSlackPostMessageAction: + typename = "SlackPostMessageAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeSlackPostMessageAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeUploadFileAction: + typename = "UploadFileAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeUploadFileAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeVictorOpsAction: + typename = "VictorOpsAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeVictorOpsAction + }{typename, premarshaled} + return json.Marshal(result) + case *SharedActionNameTypeWebhookAction: + typename = "WebhookAction" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedActionNameTypeWebhookAction + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for SharedActionNameType: "%T"`, v) + } +} + +// SharedActionNameTypeEmailAction includes the requested fields of the GraphQL type EmailAction. +// The GraphQL type's documentation follows. +// +// An email action. +type SharedActionNameTypeEmailAction struct { + Typename *string `json:"__typename"` + ActionNameEmailAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeEmailAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeEmailAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeEmailAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeEmailAction) GetName() string { return v.ActionNameEmailAction.Name } + +func (v *SharedActionNameTypeEmailAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeEmailAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeEmailAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameEmailAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeEmailAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeEmailAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeEmailAction) __premarshalJSON() (*__premarshalSharedActionNameTypeEmailAction, error) { + var retval __premarshalSharedActionNameTypeEmailAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameEmailAction.Name + return &retval, nil +} + +// SharedActionNameTypeHumioRepoAction includes the requested fields of the GraphQL type HumioRepoAction. +// The GraphQL type's documentation follows. +// +// A LogScale repository action. +type SharedActionNameTypeHumioRepoAction struct { + Typename *string `json:"__typename"` + ActionNameHumioRepoAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeHumioRepoAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeHumioRepoAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeHumioRepoAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeHumioRepoAction) GetName() string { + return v.ActionNameHumioRepoAction.Name +} + +func (v *SharedActionNameTypeHumioRepoAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeHumioRepoAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeHumioRepoAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameHumioRepoAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeHumioRepoAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeHumioRepoAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeHumioRepoAction) __premarshalJSON() (*__premarshalSharedActionNameTypeHumioRepoAction, error) { + var retval __premarshalSharedActionNameTypeHumioRepoAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameHumioRepoAction.Name + return &retval, nil +} + +// SharedActionNameTypeOpsGenieAction includes the requested fields of the GraphQL type OpsGenieAction. +// The GraphQL type's documentation follows. +// +// An OpsGenie action +type SharedActionNameTypeOpsGenieAction struct { + Typename *string `json:"__typename"` + ActionNameOpsGenieAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeOpsGenieAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeOpsGenieAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeOpsGenieAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeOpsGenieAction) GetName() string { return v.ActionNameOpsGenieAction.Name } + +func (v *SharedActionNameTypeOpsGenieAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeOpsGenieAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeOpsGenieAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameOpsGenieAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeOpsGenieAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeOpsGenieAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeOpsGenieAction) __premarshalJSON() (*__premarshalSharedActionNameTypeOpsGenieAction, error) { + var retval __premarshalSharedActionNameTypeOpsGenieAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameOpsGenieAction.Name + return &retval, nil +} + +// SharedActionNameTypePagerDutyAction includes the requested fields of the GraphQL type PagerDutyAction. +// The GraphQL type's documentation follows. +// +// A PagerDuty action. +type SharedActionNameTypePagerDutyAction struct { + Typename *string `json:"__typename"` + ActionNamePagerDutyAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypePagerDutyAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypePagerDutyAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypePagerDutyAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypePagerDutyAction) GetName() string { + return v.ActionNamePagerDutyAction.Name +} + +func (v *SharedActionNameTypePagerDutyAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypePagerDutyAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypePagerDutyAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNamePagerDutyAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypePagerDutyAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypePagerDutyAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypePagerDutyAction) __premarshalJSON() (*__premarshalSharedActionNameTypePagerDutyAction, error) { + var retval __premarshalSharedActionNameTypePagerDutyAction + + retval.Typename = v.Typename + retval.Name = v.ActionNamePagerDutyAction.Name + return &retval, nil +} + +// SharedActionNameTypeSlackAction includes the requested fields of the GraphQL type SlackAction. +// The GraphQL type's documentation follows. +// +// A Slack action +type SharedActionNameTypeSlackAction struct { + Typename *string `json:"__typename"` + ActionNameSlackAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeSlackAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeSlackAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeSlackAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeSlackAction) GetName() string { return v.ActionNameSlackAction.Name } + +func (v *SharedActionNameTypeSlackAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeSlackAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeSlackAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameSlackAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeSlackAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeSlackAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeSlackAction) __premarshalJSON() (*__premarshalSharedActionNameTypeSlackAction, error) { + var retval __premarshalSharedActionNameTypeSlackAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameSlackAction.Name + return &retval, nil +} + +// SharedActionNameTypeSlackPostMessageAction includes the requested fields of the GraphQL type SlackPostMessageAction. +// The GraphQL type's documentation follows. +// +// A slack post-message action. +type SharedActionNameTypeSlackPostMessageAction struct { + Typename *string `json:"__typename"` + ActionNameSlackPostMessageAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeSlackPostMessageAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeSlackPostMessageAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeSlackPostMessageAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeSlackPostMessageAction) GetName() string { + return v.ActionNameSlackPostMessageAction.Name +} + +func (v *SharedActionNameTypeSlackPostMessageAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeSlackPostMessageAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeSlackPostMessageAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameSlackPostMessageAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeSlackPostMessageAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeSlackPostMessageAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeSlackPostMessageAction) __premarshalJSON() (*__premarshalSharedActionNameTypeSlackPostMessageAction, error) { + var retval __premarshalSharedActionNameTypeSlackPostMessageAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameSlackPostMessageAction.Name + return &retval, nil +} + +// SharedActionNameTypeUploadFileAction includes the requested fields of the GraphQL type UploadFileAction. +// The GraphQL type's documentation follows. +// +// An upload file action. +type SharedActionNameTypeUploadFileAction struct { + Typename *string `json:"__typename"` + ActionNameUploadFileAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeUploadFileAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeUploadFileAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeUploadFileAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeUploadFileAction) GetName() string { + return v.ActionNameUploadFileAction.Name +} + +func (v *SharedActionNameTypeUploadFileAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeUploadFileAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeUploadFileAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameUploadFileAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeUploadFileAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeUploadFileAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeUploadFileAction) __premarshalJSON() (*__premarshalSharedActionNameTypeUploadFileAction, error) { + var retval __premarshalSharedActionNameTypeUploadFileAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameUploadFileAction.Name + return &retval, nil +} + +// SharedActionNameTypeVictorOpsAction includes the requested fields of the GraphQL type VictorOpsAction. +// The GraphQL type's documentation follows. +// +// A VictorOps action. +type SharedActionNameTypeVictorOpsAction struct { + Typename *string `json:"__typename"` + ActionNameVictorOpsAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeVictorOpsAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeVictorOpsAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeVictorOpsAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeVictorOpsAction) GetName() string { + return v.ActionNameVictorOpsAction.Name +} + +func (v *SharedActionNameTypeVictorOpsAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeVictorOpsAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeVictorOpsAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameVictorOpsAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeVictorOpsAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeVictorOpsAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeVictorOpsAction) __premarshalJSON() (*__premarshalSharedActionNameTypeVictorOpsAction, error) { + var retval __premarshalSharedActionNameTypeVictorOpsAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameVictorOpsAction.Name + return &retval, nil +} + +// SharedActionNameTypeWebhookAction includes the requested fields of the GraphQL type WebhookAction. +// The GraphQL type's documentation follows. +// +// A webhook action +type SharedActionNameTypeWebhookAction struct { + Typename *string `json:"__typename"` + ActionNameWebhookAction `json:"-"` +} + +// GetTypename returns SharedActionNameTypeWebhookAction.Typename, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeWebhookAction) GetTypename() *string { return v.Typename } + +// GetName returns SharedActionNameTypeWebhookAction.Name, and is useful for accessing the field via an interface. +func (v *SharedActionNameTypeWebhookAction) GetName() string { return v.ActionNameWebhookAction.Name } + +func (v *SharedActionNameTypeWebhookAction) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedActionNameTypeWebhookAction + graphql.NoUnmarshalJSON + } + firstPass.SharedActionNameTypeWebhookAction = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ActionNameWebhookAction) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedActionNameTypeWebhookAction struct { + Typename *string `json:"__typename"` + + Name string `json:"name"` +} + +func (v *SharedActionNameTypeWebhookAction) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedActionNameTypeWebhookAction) __premarshalJSON() (*__premarshalSharedActionNameTypeWebhookAction, error) { + var retval __premarshalSharedActionNameTypeWebhookAction + + retval.Typename = v.Typename + retval.Name = v.ActionNameWebhookAction.Name + return &retval, nil +} + +// SharedQueryOwnershipType includes the requested fields of the GraphQL interface QueryOwnership. +// +// SharedQueryOwnershipType is implemented by the following types: +// SharedQueryOwnershipTypeOrganizationOwnership +// SharedQueryOwnershipTypeUserOwnership +// The GraphQL type's documentation follows. +// +// Query ownership +type SharedQueryOwnershipType interface { + implementsGraphQLInterfaceSharedQueryOwnershipType() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string + QueryOwnership +} + +func (v *SharedQueryOwnershipTypeOrganizationOwnership) implementsGraphQLInterfaceSharedQueryOwnershipType() { +} +func (v *SharedQueryOwnershipTypeUserOwnership) implementsGraphQLInterfaceSharedQueryOwnershipType() { +} + +func __unmarshalSharedQueryOwnershipType(b []byte, v *SharedQueryOwnershipType) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "OrganizationOwnership": + *v = new(SharedQueryOwnershipTypeOrganizationOwnership) + return json.Unmarshal(b, *v) + case "UserOwnership": + *v = new(SharedQueryOwnershipTypeUserOwnership) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing QueryOwnership.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for SharedQueryOwnershipType: "%v"`, tn.TypeName) + } +} + +func __marshalSharedQueryOwnershipType(v *SharedQueryOwnershipType) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *SharedQueryOwnershipTypeOrganizationOwnership: + typename = "OrganizationOwnership" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedQueryOwnershipTypeOrganizationOwnership + }{typename, premarshaled} + return json.Marshal(result) + case *SharedQueryOwnershipTypeUserOwnership: + typename = "UserOwnership" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalSharedQueryOwnershipTypeUserOwnership + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for SharedQueryOwnershipType: "%T"`, v) + } +} + +// SharedQueryOwnershipTypeOrganizationOwnership includes the requested fields of the GraphQL type OrganizationOwnership. +// The GraphQL type's documentation follows. +// +// Query running with organization based ownership +type SharedQueryOwnershipTypeOrganizationOwnership struct { + Typename *string `json:"__typename"` + QueryOwnershipOrganizationOwnership `json:"-"` +} + +// GetTypename returns SharedQueryOwnershipTypeOrganizationOwnership.Typename, and is useful for accessing the field via an interface. +func (v *SharedQueryOwnershipTypeOrganizationOwnership) GetTypename() *string { return v.Typename } + +func (v *SharedQueryOwnershipTypeOrganizationOwnership) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedQueryOwnershipTypeOrganizationOwnership + graphql.NoUnmarshalJSON + } + firstPass.SharedQueryOwnershipTypeOrganizationOwnership = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.QueryOwnershipOrganizationOwnership) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedQueryOwnershipTypeOrganizationOwnership struct { + Typename *string `json:"__typename"` +} + +func (v *SharedQueryOwnershipTypeOrganizationOwnership) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedQueryOwnershipTypeOrganizationOwnership) __premarshalJSON() (*__premarshalSharedQueryOwnershipTypeOrganizationOwnership, error) { + var retval __premarshalSharedQueryOwnershipTypeOrganizationOwnership + + retval.Typename = v.Typename + return &retval, nil +} + +// SharedQueryOwnershipTypeUserOwnership includes the requested fields of the GraphQL type UserOwnership. +// The GraphQL type's documentation follows. +// +// Query running with user based ownership +type SharedQueryOwnershipTypeUserOwnership struct { + Typename *string `json:"__typename"` + QueryOwnershipUserOwnership `json:"-"` +} + +// GetTypename returns SharedQueryOwnershipTypeUserOwnership.Typename, and is useful for accessing the field via an interface. +func (v *SharedQueryOwnershipTypeUserOwnership) GetTypename() *string { return v.Typename } + +func (v *SharedQueryOwnershipTypeUserOwnership) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *SharedQueryOwnershipTypeUserOwnership + graphql.NoUnmarshalJSON + } + firstPass.SharedQueryOwnershipTypeUserOwnership = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.QueryOwnershipUserOwnership) + if err != nil { + return err + } + return nil +} + +type __premarshalSharedQueryOwnershipTypeUserOwnership struct { + Typename *string `json:"__typename"` +} + +func (v *SharedQueryOwnershipTypeUserOwnership) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *SharedQueryOwnershipTypeUserOwnership) __premarshalJSON() (*__premarshalSharedQueryOwnershipTypeUserOwnership, error) { + var retval __premarshalSharedQueryOwnershipTypeUserOwnership + + retval.Typename = v.Typename + return &retval, nil +} + +// Slack message field entry. +type SlackFieldEntryInput struct { + // Slack message field entry. + FieldName string `json:"fieldName"` + // Slack message field entry. + Value string `json:"value"` +} + +// GetFieldName returns SlackFieldEntryInput.FieldName, and is useful for accessing the field via an interface. +func (v *SlackFieldEntryInput) GetFieldName() string { return v.FieldName } + +// GetValue returns SlackFieldEntryInput.Value, and is useful for accessing the field via an interface. +func (v *SlackFieldEntryInput) GetValue() string { return v.Value } + +// Trigger mode for an aggregate alert. +type TriggerMode string + +const ( + // Wait for up to 20 minutes for a complete result before triggering. + TriggerModeCompletemode TriggerMode = "CompleteMode" + // Trigger immediately, even on incomplete results. If nothing to trigger on, wait for up to 20 minutes for there to be a result to trigger on. + TriggerModeImmediatemode TriggerMode = "ImmediateMode" +) + +// UnassignParserToIngestTokenResponse is returned by UnassignParserToIngestToken on success. +type UnassignParserToIngestTokenResponse struct { + // Un-associates a token with its currently assigned parser. + UnassignIngestToken UnassignParserToIngestTokenUnassignIngestTokenUnassignIngestTokenMutation `json:"unassignIngestToken"` +} + +// GetUnassignIngestToken returns UnassignParserToIngestTokenResponse.UnassignIngestToken, and is useful for accessing the field via an interface. +func (v *UnassignParserToIngestTokenResponse) GetUnassignIngestToken() UnassignParserToIngestTokenUnassignIngestTokenUnassignIngestTokenMutation { + return v.UnassignIngestToken +} + +// UnassignParserToIngestTokenUnassignIngestTokenUnassignIngestTokenMutation includes the requested fields of the GraphQL type UnassignIngestTokenMutation. +type UnassignParserToIngestTokenUnassignIngestTokenUnassignIngestTokenMutation struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UnassignParserToIngestTokenUnassignIngestTokenUnassignIngestTokenMutation.Typename, and is useful for accessing the field via an interface. +func (v *UnassignParserToIngestTokenUnassignIngestTokenUnassignIngestTokenMutation) GetTypename() *string { + return v.Typename +} + +// UpdateAggregateAlertResponse is returned by UpdateAggregateAlert on success. +type UpdateAggregateAlertResponse struct { + // Update an aggregate alert. + UpdateAggregateAlert UpdateAggregateAlertUpdateAggregateAlert `json:"updateAggregateAlert"` +} + +// GetUpdateAggregateAlert returns UpdateAggregateAlertResponse.UpdateAggregateAlert, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertResponse) GetUpdateAggregateAlert() UpdateAggregateAlertUpdateAggregateAlert { + return v.UpdateAggregateAlert +} + +// UpdateAggregateAlertUpdateAggregateAlert includes the requested fields of the GraphQL type AggregateAlert. +// The GraphQL type's documentation follows. +// +// An aggregate alert. +type UpdateAggregateAlertUpdateAggregateAlert struct { + AggregateAlertDetails `json:"-"` +} + +// GetId returns UpdateAggregateAlertUpdateAggregateAlert.Id, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetId() string { return v.AggregateAlertDetails.Id } + +// GetName returns UpdateAggregateAlertUpdateAggregateAlert.Name, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetName() string { + return v.AggregateAlertDetails.Name +} + +// GetDescription returns UpdateAggregateAlertUpdateAggregateAlert.Description, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetDescription() *string { + return v.AggregateAlertDetails.Description +} + +// GetQueryString returns UpdateAggregateAlertUpdateAggregateAlert.QueryString, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetQueryString() string { + return v.AggregateAlertDetails.QueryString +} + +// GetSearchIntervalSeconds returns UpdateAggregateAlertUpdateAggregateAlert.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetSearchIntervalSeconds() int64 { + return v.AggregateAlertDetails.SearchIntervalSeconds +} + +// GetThrottleTimeSeconds returns UpdateAggregateAlertUpdateAggregateAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetThrottleTimeSeconds() int64 { + return v.AggregateAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns UpdateAggregateAlertUpdateAggregateAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetThrottleField() *string { + return v.AggregateAlertDetails.ThrottleField +} + +// GetLabels returns UpdateAggregateAlertUpdateAggregateAlert.Labels, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetLabels() []string { + return v.AggregateAlertDetails.Labels +} + +// GetEnabled returns UpdateAggregateAlertUpdateAggregateAlert.Enabled, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetEnabled() bool { + return v.AggregateAlertDetails.Enabled +} + +// GetTriggerMode returns UpdateAggregateAlertUpdateAggregateAlert.TriggerMode, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetTriggerMode() TriggerMode { + return v.AggregateAlertDetails.TriggerMode +} + +// GetQueryTimestampType returns UpdateAggregateAlertUpdateAggregateAlert.QueryTimestampType, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetQueryTimestampType() QueryTimestampType { + return v.AggregateAlertDetails.QueryTimestampType +} + +// GetActions returns UpdateAggregateAlertUpdateAggregateAlert.Actions, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetActions() []SharedActionNameType { + return v.AggregateAlertDetails.Actions +} + +// GetQueryOwnership returns UpdateAggregateAlertUpdateAggregateAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *UpdateAggregateAlertUpdateAggregateAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AggregateAlertDetails.QueryOwnership +} + +func (v *UpdateAggregateAlertUpdateAggregateAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateAggregateAlertUpdateAggregateAlert + graphql.NoUnmarshalJSON + } + firstPass.UpdateAggregateAlertUpdateAggregateAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AggregateAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalUpdateAggregateAlertUpdateAggregateAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + SearchIntervalSeconds int64 `json:"searchIntervalSeconds"` + + ThrottleTimeSeconds int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + TriggerMode TriggerMode `json:"triggerMode"` + + QueryTimestampType QueryTimestampType `json:"queryTimestampType"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *UpdateAggregateAlertUpdateAggregateAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateAggregateAlertUpdateAggregateAlert) __premarshalJSON() (*__premarshalUpdateAggregateAlertUpdateAggregateAlert, error) { + var retval __premarshalUpdateAggregateAlertUpdateAggregateAlert + + retval.Id = v.AggregateAlertDetails.Id + retval.Name = v.AggregateAlertDetails.Name + retval.Description = v.AggregateAlertDetails.Description + retval.QueryString = v.AggregateAlertDetails.QueryString + retval.SearchIntervalSeconds = v.AggregateAlertDetails.SearchIntervalSeconds + retval.ThrottleTimeSeconds = v.AggregateAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.AggregateAlertDetails.ThrottleField + retval.Labels = v.AggregateAlertDetails.Labels + retval.Enabled = v.AggregateAlertDetails.Enabled + retval.TriggerMode = v.AggregateAlertDetails.TriggerMode + retval.QueryTimestampType = v.AggregateAlertDetails.QueryTimestampType + { + + dst := &retval.Actions + src := v.AggregateAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateAggregateAlertUpdateAggregateAlert.AggregateAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AggregateAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateAggregateAlertUpdateAggregateAlert.AggregateAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// UpdateAlertResponse is returned by UpdateAlert on success. +type UpdateAlertResponse struct { + // Update an alert. + UpdateAlert UpdateAlertUpdateAlert `json:"updateAlert"` +} + +// GetUpdateAlert returns UpdateAlertResponse.UpdateAlert, and is useful for accessing the field via an interface. +func (v *UpdateAlertResponse) GetUpdateAlert() UpdateAlertUpdateAlert { return v.UpdateAlert } + +// UpdateAlertUpdateAlert includes the requested fields of the GraphQL type Alert. +// The GraphQL type's documentation follows. +// +// An alert. +type UpdateAlertUpdateAlert struct { + AlertDetails `json:"-"` +} + +// GetId returns UpdateAlertUpdateAlert.Id, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetId() string { return v.AlertDetails.Id } + +// GetName returns UpdateAlertUpdateAlert.Name, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetName() string { return v.AlertDetails.Name } + +// GetQueryString returns UpdateAlertUpdateAlert.QueryString, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetQueryString() string { return v.AlertDetails.QueryString } + +// GetQueryStart returns UpdateAlertUpdateAlert.QueryStart, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetQueryStart() string { return v.AlertDetails.QueryStart } + +// GetThrottleField returns UpdateAlertUpdateAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetThrottleField() *string { return v.AlertDetails.ThrottleField } + +// GetDescription returns UpdateAlertUpdateAlert.Description, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetDescription() *string { return v.AlertDetails.Description } + +// GetThrottleTimeMillis returns UpdateAlertUpdateAlert.ThrottleTimeMillis, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetThrottleTimeMillis() int64 { + return v.AlertDetails.ThrottleTimeMillis +} + +// GetEnabled returns UpdateAlertUpdateAlert.Enabled, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetEnabled() bool { return v.AlertDetails.Enabled } + +// GetLabels returns UpdateAlertUpdateAlert.Labels, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetLabels() []string { return v.AlertDetails.Labels } + +// GetActionsV2 returns UpdateAlertUpdateAlert.ActionsV2, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetActionsV2() []SharedActionNameType { + return v.AlertDetails.ActionsV2 +} + +// GetQueryOwnership returns UpdateAlertUpdateAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *UpdateAlertUpdateAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.AlertDetails.QueryOwnership +} + +func (v *UpdateAlertUpdateAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateAlertUpdateAlert + graphql.NoUnmarshalJSON + } + firstPass.UpdateAlertUpdateAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.AlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalUpdateAlertUpdateAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + QueryString string `json:"queryString"` + + QueryStart string `json:"queryStart"` + + ThrottleField *string `json:"throttleField"` + + Description *string `json:"description"` + + ThrottleTimeMillis int64 `json:"throttleTimeMillis"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *UpdateAlertUpdateAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateAlertUpdateAlert) __premarshalJSON() (*__premarshalUpdateAlertUpdateAlert, error) { + var retval __premarshalUpdateAlertUpdateAlert + + retval.Id = v.AlertDetails.Id + retval.Name = v.AlertDetails.Name + retval.QueryString = v.AlertDetails.QueryString + retval.QueryStart = v.AlertDetails.QueryStart + retval.ThrottleField = v.AlertDetails.ThrottleField + retval.Description = v.AlertDetails.Description + retval.ThrottleTimeMillis = v.AlertDetails.ThrottleTimeMillis + retval.Enabled = v.AlertDetails.Enabled + retval.Labels = v.AlertDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.AlertDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateAlertUpdateAlert.AlertDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.AlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateAlertUpdateAlert.AlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// UpdateDescriptionForSearchDomainResponse is returned by UpdateDescriptionForSearchDomain on success. +type UpdateDescriptionForSearchDomainResponse struct { + UpdateDescriptionForSearchDomain UpdateDescriptionForSearchDomainUpdateDescriptionForSearchDomainUpdateDescriptionMutation `json:"updateDescriptionForSearchDomain"` +} + +// GetUpdateDescriptionForSearchDomain returns UpdateDescriptionForSearchDomainResponse.UpdateDescriptionForSearchDomain, and is useful for accessing the field via an interface. +func (v *UpdateDescriptionForSearchDomainResponse) GetUpdateDescriptionForSearchDomain() UpdateDescriptionForSearchDomainUpdateDescriptionForSearchDomainUpdateDescriptionMutation { + return v.UpdateDescriptionForSearchDomain +} + +// UpdateDescriptionForSearchDomainUpdateDescriptionForSearchDomainUpdateDescriptionMutation includes the requested fields of the GraphQL type UpdateDescriptionMutation. +type UpdateDescriptionForSearchDomainUpdateDescriptionForSearchDomainUpdateDescriptionMutation struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateDescriptionForSearchDomainUpdateDescriptionForSearchDomainUpdateDescriptionMutation.Typename, and is useful for accessing the field via an interface. +func (v *UpdateDescriptionForSearchDomainUpdateDescriptionForSearchDomainUpdateDescriptionMutation) GetTypename() *string { + return v.Typename +} + +// UpdateEmailActionResponse is returned by UpdateEmailAction on success. +type UpdateEmailActionResponse struct { + // Update an email action. + UpdateEmailAction UpdateEmailActionUpdateEmailAction `json:"updateEmailAction"` +} + +// GetUpdateEmailAction returns UpdateEmailActionResponse.UpdateEmailAction, and is useful for accessing the field via an interface. +func (v *UpdateEmailActionResponse) GetUpdateEmailAction() UpdateEmailActionUpdateEmailAction { + return v.UpdateEmailAction +} + +// UpdateEmailActionUpdateEmailAction includes the requested fields of the GraphQL type EmailAction. +// The GraphQL type's documentation follows. +// +// An email action. +type UpdateEmailActionUpdateEmailAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateEmailActionUpdateEmailAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateEmailActionUpdateEmailAction) GetTypename() *string { return v.Typename } + +// UpdateFilterAlertResponse is returned by UpdateFilterAlert on success. +type UpdateFilterAlertResponse struct { + // Update a filter alert. + UpdateFilterAlert UpdateFilterAlertUpdateFilterAlert `json:"updateFilterAlert"` +} + +// GetUpdateFilterAlert returns UpdateFilterAlertResponse.UpdateFilterAlert, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertResponse) GetUpdateFilterAlert() UpdateFilterAlertUpdateFilterAlert { + return v.UpdateFilterAlert +} + +// UpdateFilterAlertUpdateFilterAlert includes the requested fields of the GraphQL type FilterAlert. +// The GraphQL type's documentation follows. +// +// A filter alert. +type UpdateFilterAlertUpdateFilterAlert struct { + FilterAlertDetails `json:"-"` +} + +// GetId returns UpdateFilterAlertUpdateFilterAlert.Id, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetId() string { return v.FilterAlertDetails.Id } + +// GetName returns UpdateFilterAlertUpdateFilterAlert.Name, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetName() string { return v.FilterAlertDetails.Name } + +// GetDescription returns UpdateFilterAlertUpdateFilterAlert.Description, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetDescription() *string { + return v.FilterAlertDetails.Description +} + +// GetQueryString returns UpdateFilterAlertUpdateFilterAlert.QueryString, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetQueryString() string { + return v.FilterAlertDetails.QueryString +} + +// GetThrottleTimeSeconds returns UpdateFilterAlertUpdateFilterAlert.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetThrottleTimeSeconds() *int64 { + return v.FilterAlertDetails.ThrottleTimeSeconds +} + +// GetThrottleField returns UpdateFilterAlertUpdateFilterAlert.ThrottleField, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetThrottleField() *string { + return v.FilterAlertDetails.ThrottleField +} + +// GetLabels returns UpdateFilterAlertUpdateFilterAlert.Labels, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetLabels() []string { return v.FilterAlertDetails.Labels } + +// GetEnabled returns UpdateFilterAlertUpdateFilterAlert.Enabled, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetEnabled() bool { return v.FilterAlertDetails.Enabled } + +// GetActions returns UpdateFilterAlertUpdateFilterAlert.Actions, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetActions() []SharedActionNameType { + return v.FilterAlertDetails.Actions +} + +// GetQueryOwnership returns UpdateFilterAlertUpdateFilterAlert.QueryOwnership, and is useful for accessing the field via an interface. +func (v *UpdateFilterAlertUpdateFilterAlert) GetQueryOwnership() SharedQueryOwnershipType { + return v.FilterAlertDetails.QueryOwnership +} + +func (v *UpdateFilterAlertUpdateFilterAlert) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateFilterAlertUpdateFilterAlert + graphql.NoUnmarshalJSON + } + firstPass.UpdateFilterAlertUpdateFilterAlert = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.FilterAlertDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalUpdateFilterAlertUpdateFilterAlert struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + ThrottleTimeSeconds *int64 `json:"throttleTimeSeconds"` + + ThrottleField *string `json:"throttleField"` + + Labels []string `json:"labels"` + + Enabled bool `json:"enabled"` + + Actions []json.RawMessage `json:"actions"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *UpdateFilterAlertUpdateFilterAlert) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateFilterAlertUpdateFilterAlert) __premarshalJSON() (*__premarshalUpdateFilterAlertUpdateFilterAlert, error) { + var retval __premarshalUpdateFilterAlertUpdateFilterAlert + + retval.Id = v.FilterAlertDetails.Id + retval.Name = v.FilterAlertDetails.Name + retval.Description = v.FilterAlertDetails.Description + retval.QueryString = v.FilterAlertDetails.QueryString + retval.ThrottleTimeSeconds = v.FilterAlertDetails.ThrottleTimeSeconds + retval.ThrottleField = v.FilterAlertDetails.ThrottleField + retval.Labels = v.FilterAlertDetails.Labels + retval.Enabled = v.FilterAlertDetails.Enabled + { + + dst := &retval.Actions + src := v.FilterAlertDetails.Actions + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateFilterAlertUpdateFilterAlert.FilterAlertDetails.Actions: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.FilterAlertDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateFilterAlertUpdateFilterAlert.FilterAlertDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// UpdateHumioRepoActionResponse is returned by UpdateHumioRepoAction on success. +type UpdateHumioRepoActionResponse struct { + // Update a LogScale repository action. + UpdateHumioRepoAction UpdateHumioRepoActionUpdateHumioRepoAction `json:"updateHumioRepoAction"` +} + +// GetUpdateHumioRepoAction returns UpdateHumioRepoActionResponse.UpdateHumioRepoAction, and is useful for accessing the field via an interface. +func (v *UpdateHumioRepoActionResponse) GetUpdateHumioRepoAction() UpdateHumioRepoActionUpdateHumioRepoAction { + return v.UpdateHumioRepoAction +} + +// UpdateHumioRepoActionUpdateHumioRepoAction includes the requested fields of the GraphQL type HumioRepoAction. +// The GraphQL type's documentation follows. +// +// A LogScale repository action. +type UpdateHumioRepoActionUpdateHumioRepoAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateHumioRepoActionUpdateHumioRepoAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateHumioRepoActionUpdateHumioRepoAction) GetTypename() *string { return v.Typename } + +// UpdateIngestBasedRetentionResponse is returned by UpdateIngestBasedRetention on success. +type UpdateIngestBasedRetentionResponse struct { + // Update the retention policy of a repository. + UpdateRetention UpdateIngestBasedRetentionUpdateRetentionUpdateRetentionMutation `json:"updateRetention"` +} + +// GetUpdateRetention returns UpdateIngestBasedRetentionResponse.UpdateRetention, and is useful for accessing the field via an interface. +func (v *UpdateIngestBasedRetentionResponse) GetUpdateRetention() UpdateIngestBasedRetentionUpdateRetentionUpdateRetentionMutation { + return v.UpdateRetention +} + +// UpdateIngestBasedRetentionUpdateRetentionUpdateRetentionMutation includes the requested fields of the GraphQL type UpdateRetentionMutation. +type UpdateIngestBasedRetentionUpdateRetentionUpdateRetentionMutation struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateIngestBasedRetentionUpdateRetentionUpdateRetentionMutation.Typename, and is useful for accessing the field via an interface. +func (v *UpdateIngestBasedRetentionUpdateRetentionUpdateRetentionMutation) GetTypename() *string { + return v.Typename +} + +// UpdateLicenseKeyResponse is returned by UpdateLicenseKey on success. +type UpdateLicenseKeyResponse struct { + // Update the license key for the LogScale cluster. If there is an existing license on this cluster this operation requires permission to manage cluster. + UpdateLicenseKey UpdateLicenseKeyUpdateLicenseKeyLicense `json:"-"` +} + +// GetUpdateLicenseKey returns UpdateLicenseKeyResponse.UpdateLicenseKey, and is useful for accessing the field via an interface. +func (v *UpdateLicenseKeyResponse) GetUpdateLicenseKey() UpdateLicenseKeyUpdateLicenseKeyLicense { + return v.UpdateLicenseKey +} + +func (v *UpdateLicenseKeyResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateLicenseKeyResponse + UpdateLicenseKey json.RawMessage `json:"updateLicenseKey"` + graphql.NoUnmarshalJSON + } + firstPass.UpdateLicenseKeyResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.UpdateLicenseKey + src := firstPass.UpdateLicenseKey + if len(src) != 0 && string(src) != "null" { + err = __unmarshalUpdateLicenseKeyUpdateLicenseKeyLicense( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal UpdateLicenseKeyResponse.UpdateLicenseKey: %w", err) + } + } + } + return nil +} + +type __premarshalUpdateLicenseKeyResponse struct { + UpdateLicenseKey json.RawMessage `json:"updateLicenseKey"` +} + +func (v *UpdateLicenseKeyResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateLicenseKeyResponse) __premarshalJSON() (*__premarshalUpdateLicenseKeyResponse, error) { + var retval __premarshalUpdateLicenseKeyResponse + + { + + dst := &retval.UpdateLicenseKey + src := v.UpdateLicenseKey + var err error + *dst, err = __marshalUpdateLicenseKeyUpdateLicenseKeyLicense( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateLicenseKeyResponse.UpdateLicenseKey: %w", err) + } + } + return &retval, nil +} + +// UpdateLicenseKeyUpdateLicenseKeyLicense includes the requested fields of the GraphQL interface License. +// +// UpdateLicenseKeyUpdateLicenseKeyLicense is implemented by the following types: +// UpdateLicenseKeyUpdateLicenseKeyOnPremLicense +// UpdateLicenseKeyUpdateLicenseKeyTrialLicense +// The GraphQL type's documentation follows. +// +// Represents information about the LogScale instance. +type UpdateLicenseKeyUpdateLicenseKeyLicense interface { + implementsGraphQLInterfaceUpdateLicenseKeyUpdateLicenseKeyLicense() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() *string +} + +func (v *UpdateLicenseKeyUpdateLicenseKeyOnPremLicense) implementsGraphQLInterfaceUpdateLicenseKeyUpdateLicenseKeyLicense() { +} +func (v *UpdateLicenseKeyUpdateLicenseKeyTrialLicense) implementsGraphQLInterfaceUpdateLicenseKeyUpdateLicenseKeyLicense() { +} + +func __unmarshalUpdateLicenseKeyUpdateLicenseKeyLicense(b []byte, v *UpdateLicenseKeyUpdateLicenseKeyLicense) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "OnPremLicense": + *v = new(UpdateLicenseKeyUpdateLicenseKeyOnPremLicense) + return json.Unmarshal(b, *v) + case "TrialLicense": + *v = new(UpdateLicenseKeyUpdateLicenseKeyTrialLicense) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing License.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for UpdateLicenseKeyUpdateLicenseKeyLicense: "%v"`, tn.TypeName) + } +} + +func __marshalUpdateLicenseKeyUpdateLicenseKeyLicense(v *UpdateLicenseKeyUpdateLicenseKeyLicense) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *UpdateLicenseKeyUpdateLicenseKeyOnPremLicense: + typename = "OnPremLicense" + + result := struct { + TypeName string `json:"__typename"` + *UpdateLicenseKeyUpdateLicenseKeyOnPremLicense + }{typename, v} + return json.Marshal(result) + case *UpdateLicenseKeyUpdateLicenseKeyTrialLicense: + typename = "TrialLicense" + + result := struct { + TypeName string `json:"__typename"` + *UpdateLicenseKeyUpdateLicenseKeyTrialLicense + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for UpdateLicenseKeyUpdateLicenseKeyLicense: "%T"`, v) + } +} + +// UpdateLicenseKeyUpdateLicenseKeyOnPremLicense includes the requested fields of the GraphQL type OnPremLicense. +// The GraphQL type's documentation follows. +// +// Represents information about a LogScale License. +type UpdateLicenseKeyUpdateLicenseKeyOnPremLicense struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateLicenseKeyUpdateLicenseKeyOnPremLicense.Typename, and is useful for accessing the field via an interface. +func (v *UpdateLicenseKeyUpdateLicenseKeyOnPremLicense) GetTypename() *string { return v.Typename } + +// UpdateLicenseKeyUpdateLicenseKeyTrialLicense includes the requested fields of the GraphQL type TrialLicense. +// The GraphQL type's documentation follows. +// +// Represents information about an on-going trial of LogScale. +type UpdateLicenseKeyUpdateLicenseKeyTrialLicense struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateLicenseKeyUpdateLicenseKeyTrialLicense.Typename, and is useful for accessing the field via an interface. +func (v *UpdateLicenseKeyUpdateLicenseKeyTrialLicense) GetTypename() *string { return v.Typename } + +// UpdateOpsGenieActionResponse is returned by UpdateOpsGenieAction on success. +type UpdateOpsGenieActionResponse struct { + // Update an OpsGenie action. + UpdateOpsGenieAction UpdateOpsGenieActionUpdateOpsGenieAction `json:"updateOpsGenieAction"` +} + +// GetUpdateOpsGenieAction returns UpdateOpsGenieActionResponse.UpdateOpsGenieAction, and is useful for accessing the field via an interface. +func (v *UpdateOpsGenieActionResponse) GetUpdateOpsGenieAction() UpdateOpsGenieActionUpdateOpsGenieAction { + return v.UpdateOpsGenieAction +} + +// UpdateOpsGenieActionUpdateOpsGenieAction includes the requested fields of the GraphQL type OpsGenieAction. +// The GraphQL type's documentation follows. +// +// An OpsGenie action +type UpdateOpsGenieActionUpdateOpsGenieAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateOpsGenieActionUpdateOpsGenieAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateOpsGenieActionUpdateOpsGenieAction) GetTypename() *string { return v.Typename } + +// UpdatePagerDutyActionResponse is returned by UpdatePagerDutyAction on success. +type UpdatePagerDutyActionResponse struct { + // Update a PagerDuty action. + UpdatePagerDutyAction UpdatePagerDutyActionUpdatePagerDutyAction `json:"updatePagerDutyAction"` +} + +// GetUpdatePagerDutyAction returns UpdatePagerDutyActionResponse.UpdatePagerDutyAction, and is useful for accessing the field via an interface. +func (v *UpdatePagerDutyActionResponse) GetUpdatePagerDutyAction() UpdatePagerDutyActionUpdatePagerDutyAction { + return v.UpdatePagerDutyAction +} + +// UpdatePagerDutyActionUpdatePagerDutyAction includes the requested fields of the GraphQL type PagerDutyAction. +// The GraphQL type's documentation follows. +// +// A PagerDuty action. +type UpdatePagerDutyActionUpdatePagerDutyAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdatePagerDutyActionUpdatePagerDutyAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdatePagerDutyActionUpdatePagerDutyAction) GetTypename() *string { return v.Typename } + +// UpdateS3ArchivingConfigurationResponse is returned by UpdateS3ArchivingConfiguration on success. +type UpdateS3ArchivingConfigurationResponse struct { + // Configures S3 archiving for a repository. E.g. bucket and region. + S3ConfigureArchiving UpdateS3ArchivingConfigurationS3ConfigureArchivingBooleanResultType `json:"s3ConfigureArchiving"` +} + +// GetS3ConfigureArchiving returns UpdateS3ArchivingConfigurationResponse.S3ConfigureArchiving, and is useful for accessing the field via an interface. +func (v *UpdateS3ArchivingConfigurationResponse) GetS3ConfigureArchiving() UpdateS3ArchivingConfigurationS3ConfigureArchivingBooleanResultType { + return v.S3ConfigureArchiving +} + +// UpdateS3ArchivingConfigurationS3ConfigureArchivingBooleanResultType includes the requested fields of the GraphQL type BooleanResultType. +type UpdateS3ArchivingConfigurationS3ConfigureArchivingBooleanResultType struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateS3ArchivingConfigurationS3ConfigureArchivingBooleanResultType.Typename, and is useful for accessing the field via an interface. +func (v *UpdateS3ArchivingConfigurationS3ConfigureArchivingBooleanResultType) GetTypename() *string { + return v.Typename +} + +// UpdateScheduledSearchResponse is returned by UpdateScheduledSearch on success. +type UpdateScheduledSearchResponse struct { + // Update a scheduled search. + UpdateScheduledSearch UpdateScheduledSearchUpdateScheduledSearch `json:"updateScheduledSearch"` +} + +// GetUpdateScheduledSearch returns UpdateScheduledSearchResponse.UpdateScheduledSearch, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchResponse) GetUpdateScheduledSearch() UpdateScheduledSearchUpdateScheduledSearch { + return v.UpdateScheduledSearch +} + +// UpdateScheduledSearchUpdateScheduledSearch includes the requested fields of the GraphQL type ScheduledSearch. +// The GraphQL type's documentation follows. +// +// Information about a scheduled search +type UpdateScheduledSearchUpdateScheduledSearch struct { + ScheduledSearchDetails `json:"-"` +} + +// GetId returns UpdateScheduledSearchUpdateScheduledSearch.Id, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetId() string { + return v.ScheduledSearchDetails.Id +} + +// GetName returns UpdateScheduledSearchUpdateScheduledSearch.Name, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetName() string { + return v.ScheduledSearchDetails.Name +} + +// GetDescription returns UpdateScheduledSearchUpdateScheduledSearch.Description, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetDescription() *string { + return v.ScheduledSearchDetails.Description +} + +// GetQueryString returns UpdateScheduledSearchUpdateScheduledSearch.QueryString, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetQueryString() string { + return v.ScheduledSearchDetails.QueryString +} + +// GetStart returns UpdateScheduledSearchUpdateScheduledSearch.Start, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetStart() string { + return v.ScheduledSearchDetails.Start +} + +// GetEnd returns UpdateScheduledSearchUpdateScheduledSearch.End, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetEnd() string { + return v.ScheduledSearchDetails.End +} + +// GetTimeZone returns UpdateScheduledSearchUpdateScheduledSearch.TimeZone, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetTimeZone() string { + return v.ScheduledSearchDetails.TimeZone +} + +// GetSchedule returns UpdateScheduledSearchUpdateScheduledSearch.Schedule, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetSchedule() string { + return v.ScheduledSearchDetails.Schedule +} + +// GetBackfillLimit returns UpdateScheduledSearchUpdateScheduledSearch.BackfillLimit, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetBackfillLimit() int { + return v.ScheduledSearchDetails.BackfillLimit +} + +// GetEnabled returns UpdateScheduledSearchUpdateScheduledSearch.Enabled, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetEnabled() bool { + return v.ScheduledSearchDetails.Enabled +} + +// GetLabels returns UpdateScheduledSearchUpdateScheduledSearch.Labels, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetLabels() []string { + return v.ScheduledSearchDetails.Labels +} + +// GetActionsV2 returns UpdateScheduledSearchUpdateScheduledSearch.ActionsV2, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetActionsV2() []SharedActionNameType { + return v.ScheduledSearchDetails.ActionsV2 +} + +// GetQueryOwnership returns UpdateScheduledSearchUpdateScheduledSearch.QueryOwnership, and is useful for accessing the field via an interface. +func (v *UpdateScheduledSearchUpdateScheduledSearch) GetQueryOwnership() SharedQueryOwnershipType { + return v.ScheduledSearchDetails.QueryOwnership +} + +func (v *UpdateScheduledSearchUpdateScheduledSearch) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *UpdateScheduledSearchUpdateScheduledSearch + graphql.NoUnmarshalJSON + } + firstPass.UpdateScheduledSearchUpdateScheduledSearch = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ScheduledSearchDetails) + if err != nil { + return err + } + return nil +} + +type __premarshalUpdateScheduledSearchUpdateScheduledSearch struct { + Id string `json:"id"` + + Name string `json:"name"` + + Description *string `json:"description"` + + QueryString string `json:"queryString"` + + Start string `json:"start"` + + End string `json:"end"` + + TimeZone string `json:"timeZone"` + + Schedule string `json:"schedule"` + + BackfillLimit int `json:"backfillLimit"` + + Enabled bool `json:"enabled"` + + Labels []string `json:"labels"` + + ActionsV2 []json.RawMessage `json:"actionsV2"` + + QueryOwnership json.RawMessage `json:"queryOwnership"` +} + +func (v *UpdateScheduledSearchUpdateScheduledSearch) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *UpdateScheduledSearchUpdateScheduledSearch) __premarshalJSON() (*__premarshalUpdateScheduledSearchUpdateScheduledSearch, error) { + var retval __premarshalUpdateScheduledSearchUpdateScheduledSearch + + retval.Id = v.ScheduledSearchDetails.Id + retval.Name = v.ScheduledSearchDetails.Name + retval.Description = v.ScheduledSearchDetails.Description + retval.QueryString = v.ScheduledSearchDetails.QueryString + retval.Start = v.ScheduledSearchDetails.Start + retval.End = v.ScheduledSearchDetails.End + retval.TimeZone = v.ScheduledSearchDetails.TimeZone + retval.Schedule = v.ScheduledSearchDetails.Schedule + retval.BackfillLimit = v.ScheduledSearchDetails.BackfillLimit + retval.Enabled = v.ScheduledSearchDetails.Enabled + retval.Labels = v.ScheduledSearchDetails.Labels + { + + dst := &retval.ActionsV2 + src := v.ScheduledSearchDetails.ActionsV2 + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalSharedActionNameType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateScheduledSearchUpdateScheduledSearch.ScheduledSearchDetails.ActionsV2: %w", err) + } + } + } + { + + dst := &retval.QueryOwnership + src := v.ScheduledSearchDetails.QueryOwnership + var err error + *dst, err = __marshalSharedQueryOwnershipType( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal UpdateScheduledSearchUpdateScheduledSearch.ScheduledSearchDetails.QueryOwnership: %w", err) + } + } + return &retval, nil +} + +// UpdateSlackActionResponse is returned by UpdateSlackAction on success. +type UpdateSlackActionResponse struct { + // Update a Slack action. + UpdateSlackAction UpdateSlackActionUpdateSlackAction `json:"updateSlackAction"` +} + +// GetUpdateSlackAction returns UpdateSlackActionResponse.UpdateSlackAction, and is useful for accessing the field via an interface. +func (v *UpdateSlackActionResponse) GetUpdateSlackAction() UpdateSlackActionUpdateSlackAction { + return v.UpdateSlackAction +} + +// UpdateSlackActionUpdateSlackAction includes the requested fields of the GraphQL type SlackAction. +// The GraphQL type's documentation follows. +// +// A Slack action +type UpdateSlackActionUpdateSlackAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateSlackActionUpdateSlackAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateSlackActionUpdateSlackAction) GetTypename() *string { return v.Typename } + +// UpdateSlackPostMessageActionResponse is returned by UpdateSlackPostMessageAction on success. +type UpdateSlackPostMessageActionResponse struct { + // Update a post-message Slack action. + UpdateSlackPostMessageAction UpdateSlackPostMessageActionUpdateSlackPostMessageAction `json:"updateSlackPostMessageAction"` +} + +// GetUpdateSlackPostMessageAction returns UpdateSlackPostMessageActionResponse.UpdateSlackPostMessageAction, and is useful for accessing the field via an interface. +func (v *UpdateSlackPostMessageActionResponse) GetUpdateSlackPostMessageAction() UpdateSlackPostMessageActionUpdateSlackPostMessageAction { + return v.UpdateSlackPostMessageAction +} + +// UpdateSlackPostMessageActionUpdateSlackPostMessageAction includes the requested fields of the GraphQL type SlackPostMessageAction. +// The GraphQL type's documentation follows. +// +// A slack post-message action. +type UpdateSlackPostMessageActionUpdateSlackPostMessageAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateSlackPostMessageActionUpdateSlackPostMessageAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateSlackPostMessageActionUpdateSlackPostMessageAction) GetTypename() *string { + return v.Typename +} + +// UpdateStorageBasedRetentionResponse is returned by UpdateStorageBasedRetention on success. +type UpdateStorageBasedRetentionResponse struct { + // Update the retention policy of a repository. + UpdateRetention UpdateStorageBasedRetentionUpdateRetentionUpdateRetentionMutation `json:"updateRetention"` +} + +// GetUpdateRetention returns UpdateStorageBasedRetentionResponse.UpdateRetention, and is useful for accessing the field via an interface. +func (v *UpdateStorageBasedRetentionResponse) GetUpdateRetention() UpdateStorageBasedRetentionUpdateRetentionUpdateRetentionMutation { + return v.UpdateRetention +} + +// UpdateStorageBasedRetentionUpdateRetentionUpdateRetentionMutation includes the requested fields of the GraphQL type UpdateRetentionMutation. +type UpdateStorageBasedRetentionUpdateRetentionUpdateRetentionMutation struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateStorageBasedRetentionUpdateRetentionUpdateRetentionMutation.Typename, and is useful for accessing the field via an interface. +func (v *UpdateStorageBasedRetentionUpdateRetentionUpdateRetentionMutation) GetTypename() *string { + return v.Typename +} + +// UpdateTimeBasedRetentionResponse is returned by UpdateTimeBasedRetention on success. +type UpdateTimeBasedRetentionResponse struct { + // Update the retention policy of a repository. + UpdateRetention UpdateTimeBasedRetentionUpdateRetentionUpdateRetentionMutation `json:"updateRetention"` +} + +// GetUpdateRetention returns UpdateTimeBasedRetentionResponse.UpdateRetention, and is useful for accessing the field via an interface. +func (v *UpdateTimeBasedRetentionResponse) GetUpdateRetention() UpdateTimeBasedRetentionUpdateRetentionUpdateRetentionMutation { + return v.UpdateRetention +} + +// UpdateTimeBasedRetentionUpdateRetentionUpdateRetentionMutation includes the requested fields of the GraphQL type UpdateRetentionMutation. +type UpdateTimeBasedRetentionUpdateRetentionUpdateRetentionMutation struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateTimeBasedRetentionUpdateRetentionUpdateRetentionMutation.Typename, and is useful for accessing the field via an interface. +func (v *UpdateTimeBasedRetentionUpdateRetentionUpdateRetentionMutation) GetTypename() *string { + return v.Typename +} + +// UpdateVictorOpsActionResponse is returned by UpdateVictorOpsAction on success. +type UpdateVictorOpsActionResponse struct { + // Update a VictorOps action. + UpdateVictorOpsAction UpdateVictorOpsActionUpdateVictorOpsAction `json:"updateVictorOpsAction"` +} + +// GetUpdateVictorOpsAction returns UpdateVictorOpsActionResponse.UpdateVictorOpsAction, and is useful for accessing the field via an interface. +func (v *UpdateVictorOpsActionResponse) GetUpdateVictorOpsAction() UpdateVictorOpsActionUpdateVictorOpsAction { + return v.UpdateVictorOpsAction +} + +// UpdateVictorOpsActionUpdateVictorOpsAction includes the requested fields of the GraphQL type VictorOpsAction. +// The GraphQL type's documentation follows. +// +// A VictorOps action. +type UpdateVictorOpsActionUpdateVictorOpsAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateVictorOpsActionUpdateVictorOpsAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateVictorOpsActionUpdateVictorOpsAction) GetTypename() *string { return v.Typename } + +// UpdateViewConnectionsResponse is returned by UpdateViewConnections on success. +type UpdateViewConnectionsResponse struct { + // Update a view. + UpdateView UpdateViewConnectionsUpdateView `json:"updateView"` +} + +// GetUpdateView returns UpdateViewConnectionsResponse.UpdateView, and is useful for accessing the field via an interface. +func (v *UpdateViewConnectionsResponse) GetUpdateView() UpdateViewConnectionsUpdateView { + return v.UpdateView +} + +// UpdateViewConnectionsUpdateView includes the requested fields of the GraphQL type View. +// The GraphQL type's documentation follows. +// +// Represents information about a view, pulling data from one or several repositories. +type UpdateViewConnectionsUpdateView struct { + Name string `json:"name"` +} + +// GetName returns UpdateViewConnectionsUpdateView.Name, and is useful for accessing the field via an interface. +func (v *UpdateViewConnectionsUpdateView) GetName() string { return v.Name } + +// UpdateWebhookActionResponse is returned by UpdateWebhookAction on success. +type UpdateWebhookActionResponse struct { + // Update a webhook action. + UpdateWebhookAction UpdateWebhookActionUpdateWebhookAction `json:"updateWebhookAction"` +} + +// GetUpdateWebhookAction returns UpdateWebhookActionResponse.UpdateWebhookAction, and is useful for accessing the field via an interface. +func (v *UpdateWebhookActionResponse) GetUpdateWebhookAction() UpdateWebhookActionUpdateWebhookAction { + return v.UpdateWebhookAction +} + +// UpdateWebhookActionUpdateWebhookAction includes the requested fields of the GraphQL type WebhookAction. +// The GraphQL type's documentation follows. +// +// A webhook action +type UpdateWebhookActionUpdateWebhookAction struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns UpdateWebhookActionUpdateWebhookAction.Typename, and is useful for accessing the field via an interface. +func (v *UpdateWebhookActionUpdateWebhookAction) GetTypename() *string { return v.Typename } + +// UserDetails includes the GraphQL fields of User requested by the fragment UserDetails. +// The GraphQL type's documentation follows. +// +// A user profile. +type UserDetails struct { + Id string `json:"id"` + Username string `json:"username"` + IsRoot bool `json:"isRoot"` +} + +// GetId returns UserDetails.Id, and is useful for accessing the field via an interface. +func (v *UserDetails) GetId() string { return v.Id } + +// GetUsername returns UserDetails.Username, and is useful for accessing the field via an interface. +func (v *UserDetails) GetUsername() string { return v.Username } + +// GetIsRoot returns UserDetails.IsRoot, and is useful for accessing the field via an interface. +func (v *UserDetails) GetIsRoot() bool { return v.IsRoot } + +// The repositories this view will read from. +type ViewConnectionInput struct { + // The repositories this view will read from. + RepositoryName string `json:"repositoryName"` + // The repositories this view will read from. + Filter string `json:"filter"` + // The repositories this view will read from. + LanguageVersion *LanguageVersionEnum `json:"languageVersion"` +} + +// GetRepositoryName returns ViewConnectionInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *ViewConnectionInput) GetRepositoryName() string { return v.RepositoryName } + +// GetFilter returns ViewConnectionInput.Filter, and is useful for accessing the field via an interface. +func (v *ViewConnectionInput) GetFilter() string { return v.Filter } + +// GetLanguageVersion returns ViewConnectionInput.LanguageVersion, and is useful for accessing the field via an interface. +func (v *ViewConnectionInput) GetLanguageVersion() *LanguageVersionEnum { return v.LanguageVersion } + +// __AddIngestTokenInput is used internally by genqlient +type __AddIngestTokenInput struct { + RepositoryName string `json:"RepositoryName"` + Name string `json:"Name"` + ParserName *string `json:"ParserName"` +} + +// GetRepositoryName returns __AddIngestTokenInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__AddIngestTokenInput) GetRepositoryName() string { return v.RepositoryName } + +// GetName returns __AddIngestTokenInput.Name, and is useful for accessing the field via an interface. +func (v *__AddIngestTokenInput) GetName() string { return v.Name } + +// GetParserName returns __AddIngestTokenInput.ParserName, and is useful for accessing the field via an interface. +func (v *__AddIngestTokenInput) GetParserName() *string { return v.ParserName } + +// __AddUserInput is used internally by genqlient +type __AddUserInput struct { + Username string `json:"Username"` + IsRoot *bool `json:"IsRoot"` +} + +// GetUsername returns __AddUserInput.Username, and is useful for accessing the field via an interface. +func (v *__AddUserInput) GetUsername() string { return v.Username } + +// GetIsRoot returns __AddUserInput.IsRoot, and is useful for accessing the field via an interface. +func (v *__AddUserInput) GetIsRoot() *bool { return v.IsRoot } + +// __AssignParserToIngestTokenInput is used internally by genqlient +type __AssignParserToIngestTokenInput struct { + RepositoryName string `json:"RepositoryName"` + IngestTokenName string `json:"IngestTokenName"` + ParserName string `json:"ParserName"` +} + +// GetRepositoryName returns __AssignParserToIngestTokenInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__AssignParserToIngestTokenInput) GetRepositoryName() string { return v.RepositoryName } + +// GetIngestTokenName returns __AssignParserToIngestTokenInput.IngestTokenName, and is useful for accessing the field via an interface. +func (v *__AssignParserToIngestTokenInput) GetIngestTokenName() string { return v.IngestTokenName } + +// GetParserName returns __AssignParserToIngestTokenInput.ParserName, and is useful for accessing the field via an interface. +func (v *__AssignParserToIngestTokenInput) GetParserName() string { return v.ParserName } + +// __CreateAggregateAlertInput is used internally by genqlient +type __CreateAggregateAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + SearchIntervalSeconds int64 `json:"SearchIntervalSeconds"` + ActionIdsOrNames []string `json:"ActionIdsOrNames"` + Labels []string `json:"Labels"` + Enabled bool `json:"Enabled"` + ThrottleField *string `json:"ThrottleField"` + ThrottleTimeSeconds int64 `json:"ThrottleTimeSeconds"` + TriggerMode TriggerMode `json:"TriggerMode"` + QueryTimestampMode QueryTimestampType `json:"QueryTimestampMode"` + QueryOwnershipType QueryOwnershipType `json:"QueryOwnershipType"` +} + +// GetSearchDomainName returns __CreateAggregateAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetName returns __CreateAggregateAlertInput.Name, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetName() string { return v.Name } + +// GetDescription returns __CreateAggregateAlertInput.Description, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __CreateAggregateAlertInput.QueryString, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetQueryString() string { return v.QueryString } + +// GetSearchIntervalSeconds returns __CreateAggregateAlertInput.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetSearchIntervalSeconds() int64 { + return v.SearchIntervalSeconds +} + +// GetActionIdsOrNames returns __CreateAggregateAlertInput.ActionIdsOrNames, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetActionIdsOrNames() []string { return v.ActionIdsOrNames } + +// GetLabels returns __CreateAggregateAlertInput.Labels, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetLabels() []string { return v.Labels } + +// GetEnabled returns __CreateAggregateAlertInput.Enabled, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetEnabled() bool { return v.Enabled } + +// GetThrottleField returns __CreateAggregateAlertInput.ThrottleField, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetThrottleField() *string { return v.ThrottleField } + +// GetThrottleTimeSeconds returns __CreateAggregateAlertInput.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetThrottleTimeSeconds() int64 { return v.ThrottleTimeSeconds } + +// GetTriggerMode returns __CreateAggregateAlertInput.TriggerMode, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetTriggerMode() TriggerMode { return v.TriggerMode } + +// GetQueryTimestampMode returns __CreateAggregateAlertInput.QueryTimestampMode, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetQueryTimestampMode() QueryTimestampType { + return v.QueryTimestampMode +} + +// GetQueryOwnershipType returns __CreateAggregateAlertInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__CreateAggregateAlertInput) GetQueryOwnershipType() QueryOwnershipType { + return v.QueryOwnershipType +} + +// __CreateAlertInput is used internally by genqlient +type __CreateAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + QueryStart string `json:"QueryStart"` + ThrottleTimeMillis int64 `json:"ThrottleTimeMillis"` + Enabled *bool `json:"Enabled"` + Actions []string `json:"Actions"` + Labels []string `json:"Labels"` + QueryOwnershipType *QueryOwnershipType `json:"QueryOwnershipType"` + ThrottleField *string `json:"ThrottleField"` +} + +// GetSearchDomainName returns __CreateAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetName returns __CreateAlertInput.Name, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetName() string { return v.Name } + +// GetDescription returns __CreateAlertInput.Description, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __CreateAlertInput.QueryString, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetQueryString() string { return v.QueryString } + +// GetQueryStart returns __CreateAlertInput.QueryStart, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetQueryStart() string { return v.QueryStart } + +// GetThrottleTimeMillis returns __CreateAlertInput.ThrottleTimeMillis, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetThrottleTimeMillis() int64 { return v.ThrottleTimeMillis } + +// GetEnabled returns __CreateAlertInput.Enabled, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetEnabled() *bool { return v.Enabled } + +// GetActions returns __CreateAlertInput.Actions, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetActions() []string { return v.Actions } + +// GetLabels returns __CreateAlertInput.Labels, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetLabels() []string { return v.Labels } + +// GetQueryOwnershipType returns __CreateAlertInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetQueryOwnershipType() *QueryOwnershipType { return v.QueryOwnershipType } + +// GetThrottleField returns __CreateAlertInput.ThrottleField, and is useful for accessing the field via an interface. +func (v *__CreateAlertInput) GetThrottleField() *string { return v.ThrottleField } + +// __CreateEmailActionInput is used internally by genqlient +type __CreateEmailActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + Recipients []string `json:"Recipients"` + SubjectTemplate *string `json:"SubjectTemplate"` + BodyTemplate *string `json:"BodyTemplate"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreateEmailActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateEmailActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateEmailActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateEmailActionInput) GetActionName() string { return v.ActionName } + +// GetRecipients returns __CreateEmailActionInput.Recipients, and is useful for accessing the field via an interface. +func (v *__CreateEmailActionInput) GetRecipients() []string { return v.Recipients } + +// GetSubjectTemplate returns __CreateEmailActionInput.SubjectTemplate, and is useful for accessing the field via an interface. +func (v *__CreateEmailActionInput) GetSubjectTemplate() *string { return v.SubjectTemplate } + +// GetBodyTemplate returns __CreateEmailActionInput.BodyTemplate, and is useful for accessing the field via an interface. +func (v *__CreateEmailActionInput) GetBodyTemplate() *string { return v.BodyTemplate } + +// GetUseProxy returns __CreateEmailActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreateEmailActionInput) GetUseProxy() bool { return v.UseProxy } + +// __CreateFilterAlertInput is used internally by genqlient +type __CreateFilterAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + ActionIdsOrNames []string `json:"ActionIdsOrNames"` + Labels []string `json:"Labels"` + Enabled bool `json:"Enabled"` + ThrottleField *string `json:"ThrottleField"` + ThrottleTimeSeconds int64 `json:"ThrottleTimeSeconds"` + QueryOwnershipType QueryOwnershipType `json:"QueryOwnershipType"` +} + +// GetSearchDomainName returns __CreateFilterAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetName returns __CreateFilterAlertInput.Name, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetName() string { return v.Name } + +// GetDescription returns __CreateFilterAlertInput.Description, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __CreateFilterAlertInput.QueryString, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetQueryString() string { return v.QueryString } + +// GetActionIdsOrNames returns __CreateFilterAlertInput.ActionIdsOrNames, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetActionIdsOrNames() []string { return v.ActionIdsOrNames } + +// GetLabels returns __CreateFilterAlertInput.Labels, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetLabels() []string { return v.Labels } + +// GetEnabled returns __CreateFilterAlertInput.Enabled, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetEnabled() bool { return v.Enabled } + +// GetThrottleField returns __CreateFilterAlertInput.ThrottleField, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetThrottleField() *string { return v.ThrottleField } + +// GetThrottleTimeSeconds returns __CreateFilterAlertInput.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetThrottleTimeSeconds() int64 { return v.ThrottleTimeSeconds } + +// GetQueryOwnershipType returns __CreateFilterAlertInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__CreateFilterAlertInput) GetQueryOwnershipType() QueryOwnershipType { + return v.QueryOwnershipType +} + +// __CreateHumioRepoActionInput is used internally by genqlient +type __CreateHumioRepoActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + IngestToken string `json:"IngestToken"` +} + +// GetSearchDomainName returns __CreateHumioRepoActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateHumioRepoActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateHumioRepoActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateHumioRepoActionInput) GetActionName() string { return v.ActionName } + +// GetIngestToken returns __CreateHumioRepoActionInput.IngestToken, and is useful for accessing the field via an interface. +func (v *__CreateHumioRepoActionInput) GetIngestToken() string { return v.IngestToken } + +// __CreateOpsGenieActionInput is used internally by genqlient +type __CreateOpsGenieActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + ApiUrl string `json:"ApiUrl"` + GenieKey string `json:"GenieKey"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreateOpsGenieActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateOpsGenieActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateOpsGenieActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateOpsGenieActionInput) GetActionName() string { return v.ActionName } + +// GetApiUrl returns __CreateOpsGenieActionInput.ApiUrl, and is useful for accessing the field via an interface. +func (v *__CreateOpsGenieActionInput) GetApiUrl() string { return v.ApiUrl } + +// GetGenieKey returns __CreateOpsGenieActionInput.GenieKey, and is useful for accessing the field via an interface. +func (v *__CreateOpsGenieActionInput) GetGenieKey() string { return v.GenieKey } + +// GetUseProxy returns __CreateOpsGenieActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreateOpsGenieActionInput) GetUseProxy() bool { return v.UseProxy } + +// __CreatePagerDutyActionInput is used internally by genqlient +type __CreatePagerDutyActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + Severity string `json:"Severity"` + RoutingKey string `json:"RoutingKey"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreatePagerDutyActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreatePagerDutyActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreatePagerDutyActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreatePagerDutyActionInput) GetActionName() string { return v.ActionName } + +// GetSeverity returns __CreatePagerDutyActionInput.Severity, and is useful for accessing the field via an interface. +func (v *__CreatePagerDutyActionInput) GetSeverity() string { return v.Severity } + +// GetRoutingKey returns __CreatePagerDutyActionInput.RoutingKey, and is useful for accessing the field via an interface. +func (v *__CreatePagerDutyActionInput) GetRoutingKey() string { return v.RoutingKey } + +// GetUseProxy returns __CreatePagerDutyActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreatePagerDutyActionInput) GetUseProxy() bool { return v.UseProxy } + +// __CreateParserOrUpdateInput is used internally by genqlient +type __CreateParserOrUpdateInput struct { + RepositoryName string `json:"RepositoryName"` + Name string `json:"Name"` + Script string `json:"Script"` + TestCases []ParserTestCaseInput `json:"TestCases"` + FieldsToTag []string `json:"FieldsToTag"` + FieldsToBeRemovedBeforeParsing []string `json:"FieldsToBeRemovedBeforeParsing"` + AllowOverridingExistingParser bool `json:"AllowOverridingExistingParser"` +} + +// GetRepositoryName returns __CreateParserOrUpdateInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetRepositoryName() string { return v.RepositoryName } + +// GetName returns __CreateParserOrUpdateInput.Name, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetName() string { return v.Name } + +// GetScript returns __CreateParserOrUpdateInput.Script, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetScript() string { return v.Script } + +// GetTestCases returns __CreateParserOrUpdateInput.TestCases, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetTestCases() []ParserTestCaseInput { return v.TestCases } + +// GetFieldsToTag returns __CreateParserOrUpdateInput.FieldsToTag, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetFieldsToTag() []string { return v.FieldsToTag } + +// GetFieldsToBeRemovedBeforeParsing returns __CreateParserOrUpdateInput.FieldsToBeRemovedBeforeParsing, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetFieldsToBeRemovedBeforeParsing() []string { + return v.FieldsToBeRemovedBeforeParsing +} + +// GetAllowOverridingExistingParser returns __CreateParserOrUpdateInput.AllowOverridingExistingParser, and is useful for accessing the field via an interface. +func (v *__CreateParserOrUpdateInput) GetAllowOverridingExistingParser() bool { + return v.AllowOverridingExistingParser +} + +// __CreateRepositoryInput is used internally by genqlient +type __CreateRepositoryInput struct { + RepositoryName string `json:"RepositoryName"` +} + +// GetRepositoryName returns __CreateRepositoryInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__CreateRepositoryInput) GetRepositoryName() string { return v.RepositoryName } + +// __CreateScheduledSearchInput is used internally by genqlient +type __CreateScheduledSearchInput struct { + SearchDomainName string `json:"SearchDomainName"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + QueryStart string `json:"QueryStart"` + QueryEnd string `json:"QueryEnd"` + Schedule string `json:"Schedule"` + TimeZone string `json:"TimeZone"` + BackfillLimit int `json:"BackfillLimit"` + Enabled bool `json:"Enabled"` + ActionIdsOrNames []string `json:"ActionIdsOrNames"` + Labels []string `json:"Labels"` + QueryOwnershipType *QueryOwnershipType `json:"QueryOwnershipType"` +} + +// GetSearchDomainName returns __CreateScheduledSearchInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetName returns __CreateScheduledSearchInput.Name, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetName() string { return v.Name } + +// GetDescription returns __CreateScheduledSearchInput.Description, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __CreateScheduledSearchInput.QueryString, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetQueryString() string { return v.QueryString } + +// GetQueryStart returns __CreateScheduledSearchInput.QueryStart, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetQueryStart() string { return v.QueryStart } + +// GetQueryEnd returns __CreateScheduledSearchInput.QueryEnd, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetQueryEnd() string { return v.QueryEnd } + +// GetSchedule returns __CreateScheduledSearchInput.Schedule, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetSchedule() string { return v.Schedule } + +// GetTimeZone returns __CreateScheduledSearchInput.TimeZone, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetTimeZone() string { return v.TimeZone } + +// GetBackfillLimit returns __CreateScheduledSearchInput.BackfillLimit, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetBackfillLimit() int { return v.BackfillLimit } + +// GetEnabled returns __CreateScheduledSearchInput.Enabled, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetEnabled() bool { return v.Enabled } + +// GetActionIdsOrNames returns __CreateScheduledSearchInput.ActionIdsOrNames, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetActionIdsOrNames() []string { return v.ActionIdsOrNames } + +// GetLabels returns __CreateScheduledSearchInput.Labels, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetLabels() []string { return v.Labels } + +// GetQueryOwnershipType returns __CreateScheduledSearchInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__CreateScheduledSearchInput) GetQueryOwnershipType() *QueryOwnershipType { + return v.QueryOwnershipType +} + +// __CreateSlackActionInput is used internally by genqlient +type __CreateSlackActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + Fields []SlackFieldEntryInput `json:"Fields"` + Url string `json:"Url"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreateSlackActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateSlackActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateSlackActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateSlackActionInput) GetActionName() string { return v.ActionName } + +// GetFields returns __CreateSlackActionInput.Fields, and is useful for accessing the field via an interface. +func (v *__CreateSlackActionInput) GetFields() []SlackFieldEntryInput { return v.Fields } + +// GetUrl returns __CreateSlackActionInput.Url, and is useful for accessing the field via an interface. +func (v *__CreateSlackActionInput) GetUrl() string { return v.Url } + +// GetUseProxy returns __CreateSlackActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreateSlackActionInput) GetUseProxy() bool { return v.UseProxy } + +// __CreateSlackPostMessageActionInput is used internally by genqlient +type __CreateSlackPostMessageActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + ApiToken string `json:"ApiToken"` + Channels []string `json:"Channels"` + Fields []SlackFieldEntryInput `json:"Fields"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreateSlackPostMessageActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateSlackPostMessageActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateSlackPostMessageActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateSlackPostMessageActionInput) GetActionName() string { return v.ActionName } + +// GetApiToken returns __CreateSlackPostMessageActionInput.ApiToken, and is useful for accessing the field via an interface. +func (v *__CreateSlackPostMessageActionInput) GetApiToken() string { return v.ApiToken } + +// GetChannels returns __CreateSlackPostMessageActionInput.Channels, and is useful for accessing the field via an interface. +func (v *__CreateSlackPostMessageActionInput) GetChannels() []string { return v.Channels } + +// GetFields returns __CreateSlackPostMessageActionInput.Fields, and is useful for accessing the field via an interface. +func (v *__CreateSlackPostMessageActionInput) GetFields() []SlackFieldEntryInput { return v.Fields } + +// GetUseProxy returns __CreateSlackPostMessageActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreateSlackPostMessageActionInput) GetUseProxy() bool { return v.UseProxy } + +// __CreateVictorOpsActionInput is used internally by genqlient +type __CreateVictorOpsActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + MessageType string `json:"MessageType"` + NotifyUrl string `json:"NotifyUrl"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreateVictorOpsActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateVictorOpsActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateVictorOpsActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateVictorOpsActionInput) GetActionName() string { return v.ActionName } + +// GetMessageType returns __CreateVictorOpsActionInput.MessageType, and is useful for accessing the field via an interface. +func (v *__CreateVictorOpsActionInput) GetMessageType() string { return v.MessageType } + +// GetNotifyUrl returns __CreateVictorOpsActionInput.NotifyUrl, and is useful for accessing the field via an interface. +func (v *__CreateVictorOpsActionInput) GetNotifyUrl() string { return v.NotifyUrl } + +// GetUseProxy returns __CreateVictorOpsActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreateVictorOpsActionInput) GetUseProxy() bool { return v.UseProxy } + +// __CreateViewInput is used internally by genqlient +type __CreateViewInput struct { + ViewName string `json:"ViewName"` + Description *string `json:"Description"` + Connections []ViewConnectionInput `json:"Connections"` +} + +// GetViewName returns __CreateViewInput.ViewName, and is useful for accessing the field via an interface. +func (v *__CreateViewInput) GetViewName() string { return v.ViewName } + +// GetDescription returns __CreateViewInput.Description, and is useful for accessing the field via an interface. +func (v *__CreateViewInput) GetDescription() *string { return v.Description } + +// GetConnections returns __CreateViewInput.Connections, and is useful for accessing the field via an interface. +func (v *__CreateViewInput) GetConnections() []ViewConnectionInput { return v.Connections } + +// __CreateWebhookActionInput is used internally by genqlient +type __CreateWebhookActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionName string `json:"ActionName"` + Url string `json:"Url"` + Method string `json:"Method"` + Headers []HttpHeaderEntryInput `json:"Headers"` + BodyTemplate string `json:"BodyTemplate"` + IgnoreSSL bool `json:"IgnoreSSL"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __CreateWebhookActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionName returns __CreateWebhookActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetActionName() string { return v.ActionName } + +// GetUrl returns __CreateWebhookActionInput.Url, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetUrl() string { return v.Url } + +// GetMethod returns __CreateWebhookActionInput.Method, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetMethod() string { return v.Method } + +// GetHeaders returns __CreateWebhookActionInput.Headers, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetHeaders() []HttpHeaderEntryInput { return v.Headers } + +// GetBodyTemplate returns __CreateWebhookActionInput.BodyTemplate, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetBodyTemplate() string { return v.BodyTemplate } + +// GetIgnoreSSL returns __CreateWebhookActionInput.IgnoreSSL, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetIgnoreSSL() bool { return v.IgnoreSSL } + +// GetUseProxy returns __CreateWebhookActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__CreateWebhookActionInput) GetUseProxy() bool { return v.UseProxy } + +// __DeleteActionByIDInput is used internally by genqlient +type __DeleteActionByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` +} + +// GetSearchDomainName returns __DeleteActionByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__DeleteActionByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __DeleteActionByIDInput.ActionID, and is useful for accessing the field via an interface. +func (v *__DeleteActionByIDInput) GetActionID() string { return v.ActionID } + +// __DeleteAggregateAlertInput is used internally by genqlient +type __DeleteAggregateAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + AggregateAlertID string `json:"AggregateAlertID"` +} + +// GetSearchDomainName returns __DeleteAggregateAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__DeleteAggregateAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetAggregateAlertID returns __DeleteAggregateAlertInput.AggregateAlertID, and is useful for accessing the field via an interface. +func (v *__DeleteAggregateAlertInput) GetAggregateAlertID() string { return v.AggregateAlertID } + +// __DeleteAlertByIDInput is used internally by genqlient +type __DeleteAlertByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + AlertID string `json:"AlertID"` +} + +// GetSearchDomainName returns __DeleteAlertByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__DeleteAlertByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetAlertID returns __DeleteAlertByIDInput.AlertID, and is useful for accessing the field via an interface. +func (v *__DeleteAlertByIDInput) GetAlertID() string { return v.AlertID } + +// __DeleteFilterAlertInput is used internally by genqlient +type __DeleteFilterAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + FilterAlertID string `json:"FilterAlertID"` +} + +// GetSearchDomainName returns __DeleteFilterAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__DeleteFilterAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetFilterAlertID returns __DeleteFilterAlertInput.FilterAlertID, and is useful for accessing the field via an interface. +func (v *__DeleteFilterAlertInput) GetFilterAlertID() string { return v.FilterAlertID } + +// __DeleteParserByIDInput is used internally by genqlient +type __DeleteParserByIDInput struct { + RepositoryName string `json:"RepositoryName"` + ParserID string `json:"ParserID"` +} + +// GetRepositoryName returns __DeleteParserByIDInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__DeleteParserByIDInput) GetRepositoryName() string { return v.RepositoryName } + +// GetParserID returns __DeleteParserByIDInput.ParserID, and is useful for accessing the field via an interface. +func (v *__DeleteParserByIDInput) GetParserID() string { return v.ParserID } + +// __DeleteScheduledSearchByIDInput is used internally by genqlient +type __DeleteScheduledSearchByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + ScheduledSearchID string `json:"ScheduledSearchID"` +} + +// GetSearchDomainName returns __DeleteScheduledSearchByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__DeleteScheduledSearchByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetScheduledSearchID returns __DeleteScheduledSearchByIDInput.ScheduledSearchID, and is useful for accessing the field via an interface. +func (v *__DeleteScheduledSearchByIDInput) GetScheduledSearchID() string { return v.ScheduledSearchID } + +// __DeleteSearchDomainInput is used internally by genqlient +type __DeleteSearchDomainInput struct { + SearchDomainName string `json:"SearchDomainName"` + DeleteMessage string `json:"DeleteMessage"` +} + +// GetSearchDomainName returns __DeleteSearchDomainInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__DeleteSearchDomainInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetDeleteMessage returns __DeleteSearchDomainInput.DeleteMessage, and is useful for accessing the field via an interface. +func (v *__DeleteSearchDomainInput) GetDeleteMessage() string { return v.DeleteMessage } + +// __DisableS3ArchivingInput is used internally by genqlient +type __DisableS3ArchivingInput struct { + RepositoryName string `json:"RepositoryName"` +} + +// GetRepositoryName returns __DisableS3ArchivingInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__DisableS3ArchivingInput) GetRepositoryName() string { return v.RepositoryName } + +// __EnableS3ArchivingInput is used internally by genqlient +type __EnableS3ArchivingInput struct { + RepositoryName string `json:"RepositoryName"` +} + +// GetRepositoryName returns __EnableS3ArchivingInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__EnableS3ArchivingInput) GetRepositoryName() string { return v.RepositoryName } + +// __GetActionByIDInput is used internally by genqlient +type __GetActionByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` +} + +// GetSearchDomainName returns __GetActionByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__GetActionByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __GetActionByIDInput.ActionID, and is useful for accessing the field via an interface. +func (v *__GetActionByIDInput) GetActionID() string { return v.ActionID } + +// __GetAggregateAlertByIDInput is used internally by genqlient +type __GetAggregateAlertByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + AggregateAlertID string `json:"AggregateAlertID"` +} + +// GetSearchDomainName returns __GetAggregateAlertByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__GetAggregateAlertByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetAggregateAlertID returns __GetAggregateAlertByIDInput.AggregateAlertID, and is useful for accessing the field via an interface. +func (v *__GetAggregateAlertByIDInput) GetAggregateAlertID() string { return v.AggregateAlertID } + +// __GetFilterAlertByIDInput is used internally by genqlient +type __GetFilterAlertByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + FilterAlertID string `json:"FilterAlertID"` +} + +// GetSearchDomainName returns __GetFilterAlertByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__GetFilterAlertByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetFilterAlertID returns __GetFilterAlertByIDInput.FilterAlertID, and is useful for accessing the field via an interface. +func (v *__GetFilterAlertByIDInput) GetFilterAlertID() string { return v.FilterAlertID } + +// __GetParserByIDInput is used internally by genqlient +type __GetParserByIDInput struct { + RepositoryName string `json:"RepositoryName"` + ParserID string `json:"ParserID"` +} + +// GetRepositoryName returns __GetParserByIDInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__GetParserByIDInput) GetRepositoryName() string { return v.RepositoryName } + +// GetParserID returns __GetParserByIDInput.ParserID, and is useful for accessing the field via an interface. +func (v *__GetParserByIDInput) GetParserID() string { return v.ParserID } + +// __GetRepositoryInput is used internally by genqlient +type __GetRepositoryInput struct { + RepositoryName string `json:"RepositoryName"` +} + +// GetRepositoryName returns __GetRepositoryInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__GetRepositoryInput) GetRepositoryName() string { return v.RepositoryName } + +// __GetScheduledSearchByIDInput is used internally by genqlient +type __GetScheduledSearchByIDInput struct { + SearchDomainName string `json:"SearchDomainName"` + ScheduledSearchID string `json:"ScheduledSearchID"` +} + +// GetSearchDomainName returns __GetScheduledSearchByIDInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__GetScheduledSearchByIDInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetScheduledSearchID returns __GetScheduledSearchByIDInput.ScheduledSearchID, and is useful for accessing the field via an interface. +func (v *__GetScheduledSearchByIDInput) GetScheduledSearchID() string { return v.ScheduledSearchID } + +// __GetSearchDomainInput is used internally by genqlient +type __GetSearchDomainInput struct { + SearchDomainName string `json:"SearchDomainName"` +} + +// GetSearchDomainName returns __GetSearchDomainInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__GetSearchDomainInput) GetSearchDomainName() string { return v.SearchDomainName } + +// __GetUsersByUsernameInput is used internally by genqlient +type __GetUsersByUsernameInput struct { + Username string `json:"Username"` +} + +// GetUsername returns __GetUsersByUsernameInput.Username, and is useful for accessing the field via an interface. +func (v *__GetUsersByUsernameInput) GetUsername() string { return v.Username } + +// __ListActionsInput is used internally by genqlient +type __ListActionsInput struct { + SearchDomainName string `json:"SearchDomainName"` +} + +// GetSearchDomainName returns __ListActionsInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__ListActionsInput) GetSearchDomainName() string { return v.SearchDomainName } + +// __ListAggregateAlertsInput is used internally by genqlient +type __ListAggregateAlertsInput struct { + SearchDomainName string `json:"SearchDomainName"` +} + +// GetSearchDomainName returns __ListAggregateAlertsInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__ListAggregateAlertsInput) GetSearchDomainName() string { return v.SearchDomainName } + +// __ListAlertsInput is used internally by genqlient +type __ListAlertsInput struct { + SearchDomainName string `json:"SearchDomainName"` +} + +// GetSearchDomainName returns __ListAlertsInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__ListAlertsInput) GetSearchDomainName() string { return v.SearchDomainName } + +// __ListFilterAlertsInput is used internally by genqlient +type __ListFilterAlertsInput struct { + SearchDomainName string `json:"SearchDomainName"` +} + +// GetSearchDomainName returns __ListFilterAlertsInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__ListFilterAlertsInput) GetSearchDomainName() string { return v.SearchDomainName } + +// __ListIngestTokensInput is used internally by genqlient +type __ListIngestTokensInput struct { + RepositoryName string `json:"RepositoryName"` +} + +// GetRepositoryName returns __ListIngestTokensInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__ListIngestTokensInput) GetRepositoryName() string { return v.RepositoryName } + +// __ListParsersInput is used internally by genqlient +type __ListParsersInput struct { + RepositoryName string `json:"RepositoryName"` +} + +// GetRepositoryName returns __ListParsersInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__ListParsersInput) GetRepositoryName() string { return v.RepositoryName } + +// __ListScheduledSearchesInput is used internally by genqlient +type __ListScheduledSearchesInput struct { + SearchDomainName string `json:"SearchDomainName"` +} + +// GetSearchDomainName returns __ListScheduledSearchesInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__ListScheduledSearchesInput) GetSearchDomainName() string { return v.SearchDomainName } + +// __RemoveIngestTokenInput is used internally by genqlient +type __RemoveIngestTokenInput struct { + RepositoryName string `json:"RepositoryName"` + Name string `json:"Name"` +} + +// GetRepositoryName returns __RemoveIngestTokenInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__RemoveIngestTokenInput) GetRepositoryName() string { return v.RepositoryName } + +// GetName returns __RemoveIngestTokenInput.Name, and is useful for accessing the field via an interface. +func (v *__RemoveIngestTokenInput) GetName() string { return v.Name } + +// __RotateTokenByIDInput is used internally by genqlient +type __RotateTokenByIDInput struct { + TokenID string `json:"TokenID"` +} + +// GetTokenID returns __RotateTokenByIDInput.TokenID, and is useful for accessing the field via an interface. +func (v *__RotateTokenByIDInput) GetTokenID() string { return v.TokenID } + +// __SetAutomaticSearchingInput is used internally by genqlient +type __SetAutomaticSearchingInput struct { + SearchDomainName string `json:"SearchDomainName"` + AutomaticSearch bool `json:"AutomaticSearch"` +} + +// GetSearchDomainName returns __SetAutomaticSearchingInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__SetAutomaticSearchingInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetAutomaticSearch returns __SetAutomaticSearchingInput.AutomaticSearch, and is useful for accessing the field via an interface. +func (v *__SetAutomaticSearchingInput) GetAutomaticSearch() bool { return v.AutomaticSearch } + +// __UnassignParserToIngestTokenInput is used internally by genqlient +type __UnassignParserToIngestTokenInput struct { + RepositoryName string `json:"RepositoryName"` + IngestTokenName string `json:"IngestTokenName"` +} + +// GetRepositoryName returns __UnassignParserToIngestTokenInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__UnassignParserToIngestTokenInput) GetRepositoryName() string { return v.RepositoryName } + +// GetIngestTokenName returns __UnassignParserToIngestTokenInput.IngestTokenName, and is useful for accessing the field via an interface. +func (v *__UnassignParserToIngestTokenInput) GetIngestTokenName() string { return v.IngestTokenName } + +// __UpdateAggregateAlertInput is used internally by genqlient +type __UpdateAggregateAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + ID string `json:"ID"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + SearchIntervalSeconds int64 `json:"SearchIntervalSeconds"` + ActionIdsOrNames []string `json:"ActionIdsOrNames"` + Labels []string `json:"Labels"` + Enabled bool `json:"Enabled"` + ThrottleField *string `json:"ThrottleField"` + ThrottleTimeSeconds int64 `json:"ThrottleTimeSeconds"` + TriggerMode TriggerMode `json:"TriggerMode"` + QueryTimestampMode QueryTimestampType `json:"QueryTimestampMode"` + QueryOwnershipType QueryOwnershipType `json:"QueryOwnershipType"` +} + +// GetSearchDomainName returns __UpdateAggregateAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetID returns __UpdateAggregateAlertInput.ID, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetID() string { return v.ID } + +// GetName returns __UpdateAggregateAlertInput.Name, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetName() string { return v.Name } + +// GetDescription returns __UpdateAggregateAlertInput.Description, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __UpdateAggregateAlertInput.QueryString, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetQueryString() string { return v.QueryString } + +// GetSearchIntervalSeconds returns __UpdateAggregateAlertInput.SearchIntervalSeconds, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetSearchIntervalSeconds() int64 { + return v.SearchIntervalSeconds +} + +// GetActionIdsOrNames returns __UpdateAggregateAlertInput.ActionIdsOrNames, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetActionIdsOrNames() []string { return v.ActionIdsOrNames } + +// GetLabels returns __UpdateAggregateAlertInput.Labels, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetLabels() []string { return v.Labels } + +// GetEnabled returns __UpdateAggregateAlertInput.Enabled, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetEnabled() bool { return v.Enabled } + +// GetThrottleField returns __UpdateAggregateAlertInput.ThrottleField, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetThrottleField() *string { return v.ThrottleField } + +// GetThrottleTimeSeconds returns __UpdateAggregateAlertInput.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetThrottleTimeSeconds() int64 { return v.ThrottleTimeSeconds } + +// GetTriggerMode returns __UpdateAggregateAlertInput.TriggerMode, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetTriggerMode() TriggerMode { return v.TriggerMode } + +// GetQueryTimestampMode returns __UpdateAggregateAlertInput.QueryTimestampMode, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetQueryTimestampMode() QueryTimestampType { + return v.QueryTimestampMode +} + +// GetQueryOwnershipType returns __UpdateAggregateAlertInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__UpdateAggregateAlertInput) GetQueryOwnershipType() QueryOwnershipType { + return v.QueryOwnershipType +} + +// __UpdateAlertInput is used internally by genqlient +type __UpdateAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + AlertID string `json:"AlertID"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + QueryStart string `json:"QueryStart"` + ThrottleTimeMillis int64 `json:"ThrottleTimeMillis"` + Enabled bool `json:"Enabled"` + Actions []string `json:"Actions"` + Labels []string `json:"Labels"` + QueryOwnershipType *QueryOwnershipType `json:"QueryOwnershipType"` + ThrottleField *string `json:"ThrottleField"` +} + +// GetSearchDomainName returns __UpdateAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetAlertID returns __UpdateAlertInput.AlertID, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetAlertID() string { return v.AlertID } + +// GetName returns __UpdateAlertInput.Name, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetName() string { return v.Name } + +// GetDescription returns __UpdateAlertInput.Description, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __UpdateAlertInput.QueryString, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetQueryString() string { return v.QueryString } + +// GetQueryStart returns __UpdateAlertInput.QueryStart, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetQueryStart() string { return v.QueryStart } + +// GetThrottleTimeMillis returns __UpdateAlertInput.ThrottleTimeMillis, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetThrottleTimeMillis() int64 { return v.ThrottleTimeMillis } + +// GetEnabled returns __UpdateAlertInput.Enabled, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetEnabled() bool { return v.Enabled } + +// GetActions returns __UpdateAlertInput.Actions, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetActions() []string { return v.Actions } + +// GetLabels returns __UpdateAlertInput.Labels, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetLabels() []string { return v.Labels } + +// GetQueryOwnershipType returns __UpdateAlertInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetQueryOwnershipType() *QueryOwnershipType { return v.QueryOwnershipType } + +// GetThrottleField returns __UpdateAlertInput.ThrottleField, and is useful for accessing the field via an interface. +func (v *__UpdateAlertInput) GetThrottleField() *string { return v.ThrottleField } + +// __UpdateDescriptionForSearchDomainInput is used internally by genqlient +type __UpdateDescriptionForSearchDomainInput struct { + SearchDomainName string `json:"SearchDomainName"` + NewDescription string `json:"NewDescription"` +} + +// GetSearchDomainName returns __UpdateDescriptionForSearchDomainInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateDescriptionForSearchDomainInput) GetSearchDomainName() string { + return v.SearchDomainName +} + +// GetNewDescription returns __UpdateDescriptionForSearchDomainInput.NewDescription, and is useful for accessing the field via an interface. +func (v *__UpdateDescriptionForSearchDomainInput) GetNewDescription() string { return v.NewDescription } + +// __UpdateEmailActionInput is used internally by genqlient +type __UpdateEmailActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + Recipients []string `json:"Recipients"` + SubjectTemplate *string `json:"SubjectTemplate"` + BodyTemplate *string `json:"BodyTemplate"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdateEmailActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateEmailActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateEmailActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetActionName() string { return v.ActionName } + +// GetRecipients returns __UpdateEmailActionInput.Recipients, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetRecipients() []string { return v.Recipients } + +// GetSubjectTemplate returns __UpdateEmailActionInput.SubjectTemplate, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetSubjectTemplate() *string { return v.SubjectTemplate } + +// GetBodyTemplate returns __UpdateEmailActionInput.BodyTemplate, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetBodyTemplate() *string { return v.BodyTemplate } + +// GetUseProxy returns __UpdateEmailActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdateEmailActionInput) GetUseProxy() bool { return v.UseProxy } + +// __UpdateFilterAlertInput is used internally by genqlient +type __UpdateFilterAlertInput struct { + SearchDomainName string `json:"SearchDomainName"` + ID string `json:"ID"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + ActionIdsOrNames []string `json:"ActionIdsOrNames"` + Labels []string `json:"Labels"` + Enabled bool `json:"Enabled"` + ThrottleField *string `json:"ThrottleField"` + ThrottleTimeSeconds int64 `json:"ThrottleTimeSeconds"` + QueryOwnershipType QueryOwnershipType `json:"QueryOwnershipType"` +} + +// GetSearchDomainName returns __UpdateFilterAlertInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetID returns __UpdateFilterAlertInput.ID, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetID() string { return v.ID } + +// GetName returns __UpdateFilterAlertInput.Name, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetName() string { return v.Name } + +// GetDescription returns __UpdateFilterAlertInput.Description, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __UpdateFilterAlertInput.QueryString, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetQueryString() string { return v.QueryString } + +// GetActionIdsOrNames returns __UpdateFilterAlertInput.ActionIdsOrNames, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetActionIdsOrNames() []string { return v.ActionIdsOrNames } + +// GetLabels returns __UpdateFilterAlertInput.Labels, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetLabels() []string { return v.Labels } + +// GetEnabled returns __UpdateFilterAlertInput.Enabled, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetEnabled() bool { return v.Enabled } + +// GetThrottleField returns __UpdateFilterAlertInput.ThrottleField, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetThrottleField() *string { return v.ThrottleField } + +// GetThrottleTimeSeconds returns __UpdateFilterAlertInput.ThrottleTimeSeconds, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetThrottleTimeSeconds() int64 { return v.ThrottleTimeSeconds } + +// GetQueryOwnershipType returns __UpdateFilterAlertInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__UpdateFilterAlertInput) GetQueryOwnershipType() QueryOwnershipType { + return v.QueryOwnershipType +} + +// __UpdateHumioRepoActionInput is used internally by genqlient +type __UpdateHumioRepoActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + IngestToken string `json:"IngestToken"` +} + +// GetSearchDomainName returns __UpdateHumioRepoActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateHumioRepoActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateHumioRepoActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateHumioRepoActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateHumioRepoActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateHumioRepoActionInput) GetActionName() string { return v.ActionName } + +// GetIngestToken returns __UpdateHumioRepoActionInput.IngestToken, and is useful for accessing the field via an interface. +func (v *__UpdateHumioRepoActionInput) GetIngestToken() string { return v.IngestToken } + +// __UpdateIngestBasedRetentionInput is used internally by genqlient +type __UpdateIngestBasedRetentionInput struct { + RepositoryName string `json:"RepositoryName"` + IngestInGB *float64 `json:"IngestInGB"` +} + +// GetRepositoryName returns __UpdateIngestBasedRetentionInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__UpdateIngestBasedRetentionInput) GetRepositoryName() string { return v.RepositoryName } + +// GetIngestInGB returns __UpdateIngestBasedRetentionInput.IngestInGB, and is useful for accessing the field via an interface. +func (v *__UpdateIngestBasedRetentionInput) GetIngestInGB() *float64 { return v.IngestInGB } + +// __UpdateLicenseKeyInput is used internally by genqlient +type __UpdateLicenseKeyInput struct { + LicenseKey string `json:"LicenseKey"` +} + +// GetLicenseKey returns __UpdateLicenseKeyInput.LicenseKey, and is useful for accessing the field via an interface. +func (v *__UpdateLicenseKeyInput) GetLicenseKey() string { return v.LicenseKey } + +// __UpdateOpsGenieActionInput is used internally by genqlient +type __UpdateOpsGenieActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + ApiUrl string `json:"ApiUrl"` + GenieKey string `json:"GenieKey"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdateOpsGenieActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateOpsGenieActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateOpsGenieActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateOpsGenieActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateOpsGenieActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateOpsGenieActionInput) GetActionName() string { return v.ActionName } + +// GetApiUrl returns __UpdateOpsGenieActionInput.ApiUrl, and is useful for accessing the field via an interface. +func (v *__UpdateOpsGenieActionInput) GetApiUrl() string { return v.ApiUrl } + +// GetGenieKey returns __UpdateOpsGenieActionInput.GenieKey, and is useful for accessing the field via an interface. +func (v *__UpdateOpsGenieActionInput) GetGenieKey() string { return v.GenieKey } + +// GetUseProxy returns __UpdateOpsGenieActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdateOpsGenieActionInput) GetUseProxy() bool { return v.UseProxy } + +// __UpdatePagerDutyActionInput is used internally by genqlient +type __UpdatePagerDutyActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + Severity string `json:"Severity"` + RoutingKey string `json:"RoutingKey"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdatePagerDutyActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdatePagerDutyActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdatePagerDutyActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdatePagerDutyActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdatePagerDutyActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdatePagerDutyActionInput) GetActionName() string { return v.ActionName } + +// GetSeverity returns __UpdatePagerDutyActionInput.Severity, and is useful for accessing the field via an interface. +func (v *__UpdatePagerDutyActionInput) GetSeverity() string { return v.Severity } + +// GetRoutingKey returns __UpdatePagerDutyActionInput.RoutingKey, and is useful for accessing the field via an interface. +func (v *__UpdatePagerDutyActionInput) GetRoutingKey() string { return v.RoutingKey } + +// GetUseProxy returns __UpdatePagerDutyActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdatePagerDutyActionInput) GetUseProxy() bool { return v.UseProxy } + +// __UpdateS3ArchivingConfigurationInput is used internally by genqlient +type __UpdateS3ArchivingConfigurationInput struct { + RepositoryName string `json:"RepositoryName"` + BucketName string `json:"BucketName"` + BucketRegion string `json:"BucketRegion"` + Format S3ArchivingFormat `json:"Format"` +} + +// GetRepositoryName returns __UpdateS3ArchivingConfigurationInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__UpdateS3ArchivingConfigurationInput) GetRepositoryName() string { return v.RepositoryName } + +// GetBucketName returns __UpdateS3ArchivingConfigurationInput.BucketName, and is useful for accessing the field via an interface. +func (v *__UpdateS3ArchivingConfigurationInput) GetBucketName() string { return v.BucketName } + +// GetBucketRegion returns __UpdateS3ArchivingConfigurationInput.BucketRegion, and is useful for accessing the field via an interface. +func (v *__UpdateS3ArchivingConfigurationInput) GetBucketRegion() string { return v.BucketRegion } + +// GetFormat returns __UpdateS3ArchivingConfigurationInput.Format, and is useful for accessing the field via an interface. +func (v *__UpdateS3ArchivingConfigurationInput) GetFormat() S3ArchivingFormat { return v.Format } + +// __UpdateScheduledSearchInput is used internally by genqlient +type __UpdateScheduledSearchInput struct { + SearchDomainName string `json:"SearchDomainName"` + ID string `json:"ID"` + Name string `json:"Name"` + Description *string `json:"Description"` + QueryString string `json:"QueryString"` + QueryStart string `json:"QueryStart"` + QueryEnd string `json:"QueryEnd"` + Schedule string `json:"Schedule"` + TimeZone string `json:"TimeZone"` + BackfillLimit int `json:"BackfillLimit"` + Enabled bool `json:"Enabled"` + ActionIdsOrNames []string `json:"ActionIdsOrNames"` + Labels []string `json:"Labels"` + QueryOwnershipType *QueryOwnershipType `json:"QueryOwnershipType"` +} + +// GetSearchDomainName returns __UpdateScheduledSearchInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetID returns __UpdateScheduledSearchInput.ID, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetID() string { return v.ID } + +// GetName returns __UpdateScheduledSearchInput.Name, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetName() string { return v.Name } + +// GetDescription returns __UpdateScheduledSearchInput.Description, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetDescription() *string { return v.Description } + +// GetQueryString returns __UpdateScheduledSearchInput.QueryString, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetQueryString() string { return v.QueryString } + +// GetQueryStart returns __UpdateScheduledSearchInput.QueryStart, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetQueryStart() string { return v.QueryStart } + +// GetQueryEnd returns __UpdateScheduledSearchInput.QueryEnd, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetQueryEnd() string { return v.QueryEnd } + +// GetSchedule returns __UpdateScheduledSearchInput.Schedule, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetSchedule() string { return v.Schedule } + +// GetTimeZone returns __UpdateScheduledSearchInput.TimeZone, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetTimeZone() string { return v.TimeZone } + +// GetBackfillLimit returns __UpdateScheduledSearchInput.BackfillLimit, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetBackfillLimit() int { return v.BackfillLimit } + +// GetEnabled returns __UpdateScheduledSearchInput.Enabled, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetEnabled() bool { return v.Enabled } + +// GetActionIdsOrNames returns __UpdateScheduledSearchInput.ActionIdsOrNames, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetActionIdsOrNames() []string { return v.ActionIdsOrNames } + +// GetLabels returns __UpdateScheduledSearchInput.Labels, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetLabels() []string { return v.Labels } + +// GetQueryOwnershipType returns __UpdateScheduledSearchInput.QueryOwnershipType, and is useful for accessing the field via an interface. +func (v *__UpdateScheduledSearchInput) GetQueryOwnershipType() *QueryOwnershipType { + return v.QueryOwnershipType +} + +// __UpdateSlackActionInput is used internally by genqlient +type __UpdateSlackActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + Fields []SlackFieldEntryInput `json:"Fields"` + Url string `json:"Url"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdateSlackActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateSlackActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateSlackActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateSlackActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateSlackActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateSlackActionInput) GetActionName() string { return v.ActionName } + +// GetFields returns __UpdateSlackActionInput.Fields, and is useful for accessing the field via an interface. +func (v *__UpdateSlackActionInput) GetFields() []SlackFieldEntryInput { return v.Fields } + +// GetUrl returns __UpdateSlackActionInput.Url, and is useful for accessing the field via an interface. +func (v *__UpdateSlackActionInput) GetUrl() string { return v.Url } + +// GetUseProxy returns __UpdateSlackActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdateSlackActionInput) GetUseProxy() bool { return v.UseProxy } + +// __UpdateSlackPostMessageActionInput is used internally by genqlient +type __UpdateSlackPostMessageActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + ApiToken string `json:"ApiToken"` + Channels []string `json:"Channels"` + Fields []SlackFieldEntryInput `json:"Fields"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdateSlackPostMessageActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateSlackPostMessageActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateSlackPostMessageActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetActionName() string { return v.ActionName } + +// GetApiToken returns __UpdateSlackPostMessageActionInput.ApiToken, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetApiToken() string { return v.ApiToken } + +// GetChannels returns __UpdateSlackPostMessageActionInput.Channels, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetChannels() []string { return v.Channels } + +// GetFields returns __UpdateSlackPostMessageActionInput.Fields, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetFields() []SlackFieldEntryInput { return v.Fields } + +// GetUseProxy returns __UpdateSlackPostMessageActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdateSlackPostMessageActionInput) GetUseProxy() bool { return v.UseProxy } + +// __UpdateStorageBasedRetentionInput is used internally by genqlient +type __UpdateStorageBasedRetentionInput struct { + RepositoryName string `json:"RepositoryName"` + StorageInGB *float64 `json:"StorageInGB"` +} + +// GetRepositoryName returns __UpdateStorageBasedRetentionInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__UpdateStorageBasedRetentionInput) GetRepositoryName() string { return v.RepositoryName } + +// GetStorageInGB returns __UpdateStorageBasedRetentionInput.StorageInGB, and is useful for accessing the field via an interface. +func (v *__UpdateStorageBasedRetentionInput) GetStorageInGB() *float64 { return v.StorageInGB } + +// __UpdateTimeBasedRetentionInput is used internally by genqlient +type __UpdateTimeBasedRetentionInput struct { + RepositoryName string `json:"RepositoryName"` + RetentionInDays *float64 `json:"RetentionInDays"` +} + +// GetRepositoryName returns __UpdateTimeBasedRetentionInput.RepositoryName, and is useful for accessing the field via an interface. +func (v *__UpdateTimeBasedRetentionInput) GetRepositoryName() string { return v.RepositoryName } + +// GetRetentionInDays returns __UpdateTimeBasedRetentionInput.RetentionInDays, and is useful for accessing the field via an interface. +func (v *__UpdateTimeBasedRetentionInput) GetRetentionInDays() *float64 { return v.RetentionInDays } + +// __UpdateVictorOpsActionInput is used internally by genqlient +type __UpdateVictorOpsActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + MessageType string `json:"MessageType"` + NotifyUrl string `json:"NotifyUrl"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdateVictorOpsActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateVictorOpsActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateVictorOpsActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateVictorOpsActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateVictorOpsActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateVictorOpsActionInput) GetActionName() string { return v.ActionName } + +// GetMessageType returns __UpdateVictorOpsActionInput.MessageType, and is useful for accessing the field via an interface. +func (v *__UpdateVictorOpsActionInput) GetMessageType() string { return v.MessageType } + +// GetNotifyUrl returns __UpdateVictorOpsActionInput.NotifyUrl, and is useful for accessing the field via an interface. +func (v *__UpdateVictorOpsActionInput) GetNotifyUrl() string { return v.NotifyUrl } + +// GetUseProxy returns __UpdateVictorOpsActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdateVictorOpsActionInput) GetUseProxy() bool { return v.UseProxy } + +// __UpdateViewConnectionsInput is used internally by genqlient +type __UpdateViewConnectionsInput struct { + ViewName string `json:"ViewName"` + Connections []ViewConnectionInput `json:"Connections"` +} + +// GetViewName returns __UpdateViewConnectionsInput.ViewName, and is useful for accessing the field via an interface. +func (v *__UpdateViewConnectionsInput) GetViewName() string { return v.ViewName } + +// GetConnections returns __UpdateViewConnectionsInput.Connections, and is useful for accessing the field via an interface. +func (v *__UpdateViewConnectionsInput) GetConnections() []ViewConnectionInput { return v.Connections } + +// __UpdateWebhookActionInput is used internally by genqlient +type __UpdateWebhookActionInput struct { + SearchDomainName string `json:"SearchDomainName"` + ActionID string `json:"ActionID"` + ActionName string `json:"ActionName"` + Url string `json:"Url"` + Method string `json:"Method"` + Headers []HttpHeaderEntryInput `json:"Headers"` + BodyTemplate string `json:"BodyTemplate"` + IgnoreSSL bool `json:"IgnoreSSL"` + UseProxy bool `json:"UseProxy"` +} + +// GetSearchDomainName returns __UpdateWebhookActionInput.SearchDomainName, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetSearchDomainName() string { return v.SearchDomainName } + +// GetActionID returns __UpdateWebhookActionInput.ActionID, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetActionID() string { return v.ActionID } + +// GetActionName returns __UpdateWebhookActionInput.ActionName, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetActionName() string { return v.ActionName } + +// GetUrl returns __UpdateWebhookActionInput.Url, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetUrl() string { return v.Url } + +// GetMethod returns __UpdateWebhookActionInput.Method, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetMethod() string { return v.Method } + +// GetHeaders returns __UpdateWebhookActionInput.Headers, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetHeaders() []HttpHeaderEntryInput { return v.Headers } + +// GetBodyTemplate returns __UpdateWebhookActionInput.BodyTemplate, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetBodyTemplate() string { return v.BodyTemplate } + +// GetIgnoreSSL returns __UpdateWebhookActionInput.IgnoreSSL, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetIgnoreSSL() bool { return v.IgnoreSSL } + +// GetUseProxy returns __UpdateWebhookActionInput.UseProxy, and is useful for accessing the field via an interface. +func (v *__UpdateWebhookActionInput) GetUseProxy() bool { return v.UseProxy } + +// The query or mutation executed by AddIngestToken. +const AddIngestToken_Operation = ` +mutation AddIngestToken ($RepositoryName: String!, $Name: String!, $ParserName: String) { + addIngestTokenV3(input: {repositoryName:$RepositoryName,name:$Name,parser:$ParserName}) { + ... IngestTokenDetails + } +} +fragment IngestTokenDetails on IngestToken { + name + token + parser { + name + } +} +` + +func AddIngestToken( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + Name string, + ParserName *string, +) (*AddIngestTokenResponse, error) { + req_ := &graphql.Request{ + OpName: "AddIngestToken", + Query: AddIngestToken_Operation, + Variables: &__AddIngestTokenInput{ + RepositoryName: RepositoryName, + Name: Name, + ParserName: ParserName, + }, + } + var err_ error + + var data_ AddIngestTokenResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by AddUser. +const AddUser_Operation = ` +mutation AddUser ($Username: String!, $IsRoot: Boolean) { + addUserV2(input: {username:$Username,isRoot:$IsRoot}) { + __typename + ... on User { + ... UserDetails + } + } +} +fragment UserDetails on User { + id + username + isRoot +} +` + +func AddUser( + ctx_ context.Context, + client_ graphql.Client, + Username string, + IsRoot *bool, +) (*AddUserResponse, error) { + req_ := &graphql.Request{ + OpName: "AddUser", + Query: AddUser_Operation, + Variables: &__AddUserInput{ + Username: Username, + IsRoot: IsRoot, + }, + } + var err_ error + + var data_ AddUserResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by AssignParserToIngestToken. +const AssignParserToIngestToken_Operation = ` +mutation AssignParserToIngestToken ($RepositoryName: String!, $IngestTokenName: String!, $ParserName: String!) { + assignParserToIngestTokenV2(input: {repositoryName:$RepositoryName,parser:$ParserName,tokenName:$IngestTokenName}) { + __typename + } +} +` + +func AssignParserToIngestToken( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + IngestTokenName string, + ParserName string, +) (*AssignParserToIngestTokenResponse, error) { + req_ := &graphql.Request{ + OpName: "AssignParserToIngestToken", + Query: AssignParserToIngestToken_Operation, + Variables: &__AssignParserToIngestTokenInput{ + RepositoryName: RepositoryName, + IngestTokenName: IngestTokenName, + ParserName: ParserName, + }, + } + var err_ error + + var data_ AssignParserToIngestTokenResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateAggregateAlert. +const CreateAggregateAlert_Operation = ` +mutation CreateAggregateAlert ($SearchDomainName: RepoOrViewName!, $Name: String!, $Description: String, $QueryString: String!, $SearchIntervalSeconds: Long!, $ActionIdsOrNames: [String!]!, $Labels: [String!]!, $Enabled: Boolean!, $ThrottleField: String, $ThrottleTimeSeconds: Long!, $TriggerMode: TriggerMode!, $QueryTimestampMode: QueryTimestampType!, $QueryOwnershipType: QueryOwnershipType!) { + createAggregateAlert(input: {viewName:$SearchDomainName,name:$Name,description:$Description,queryString:$QueryString,searchIntervalSeconds:$SearchIntervalSeconds,actionIdsOrNames:$ActionIdsOrNames,labels:$Labels,enabled:$Enabled,throttleField:$ThrottleField,throttleTimeSeconds:$ThrottleTimeSeconds,triggerMode:$TriggerMode,queryTimestampType:$QueryTimestampMode,queryOwnershipType:$QueryOwnershipType}) { + ... AggregateAlertDetails + } +} +fragment AggregateAlertDetails on AggregateAlert { + id + name + description + queryString + searchIntervalSeconds + throttleTimeSeconds + throttleField + labels + enabled + triggerMode + queryTimestampType + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func CreateAggregateAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + Name string, + Description *string, + QueryString string, + SearchIntervalSeconds int64, + ActionIdsOrNames []string, + Labels []string, + Enabled bool, + ThrottleField *string, + ThrottleTimeSeconds int64, + TriggerMode TriggerMode, + QueryTimestampMode QueryTimestampType, + QueryOwnershipType QueryOwnershipType, +) (*CreateAggregateAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateAggregateAlert", + Query: CreateAggregateAlert_Operation, + Variables: &__CreateAggregateAlertInput{ + SearchDomainName: SearchDomainName, + Name: Name, + Description: Description, + QueryString: QueryString, + SearchIntervalSeconds: SearchIntervalSeconds, + ActionIdsOrNames: ActionIdsOrNames, + Labels: Labels, + Enabled: Enabled, + ThrottleField: ThrottleField, + ThrottleTimeSeconds: ThrottleTimeSeconds, + TriggerMode: TriggerMode, + QueryTimestampMode: QueryTimestampMode, + QueryOwnershipType: QueryOwnershipType, + }, + } + var err_ error + + var data_ CreateAggregateAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateAlert. +const CreateAlert_Operation = ` +mutation CreateAlert ($SearchDomainName: String!, $Name: String!, $Description: String, $QueryString: String!, $QueryStart: String!, $ThrottleTimeMillis: Long!, $Enabled: Boolean, $Actions: [String!]!, $Labels: [String!], $QueryOwnershipType: QueryOwnershipType, $ThrottleField: String) { + createAlert(input: {viewName:$SearchDomainName,name:$Name,description:$Description,queryString:$QueryString,queryStart:$QueryStart,throttleTimeMillis:$ThrottleTimeMillis,enabled:$Enabled,actions:$Actions,labels:$Labels,queryOwnershipType:$QueryOwnershipType,throttleField:$ThrottleField}) { + ... AlertDetails + } +} +fragment AlertDetails on Alert { + id + name + queryString + queryStart + throttleField + description + throttleTimeMillis + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func CreateAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + Name string, + Description *string, + QueryString string, + QueryStart string, + ThrottleTimeMillis int64, + Enabled *bool, + Actions []string, + Labels []string, + QueryOwnershipType *QueryOwnershipType, + ThrottleField *string, +) (*CreateAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateAlert", + Query: CreateAlert_Operation, + Variables: &__CreateAlertInput{ + SearchDomainName: SearchDomainName, + Name: Name, + Description: Description, + QueryString: QueryString, + QueryStart: QueryStart, + ThrottleTimeMillis: ThrottleTimeMillis, + Enabled: Enabled, + Actions: Actions, + Labels: Labels, + QueryOwnershipType: QueryOwnershipType, + ThrottleField: ThrottleField, + }, + } + var err_ error + + var data_ CreateAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateEmailAction. +const CreateEmailAction_Operation = ` +mutation CreateEmailAction ($SearchDomainName: String!, $ActionName: String!, $Recipients: [String!]!, $SubjectTemplate: String, $BodyTemplate: String, $UseProxy: Boolean!) { + createEmailAction(input: {viewName:$SearchDomainName,name:$ActionName,recipients:$Recipients,subjectTemplate:$SubjectTemplate,bodyTemplate:$BodyTemplate,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreateEmailAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + Recipients []string, + SubjectTemplate *string, + BodyTemplate *string, + UseProxy bool, +) (*CreateEmailActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateEmailAction", + Query: CreateEmailAction_Operation, + Variables: &__CreateEmailActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + Recipients: Recipients, + SubjectTemplate: SubjectTemplate, + BodyTemplate: BodyTemplate, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreateEmailActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateFilterAlert. +const CreateFilterAlert_Operation = ` +mutation CreateFilterAlert ($SearchDomainName: RepoOrViewName!, $Name: String!, $Description: String, $QueryString: String!, $ActionIdsOrNames: [String!]!, $Labels: [String!]!, $Enabled: Boolean!, $ThrottleField: String, $ThrottleTimeSeconds: Long!, $QueryOwnershipType: QueryOwnershipType!) { + createFilterAlert(input: {viewName:$SearchDomainName,name:$Name,description:$Description,queryString:$QueryString,actionIdsOrNames:$ActionIdsOrNames,labels:$Labels,enabled:$Enabled,throttleField:$ThrottleField,throttleTimeSeconds:$ThrottleTimeSeconds,queryOwnershipType:$QueryOwnershipType}) { + ... FilterAlertDetails + } +} +fragment FilterAlertDetails on FilterAlert { + id + name + description + queryString + throttleTimeSeconds + throttleField + labels + enabled + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func CreateFilterAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + Name string, + Description *string, + QueryString string, + ActionIdsOrNames []string, + Labels []string, + Enabled bool, + ThrottleField *string, + ThrottleTimeSeconds int64, + QueryOwnershipType QueryOwnershipType, +) (*CreateFilterAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateFilterAlert", + Query: CreateFilterAlert_Operation, + Variables: &__CreateFilterAlertInput{ + SearchDomainName: SearchDomainName, + Name: Name, + Description: Description, + QueryString: QueryString, + ActionIdsOrNames: ActionIdsOrNames, + Labels: Labels, + Enabled: Enabled, + ThrottleField: ThrottleField, + ThrottleTimeSeconds: ThrottleTimeSeconds, + QueryOwnershipType: QueryOwnershipType, + }, + } + var err_ error + + var data_ CreateFilterAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateHumioRepoAction. +const CreateHumioRepoAction_Operation = ` +mutation CreateHumioRepoAction ($SearchDomainName: String!, $ActionName: String!, $IngestToken: String!) { + createHumioRepoAction(input: {viewName:$SearchDomainName,name:$ActionName,ingestToken:$IngestToken}) { + __typename + } +} +` + +func CreateHumioRepoAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + IngestToken string, +) (*CreateHumioRepoActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateHumioRepoAction", + Query: CreateHumioRepoAction_Operation, + Variables: &__CreateHumioRepoActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + IngestToken: IngestToken, + }, + } + var err_ error + + var data_ CreateHumioRepoActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateOpsGenieAction. +const CreateOpsGenieAction_Operation = ` +mutation CreateOpsGenieAction ($SearchDomainName: String!, $ActionName: String!, $ApiUrl: String!, $GenieKey: String!, $UseProxy: Boolean!) { + createOpsGenieAction(input: {viewName:$SearchDomainName,name:$ActionName,apiUrl:$ApiUrl,genieKey:$GenieKey,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreateOpsGenieAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + ApiUrl string, + GenieKey string, + UseProxy bool, +) (*CreateOpsGenieActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateOpsGenieAction", + Query: CreateOpsGenieAction_Operation, + Variables: &__CreateOpsGenieActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + ApiUrl: ApiUrl, + GenieKey: GenieKey, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreateOpsGenieActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreatePagerDutyAction. +const CreatePagerDutyAction_Operation = ` +mutation CreatePagerDutyAction ($SearchDomainName: String!, $ActionName: String!, $Severity: String!, $RoutingKey: String!, $UseProxy: Boolean!) { + createPagerDutyAction(input: {viewName:$SearchDomainName,name:$ActionName,severity:$Severity,routingKey:$RoutingKey,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreatePagerDutyAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + Severity string, + RoutingKey string, + UseProxy bool, +) (*CreatePagerDutyActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreatePagerDutyAction", + Query: CreatePagerDutyAction_Operation, + Variables: &__CreatePagerDutyActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + Severity: Severity, + RoutingKey: RoutingKey, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreatePagerDutyActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateParserOrUpdate. +const CreateParserOrUpdate_Operation = ` +mutation CreateParserOrUpdate ($RepositoryName: RepoOrViewName!, $Name: String!, $Script: String!, $TestCases: [ParserTestCaseInput!]!, $FieldsToTag: [String!]!, $FieldsToBeRemovedBeforeParsing: [String!]!, $AllowOverridingExistingParser: Boolean!) { + createParserV2(input: {name:$Name,script:$Script,testCases:$TestCases,repositoryName:$RepositoryName,fieldsToTag:$FieldsToTag,fieldsToBeRemovedBeforeParsing:$FieldsToBeRemovedBeforeParsing,allowOverwritingExistingParser:$AllowOverridingExistingParser}) { + ... ParserDetails + } +} +fragment ParserDetails on Parser { + id + name + script + fieldsToTag + testCases { + event { + rawString + } + outputAssertions { + __typename + } + } +} +` + +func CreateParserOrUpdate( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + Name string, + Script string, + TestCases []ParserTestCaseInput, + FieldsToTag []string, + FieldsToBeRemovedBeforeParsing []string, + AllowOverridingExistingParser bool, +) (*CreateParserOrUpdateResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateParserOrUpdate", + Query: CreateParserOrUpdate_Operation, + Variables: &__CreateParserOrUpdateInput{ + RepositoryName: RepositoryName, + Name: Name, + Script: Script, + TestCases: TestCases, + FieldsToTag: FieldsToTag, + FieldsToBeRemovedBeforeParsing: FieldsToBeRemovedBeforeParsing, + AllowOverridingExistingParser: AllowOverridingExistingParser, + }, + } + var err_ error + + var data_ CreateParserOrUpdateResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateRepository. +const CreateRepository_Operation = ` +mutation CreateRepository ($RepositoryName: String!) { + createRepository(name: $RepositoryName) { + repository { + ... RepositoryDetails + } + } +} +fragment RepositoryDetails on Repository { + id + name + description + timeBasedRetention + ingestSizeBasedRetention + storageSizeBasedRetention + compressedByteSize + automaticSearch + s3ArchivingConfiguration { + bucket + region + disabled + format + } +} +` + +func CreateRepository( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, +) (*CreateRepositoryResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateRepository", + Query: CreateRepository_Operation, + Variables: &__CreateRepositoryInput{ + RepositoryName: RepositoryName, + }, + } + var err_ error + + var data_ CreateRepositoryResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateScheduledSearch. +const CreateScheduledSearch_Operation = ` +mutation CreateScheduledSearch ($SearchDomainName: String!, $Name: String!, $Description: String, $QueryString: String!, $QueryStart: String!, $QueryEnd: String!, $Schedule: String!, $TimeZone: String!, $BackfillLimit: Int!, $Enabled: Boolean!, $ActionIdsOrNames: [String!]!, $Labels: [String!]!, $QueryOwnershipType: QueryOwnershipType) { + createScheduledSearch(input: {viewName:$SearchDomainName,name:$Name,description:$Description,queryString:$QueryString,queryStart:$QueryStart,queryEnd:$QueryEnd,schedule:$Schedule,timeZone:$TimeZone,backfillLimit:$BackfillLimit,enabled:$Enabled,actions:$ActionIdsOrNames,labels:$Labels,queryOwnershipType:$QueryOwnershipType}) { + ... ScheduledSearchDetails + } +} +fragment ScheduledSearchDetails on ScheduledSearch { + id + name + description + queryString + start + end + timeZone + schedule + backfillLimit + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func CreateScheduledSearch( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + Name string, + Description *string, + QueryString string, + QueryStart string, + QueryEnd string, + Schedule string, + TimeZone string, + BackfillLimit int, + Enabled bool, + ActionIdsOrNames []string, + Labels []string, + QueryOwnershipType *QueryOwnershipType, +) (*CreateScheduledSearchResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateScheduledSearch", + Query: CreateScheduledSearch_Operation, + Variables: &__CreateScheduledSearchInput{ + SearchDomainName: SearchDomainName, + Name: Name, + Description: Description, + QueryString: QueryString, + QueryStart: QueryStart, + QueryEnd: QueryEnd, + Schedule: Schedule, + TimeZone: TimeZone, + BackfillLimit: BackfillLimit, + Enabled: Enabled, + ActionIdsOrNames: ActionIdsOrNames, + Labels: Labels, + QueryOwnershipType: QueryOwnershipType, + }, + } + var err_ error + + var data_ CreateScheduledSearchResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateSlackAction. +const CreateSlackAction_Operation = ` +mutation CreateSlackAction ($SearchDomainName: String!, $ActionName: String!, $Fields: [SlackFieldEntryInput!]!, $Url: String!, $UseProxy: Boolean!) { + createSlackAction(input: {viewName:$SearchDomainName,name:$ActionName,fields:$Fields,url:$Url,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreateSlackAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + Fields []SlackFieldEntryInput, + Url string, + UseProxy bool, +) (*CreateSlackActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateSlackAction", + Query: CreateSlackAction_Operation, + Variables: &__CreateSlackActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + Fields: Fields, + Url: Url, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreateSlackActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateSlackPostMessageAction. +const CreateSlackPostMessageAction_Operation = ` +mutation CreateSlackPostMessageAction ($SearchDomainName: String!, $ActionName: String!, $ApiToken: String!, $Channels: [String!]!, $Fields: [SlackFieldEntryInput!]!, $UseProxy: Boolean!) { + createSlackPostMessageAction(input: {viewName:$SearchDomainName,name:$ActionName,apiToken:$ApiToken,channels:$Channels,fields:$Fields,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreateSlackPostMessageAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + ApiToken string, + Channels []string, + Fields []SlackFieldEntryInput, + UseProxy bool, +) (*CreateSlackPostMessageActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateSlackPostMessageAction", + Query: CreateSlackPostMessageAction_Operation, + Variables: &__CreateSlackPostMessageActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + ApiToken: ApiToken, + Channels: Channels, + Fields: Fields, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreateSlackPostMessageActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateVictorOpsAction. +const CreateVictorOpsAction_Operation = ` +mutation CreateVictorOpsAction ($SearchDomainName: String!, $ActionName: String!, $MessageType: String!, $NotifyUrl: String!, $UseProxy: Boolean!) { + createVictorOpsAction(input: {viewName:$SearchDomainName,name:$ActionName,messageType:$MessageType,notifyUrl:$NotifyUrl,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreateVictorOpsAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + MessageType string, + NotifyUrl string, + UseProxy bool, +) (*CreateVictorOpsActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateVictorOpsAction", + Query: CreateVictorOpsAction_Operation, + Variables: &__CreateVictorOpsActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + MessageType: MessageType, + NotifyUrl: NotifyUrl, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreateVictorOpsActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateView. +const CreateView_Operation = ` +mutation CreateView ($ViewName: String!, $Description: String, $Connections: [ViewConnectionInput!]) { + createView(name: $ViewName, description: $Description, connections: $Connections) { + __typename + } +} +` + +func CreateView( + ctx_ context.Context, + client_ graphql.Client, + ViewName string, + Description *string, + Connections []ViewConnectionInput, +) (*CreateViewResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateView", + Query: CreateView_Operation, + Variables: &__CreateViewInput{ + ViewName: ViewName, + Description: Description, + Connections: Connections, + }, + } + var err_ error + + var data_ CreateViewResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by CreateWebhookAction. +const CreateWebhookAction_Operation = ` +mutation CreateWebhookAction ($SearchDomainName: String!, $ActionName: String!, $Url: String!, $Method: String!, $Headers: [HttpHeaderEntryInput!]!, $BodyTemplate: String!, $IgnoreSSL: Boolean!, $UseProxy: Boolean!) { + createWebhookAction(input: {viewName:$SearchDomainName,name:$ActionName,url:$Url,method:$Method,headers:$Headers,bodyTemplate:$BodyTemplate,ignoreSSL:$IgnoreSSL,useProxy:$UseProxy}) { + __typename + } +} +` + +func CreateWebhookAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionName string, + Url string, + Method string, + Headers []HttpHeaderEntryInput, + BodyTemplate string, + IgnoreSSL bool, + UseProxy bool, +) (*CreateWebhookActionResponse, error) { + req_ := &graphql.Request{ + OpName: "CreateWebhookAction", + Query: CreateWebhookAction_Operation, + Variables: &__CreateWebhookActionInput{ + SearchDomainName: SearchDomainName, + ActionName: ActionName, + Url: Url, + Method: Method, + Headers: Headers, + BodyTemplate: BodyTemplate, + IgnoreSSL: IgnoreSSL, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ CreateWebhookActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteActionByID. +const DeleteActionByID_Operation = ` +mutation DeleteActionByID ($SearchDomainName: String!, $ActionID: String!) { + deleteAction(input: {viewName:$SearchDomainName,id:$ActionID}) +} +` + +func DeleteActionByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, +) (*DeleteActionByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteActionByID", + Query: DeleteActionByID_Operation, + Variables: &__DeleteActionByIDInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + }, + } + var err_ error + + var data_ DeleteActionByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteAggregateAlert. +const DeleteAggregateAlert_Operation = ` +mutation DeleteAggregateAlert ($SearchDomainName: RepoOrViewName!, $AggregateAlertID: String!) { + deleteAggregateAlert(input: {id:$AggregateAlertID,viewName:$SearchDomainName}) +} +` + +func DeleteAggregateAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + AggregateAlertID string, +) (*DeleteAggregateAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteAggregateAlert", + Query: DeleteAggregateAlert_Operation, + Variables: &__DeleteAggregateAlertInput{ + SearchDomainName: SearchDomainName, + AggregateAlertID: AggregateAlertID, + }, + } + var err_ error + + var data_ DeleteAggregateAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteAlertByID. +const DeleteAlertByID_Operation = ` +mutation DeleteAlertByID ($SearchDomainName: String!, $AlertID: String!) { + deleteAlert(input: {viewName:$SearchDomainName,id:$AlertID}) +} +` + +func DeleteAlertByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + AlertID string, +) (*DeleteAlertByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteAlertByID", + Query: DeleteAlertByID_Operation, + Variables: &__DeleteAlertByIDInput{ + SearchDomainName: SearchDomainName, + AlertID: AlertID, + }, + } + var err_ error + + var data_ DeleteAlertByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteFilterAlert. +const DeleteFilterAlert_Operation = ` +mutation DeleteFilterAlert ($SearchDomainName: RepoOrViewName!, $FilterAlertID: String!) { + deleteFilterAlert(input: {id:$FilterAlertID,viewName:$SearchDomainName}) +} +` + +func DeleteFilterAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + FilterAlertID string, +) (*DeleteFilterAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteFilterAlert", + Query: DeleteFilterAlert_Operation, + Variables: &__DeleteFilterAlertInput{ + SearchDomainName: SearchDomainName, + FilterAlertID: FilterAlertID, + }, + } + var err_ error + + var data_ DeleteFilterAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteParserByID. +const DeleteParserByID_Operation = ` +mutation DeleteParserByID ($RepositoryName: RepoOrViewName!, $ParserID: String!) { + deleteParser(input: {repositoryName:$RepositoryName,id:$ParserID}) { + __typename + } +} +` + +func DeleteParserByID( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + ParserID string, +) (*DeleteParserByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteParserByID", + Query: DeleteParserByID_Operation, + Variables: &__DeleteParserByIDInput{ + RepositoryName: RepositoryName, + ParserID: ParserID, + }, + } + var err_ error + + var data_ DeleteParserByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteScheduledSearchByID. +const DeleteScheduledSearchByID_Operation = ` +mutation DeleteScheduledSearchByID ($SearchDomainName: String!, $ScheduledSearchID: String!) { + deleteScheduledSearch(input: {viewName:$SearchDomainName,id:$ScheduledSearchID}) +} +` + +func DeleteScheduledSearchByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ScheduledSearchID string, +) (*DeleteScheduledSearchByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteScheduledSearchByID", + Query: DeleteScheduledSearchByID_Operation, + Variables: &__DeleteScheduledSearchByIDInput{ + SearchDomainName: SearchDomainName, + ScheduledSearchID: ScheduledSearchID, + }, + } + var err_ error + + var data_ DeleteScheduledSearchByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DeleteSearchDomain. +const DeleteSearchDomain_Operation = ` +mutation DeleteSearchDomain ($SearchDomainName: String!, $DeleteMessage: String!) { + deleteSearchDomain(name: $SearchDomainName, deleteMessage: $DeleteMessage) { + __typename + } +} +` + +func DeleteSearchDomain( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + DeleteMessage string, +) (*DeleteSearchDomainResponse, error) { + req_ := &graphql.Request{ + OpName: "DeleteSearchDomain", + Query: DeleteSearchDomain_Operation, + Variables: &__DeleteSearchDomainInput{ + SearchDomainName: SearchDomainName, + DeleteMessage: DeleteMessage, + }, + } + var err_ error + + var data_ DeleteSearchDomainResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by DisableS3Archiving. +const DisableS3Archiving_Operation = ` +mutation DisableS3Archiving ($RepositoryName: String!) { + s3DisableArchiving(repositoryName: $RepositoryName) { + __typename + } +} +` + +func DisableS3Archiving( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, +) (*DisableS3ArchivingResponse, error) { + req_ := &graphql.Request{ + OpName: "DisableS3Archiving", + Query: DisableS3Archiving_Operation, + Variables: &__DisableS3ArchivingInput{ + RepositoryName: RepositoryName, + }, + } + var err_ error + + var data_ DisableS3ArchivingResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by EnableS3Archiving. +const EnableS3Archiving_Operation = ` +mutation EnableS3Archiving ($RepositoryName: String!) { + s3EnableArchiving(repositoryName: $RepositoryName) { + __typename + } +} +` + +func EnableS3Archiving( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, +) (*EnableS3ArchivingResponse, error) { + req_ := &graphql.Request{ + OpName: "EnableS3Archiving", + Query: EnableS3Archiving_Operation, + Variables: &__EnableS3ArchivingInput{ + RepositoryName: RepositoryName, + }, + } + var err_ error + + var data_ EnableS3ArchivingResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetActionByID. +const GetActionByID_Operation = ` +query GetActionByID ($SearchDomainName: String!, $ActionID: String!) { + searchDomain(name: $SearchDomainName) { + __typename + action(id: $ActionID) { + __typename + ... ActionDetails + } + } +} +fragment ActionDetails on Action { + id + name + ... on EmailAction { + recipients + subjectTemplate + emailBodyTemplate: bodyTemplate + useProxy + } + ... on HumioRepoAction { + ingestToken + } + ... on OpsGenieAction { + apiUrl + genieKey + useProxy + } + ... on PagerDutyAction { + severity + routingKey + useProxy + } + ... on SlackAction { + url + fields { + fieldName + value + } + useProxy + } + ... on SlackPostMessageAction { + apiToken + channels + fields { + fieldName + value + } + useProxy + } + ... on VictorOpsAction { + messageType + notifyUrl + useProxy + } + ... on WebhookAction { + method + url + headers { + header + value + } + WebhookBodyTemplate: bodyTemplate + ignoreSSL + useProxy + } +} +` + +func GetActionByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, +) (*GetActionByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "GetActionByID", + Query: GetActionByID_Operation, + Variables: &__GetActionByIDInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + }, + } + var err_ error + + var data_ GetActionByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetAggregateAlertByID. +const GetAggregateAlertByID_Operation = ` +query GetAggregateAlertByID ($SearchDomainName: String!, $AggregateAlertID: String!) { + searchDomain(name: $SearchDomainName) { + __typename + aggregateAlert(id: $AggregateAlertID) { + ... AggregateAlertDetails + } + } +} +fragment AggregateAlertDetails on AggregateAlert { + id + name + description + queryString + searchIntervalSeconds + throttleTimeSeconds + throttleField + labels + enabled + triggerMode + queryTimestampType + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func GetAggregateAlertByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + AggregateAlertID string, +) (*GetAggregateAlertByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "GetAggregateAlertByID", + Query: GetAggregateAlertByID_Operation, + Variables: &__GetAggregateAlertByIDInput{ + SearchDomainName: SearchDomainName, + AggregateAlertID: AggregateAlertID, + }, + } + var err_ error + + var data_ GetAggregateAlertByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetCluster. +const GetCluster_Operation = ` +query GetCluster { + cluster { + nodes { + id + zone + } + } +} +` + +func GetCluster( + ctx_ context.Context, + client_ graphql.Client, +) (*GetClusterResponse, error) { + req_ := &graphql.Request{ + OpName: "GetCluster", + Query: GetCluster_Operation, + } + var err_ error + + var data_ GetClusterResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetFilterAlertByID. +const GetFilterAlertByID_Operation = ` +query GetFilterAlertByID ($SearchDomainName: String!, $FilterAlertID: String!) { + searchDomain(name: $SearchDomainName) { + __typename + filterAlert(id: $FilterAlertID) { + ... FilterAlertDetails + } + } +} +fragment FilterAlertDetails on FilterAlert { + id + name + description + queryString + throttleTimeSeconds + throttleField + labels + enabled + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func GetFilterAlertByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + FilterAlertID string, +) (*GetFilterAlertByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "GetFilterAlertByID", + Query: GetFilterAlertByID_Operation, + Variables: &__GetFilterAlertByIDInput{ + SearchDomainName: SearchDomainName, + FilterAlertID: FilterAlertID, + }, + } + var err_ error + + var data_ GetFilterAlertByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetLicense. +const GetLicense_Operation = ` +query GetLicense { + installedLicense { + __typename + ... on OnPremLicense { + uid + expiresAt + } + } +} +` + +func GetLicense( + ctx_ context.Context, + client_ graphql.Client, +) (*GetLicenseResponse, error) { + req_ := &graphql.Request{ + OpName: "GetLicense", + Query: GetLicense_Operation, + } + var err_ error + + var data_ GetLicenseResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetParserByID. +const GetParserByID_Operation = ` +query GetParserByID ($RepositoryName: String!, $ParserID: String!) { + repository(name: $RepositoryName) { + parser(id: $ParserID) { + ... ParserDetails + } + } +} +fragment ParserDetails on Parser { + id + name + script + fieldsToTag + testCases { + event { + rawString + } + outputAssertions { + __typename + } + } +} +` + +func GetParserByID( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + ParserID string, +) (*GetParserByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "GetParserByID", + Query: GetParserByID_Operation, + Variables: &__GetParserByIDInput{ + RepositoryName: RepositoryName, + ParserID: ParserID, + }, + } + var err_ error + + var data_ GetParserByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetRepository. +const GetRepository_Operation = ` +query GetRepository ($RepositoryName: String!) { + repository(name: $RepositoryName) { + ... RepositoryDetails + } +} +fragment RepositoryDetails on Repository { + id + name + description + timeBasedRetention + ingestSizeBasedRetention + storageSizeBasedRetention + compressedByteSize + automaticSearch + s3ArchivingConfiguration { + bucket + region + disabled + format + } +} +` + +func GetRepository( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, +) (*GetRepositoryResponse, error) { + req_ := &graphql.Request{ + OpName: "GetRepository", + Query: GetRepository_Operation, + Variables: &__GetRepositoryInput{ + RepositoryName: RepositoryName, + }, + } + var err_ error + + var data_ GetRepositoryResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetScheduledSearchByID. +const GetScheduledSearchByID_Operation = ` +query GetScheduledSearchByID ($SearchDomainName: String!, $ScheduledSearchID: String!) { + searchDomain(name: $SearchDomainName) { + __typename + scheduledSearch(id: $ScheduledSearchID) { + ... ScheduledSearchDetails + } + } +} +fragment ScheduledSearchDetails on ScheduledSearch { + id + name + description + queryString + start + end + timeZone + schedule + backfillLimit + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func GetScheduledSearchByID( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ScheduledSearchID string, +) (*GetScheduledSearchByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "GetScheduledSearchByID", + Query: GetScheduledSearchByID_Operation, + Variables: &__GetScheduledSearchByIDInput{ + SearchDomainName: SearchDomainName, + ScheduledSearchID: ScheduledSearchID, + }, + } + var err_ error + + var data_ GetScheduledSearchByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetSearchDomain. +const GetSearchDomain_Operation = ` +query GetSearchDomain ($SearchDomainName: String!) { + searchDomain(name: $SearchDomainName) { + id + name + description + automaticSearch + ... on View { + connections { + repository { + name + } + filter + } + } + __typename + } +} +` + +func GetSearchDomain( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, +) (*GetSearchDomainResponse, error) { + req_ := &graphql.Request{ + OpName: "GetSearchDomain", + Query: GetSearchDomain_Operation, + Variables: &__GetSearchDomainInput{ + SearchDomainName: SearchDomainName, + }, + } + var err_ error + + var data_ GetSearchDomainResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetUsername. +const GetUsername_Operation = ` +query GetUsername { + viewer { + username + } +} +` + +func GetUsername( + ctx_ context.Context, + client_ graphql.Client, +) (*GetUsernameResponse, error) { + req_ := &graphql.Request{ + OpName: "GetUsername", + Query: GetUsername_Operation, + } + var err_ error + + var data_ GetUsernameResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetUsersByUsername. +const GetUsersByUsername_Operation = ` +query GetUsersByUsername ($Username: String!) { + users(search: $Username) { + ... UserDetails + } +} +fragment UserDetails on User { + id + username + isRoot +} +` + +func GetUsersByUsername( + ctx_ context.Context, + client_ graphql.Client, + Username string, +) (*GetUsersByUsernameResponse, error) { + req_ := &graphql.Request{ + OpName: "GetUsersByUsername", + Query: GetUsersByUsername_Operation, + Variables: &__GetUsersByUsernameInput{ + Username: Username, + }, + } + var err_ error + + var data_ GetUsersByUsernameResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListActions. +const ListActions_Operation = ` +query ListActions ($SearchDomainName: String!) { + searchDomain(name: $SearchDomainName) { + __typename + actions { + __typename + ... ActionDetails + } + } +} +fragment ActionDetails on Action { + id + name + ... on EmailAction { + recipients + subjectTemplate + emailBodyTemplate: bodyTemplate + useProxy + } + ... on HumioRepoAction { + ingestToken + } + ... on OpsGenieAction { + apiUrl + genieKey + useProxy + } + ... on PagerDutyAction { + severity + routingKey + useProxy + } + ... on SlackAction { + url + fields { + fieldName + value + } + useProxy + } + ... on SlackPostMessageAction { + apiToken + channels + fields { + fieldName + value + } + useProxy + } + ... on VictorOpsAction { + messageType + notifyUrl + useProxy + } + ... on WebhookAction { + method + url + headers { + header + value + } + WebhookBodyTemplate: bodyTemplate + ignoreSSL + useProxy + } +} +` + +func ListActions( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, +) (*ListActionsResponse, error) { + req_ := &graphql.Request{ + OpName: "ListActions", + Query: ListActions_Operation, + Variables: &__ListActionsInput{ + SearchDomainName: SearchDomainName, + }, + } + var err_ error + + var data_ ListActionsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListAggregateAlerts. +const ListAggregateAlerts_Operation = ` +query ListAggregateAlerts ($SearchDomainName: String!) { + searchDomain(name: $SearchDomainName) { + __typename + aggregateAlerts { + ... AggregateAlertDetails + } + } +} +fragment AggregateAlertDetails on AggregateAlert { + id + name + description + queryString + searchIntervalSeconds + throttleTimeSeconds + throttleField + labels + enabled + triggerMode + queryTimestampType + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func ListAggregateAlerts( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, +) (*ListAggregateAlertsResponse, error) { + req_ := &graphql.Request{ + OpName: "ListAggregateAlerts", + Query: ListAggregateAlerts_Operation, + Variables: &__ListAggregateAlertsInput{ + SearchDomainName: SearchDomainName, + }, + } + var err_ error + + var data_ ListAggregateAlertsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListAlerts. +const ListAlerts_Operation = ` +query ListAlerts ($SearchDomainName: String!) { + searchDomain(name: $SearchDomainName) { + __typename + alerts { + ... AlertDetails + } + } +} +fragment AlertDetails on Alert { + id + name + queryString + queryStart + throttleField + description + throttleTimeMillis + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func ListAlerts( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, +) (*ListAlertsResponse, error) { + req_ := &graphql.Request{ + OpName: "ListAlerts", + Query: ListAlerts_Operation, + Variables: &__ListAlertsInput{ + SearchDomainName: SearchDomainName, + }, + } + var err_ error + + var data_ ListAlertsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListFilterAlerts. +const ListFilterAlerts_Operation = ` +query ListFilterAlerts ($SearchDomainName: String!) { + searchDomain(name: $SearchDomainName) { + __typename + filterAlerts { + ... FilterAlertDetails + } + } +} +fragment FilterAlertDetails on FilterAlert { + id + name + description + queryString + throttleTimeSeconds + throttleField + labels + enabled + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func ListFilterAlerts( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, +) (*ListFilterAlertsResponse, error) { + req_ := &graphql.Request{ + OpName: "ListFilterAlerts", + Query: ListFilterAlerts_Operation, + Variables: &__ListFilterAlertsInput{ + SearchDomainName: SearchDomainName, + }, + } + var err_ error + + var data_ ListFilterAlertsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListIngestTokens. +const ListIngestTokens_Operation = ` +query ListIngestTokens ($RepositoryName: String!) { + repository(name: $RepositoryName) { + ingestTokens { + ... IngestTokenDetails + } + } +} +fragment IngestTokenDetails on IngestToken { + name + token + parser { + name + } +} +` + +func ListIngestTokens( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, +) (*ListIngestTokensResponse, error) { + req_ := &graphql.Request{ + OpName: "ListIngestTokens", + Query: ListIngestTokens_Operation, + Variables: &__ListIngestTokensInput{ + RepositoryName: RepositoryName, + }, + } + var err_ error + + var data_ ListIngestTokensResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListParsers. +const ListParsers_Operation = ` +query ListParsers ($RepositoryName: String!) { + repository(name: $RepositoryName) { + parsers { + id + name + } + } +} +` + +func ListParsers( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, +) (*ListParsersResponse, error) { + req_ := &graphql.Request{ + OpName: "ListParsers", + Query: ListParsers_Operation, + Variables: &__ListParsersInput{ + RepositoryName: RepositoryName, + }, + } + var err_ error + + var data_ ListParsersResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListRepositories. +const ListRepositories_Operation = ` +query ListRepositories { + repositories { + id + name + compressedByteSize + } +} +` + +func ListRepositories( + ctx_ context.Context, + client_ graphql.Client, +) (*ListRepositoriesResponse, error) { + req_ := &graphql.Request{ + OpName: "ListRepositories", + Query: ListRepositories_Operation, + } + var err_ error + + var data_ ListRepositoriesResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListScheduledSearches. +const ListScheduledSearches_Operation = ` +query ListScheduledSearches ($SearchDomainName: String!) { + searchDomain(name: $SearchDomainName) { + __typename + scheduledSearches { + ... ScheduledSearchDetails + } + } +} +fragment ScheduledSearchDetails on ScheduledSearch { + id + name + description + queryString + start + end + timeZone + schedule + backfillLimit + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func ListScheduledSearches( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, +) (*ListScheduledSearchesResponse, error) { + req_ := &graphql.Request{ + OpName: "ListScheduledSearches", + Query: ListScheduledSearches_Operation, + Variables: &__ListScheduledSearchesInput{ + SearchDomainName: SearchDomainName, + }, + } + var err_ error + + var data_ ListScheduledSearchesResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by ListSearchDomains. +const ListSearchDomains_Operation = ` +query ListSearchDomains { + searchDomains { + __typename + name + automaticSearch + } +} +` + +func ListSearchDomains( + ctx_ context.Context, + client_ graphql.Client, +) (*ListSearchDomainsResponse, error) { + req_ := &graphql.Request{ + OpName: "ListSearchDomains", + Query: ListSearchDomains_Operation, + } + var err_ error + + var data_ ListSearchDomainsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by RemoveIngestToken. +const RemoveIngestToken_Operation = ` +mutation RemoveIngestToken ($RepositoryName: String!, $Name: String!) { + removeIngestToken(repositoryName: $RepositoryName, name: $Name) { + __typename + } +} +` + +func RemoveIngestToken( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + Name string, +) (*RemoveIngestTokenResponse, error) { + req_ := &graphql.Request{ + OpName: "RemoveIngestToken", + Query: RemoveIngestToken_Operation, + Variables: &__RemoveIngestTokenInput{ + RepositoryName: RepositoryName, + Name: Name, + }, + } + var err_ error + + var data_ RemoveIngestTokenResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by RotateTokenByID. +const RotateTokenByID_Operation = ` +mutation RotateTokenByID ($TokenID: String!) { + rotateToken(input: {id:$TokenID}) +} +` + +func RotateTokenByID( + ctx_ context.Context, + client_ graphql.Client, + TokenID string, +) (*RotateTokenByIDResponse, error) { + req_ := &graphql.Request{ + OpName: "RotateTokenByID", + Query: RotateTokenByID_Operation, + Variables: &__RotateTokenByIDInput{ + TokenID: TokenID, + }, + } + var err_ error + + var data_ RotateTokenByIDResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by SetAutomaticSearching. +const SetAutomaticSearching_Operation = ` +mutation SetAutomaticSearching ($SearchDomainName: String!, $AutomaticSearch: Boolean!) { + setAutomaticSearching(name: $SearchDomainName, automaticSearch: $AutomaticSearch) { + __typename + } +} +` + +func SetAutomaticSearching( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + AutomaticSearch bool, +) (*SetAutomaticSearchingResponse, error) { + req_ := &graphql.Request{ + OpName: "SetAutomaticSearching", + Query: SetAutomaticSearching_Operation, + Variables: &__SetAutomaticSearchingInput{ + SearchDomainName: SearchDomainName, + AutomaticSearch: AutomaticSearch, + }, + } + var err_ error + + var data_ SetAutomaticSearchingResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UnassignParserToIngestToken. +const UnassignParserToIngestToken_Operation = ` +mutation UnassignParserToIngestToken ($RepositoryName: String!, $IngestTokenName: String!) { + unassignIngestToken(repositoryName: $RepositoryName, tokenName: $IngestTokenName) { + __typename + } +} +` + +func UnassignParserToIngestToken( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + IngestTokenName string, +) (*UnassignParserToIngestTokenResponse, error) { + req_ := &graphql.Request{ + OpName: "UnassignParserToIngestToken", + Query: UnassignParserToIngestToken_Operation, + Variables: &__UnassignParserToIngestTokenInput{ + RepositoryName: RepositoryName, + IngestTokenName: IngestTokenName, + }, + } + var err_ error + + var data_ UnassignParserToIngestTokenResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateAggregateAlert. +const UpdateAggregateAlert_Operation = ` +mutation UpdateAggregateAlert ($SearchDomainName: RepoOrViewName!, $ID: String!, $Name: String!, $Description: String, $QueryString: String!, $SearchIntervalSeconds: Long!, $ActionIdsOrNames: [String!]!, $Labels: [String!]!, $Enabled: Boolean!, $ThrottleField: String, $ThrottleTimeSeconds: Long!, $TriggerMode: TriggerMode!, $QueryTimestampMode: QueryTimestampType!, $QueryOwnershipType: QueryOwnershipType!) { + updateAggregateAlert(input: {viewName:$SearchDomainName,id:$ID,name:$Name,description:$Description,queryString:$QueryString,searchIntervalSeconds:$SearchIntervalSeconds,actionIdsOrNames:$ActionIdsOrNames,labels:$Labels,enabled:$Enabled,throttleField:$ThrottleField,throttleTimeSeconds:$ThrottleTimeSeconds,triggerMode:$TriggerMode,queryTimestampType:$QueryTimestampMode,queryOwnershipType:$QueryOwnershipType}) { + ... AggregateAlertDetails + } +} +fragment AggregateAlertDetails on AggregateAlert { + id + name + description + queryString + searchIntervalSeconds + throttleTimeSeconds + throttleField + labels + enabled + triggerMode + queryTimestampType + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func UpdateAggregateAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ID string, + Name string, + Description *string, + QueryString string, + SearchIntervalSeconds int64, + ActionIdsOrNames []string, + Labels []string, + Enabled bool, + ThrottleField *string, + ThrottleTimeSeconds int64, + TriggerMode TriggerMode, + QueryTimestampMode QueryTimestampType, + QueryOwnershipType QueryOwnershipType, +) (*UpdateAggregateAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateAggregateAlert", + Query: UpdateAggregateAlert_Operation, + Variables: &__UpdateAggregateAlertInput{ + SearchDomainName: SearchDomainName, + ID: ID, + Name: Name, + Description: Description, + QueryString: QueryString, + SearchIntervalSeconds: SearchIntervalSeconds, + ActionIdsOrNames: ActionIdsOrNames, + Labels: Labels, + Enabled: Enabled, + ThrottleField: ThrottleField, + ThrottleTimeSeconds: ThrottleTimeSeconds, + TriggerMode: TriggerMode, + QueryTimestampMode: QueryTimestampMode, + QueryOwnershipType: QueryOwnershipType, + }, + } + var err_ error + + var data_ UpdateAggregateAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateAlert. +const UpdateAlert_Operation = ` +mutation UpdateAlert ($SearchDomainName: String!, $AlertID: String!, $Name: String!, $Description: String, $QueryString: String!, $QueryStart: String!, $ThrottleTimeMillis: Long!, $Enabled: Boolean!, $Actions: [String!]!, $Labels: [String!]!, $QueryOwnershipType: QueryOwnershipType, $ThrottleField: String) { + updateAlert(input: {id:$AlertID,viewName:$SearchDomainName,name:$Name,description:$Description,queryString:$QueryString,queryStart:$QueryStart,throttleTimeMillis:$ThrottleTimeMillis,enabled:$Enabled,actions:$Actions,labels:$Labels,queryOwnershipType:$QueryOwnershipType,throttleField:$ThrottleField}) { + ... AlertDetails + } +} +fragment AlertDetails on Alert { + id + name + queryString + queryStart + throttleField + description + throttleTimeMillis + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func UpdateAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + AlertID string, + Name string, + Description *string, + QueryString string, + QueryStart string, + ThrottleTimeMillis int64, + Enabled bool, + Actions []string, + Labels []string, + QueryOwnershipType *QueryOwnershipType, + ThrottleField *string, +) (*UpdateAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateAlert", + Query: UpdateAlert_Operation, + Variables: &__UpdateAlertInput{ + SearchDomainName: SearchDomainName, + AlertID: AlertID, + Name: Name, + Description: Description, + QueryString: QueryString, + QueryStart: QueryStart, + ThrottleTimeMillis: ThrottleTimeMillis, + Enabled: Enabled, + Actions: Actions, + Labels: Labels, + QueryOwnershipType: QueryOwnershipType, + ThrottleField: ThrottleField, + }, + } + var err_ error + + var data_ UpdateAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateDescriptionForSearchDomain. +const UpdateDescriptionForSearchDomain_Operation = ` +mutation UpdateDescriptionForSearchDomain ($SearchDomainName: String!, $NewDescription: String!) { + updateDescriptionForSearchDomain(name: $SearchDomainName, newDescription: $NewDescription) { + __typename + } +} +` + +func UpdateDescriptionForSearchDomain( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + NewDescription string, +) (*UpdateDescriptionForSearchDomainResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateDescriptionForSearchDomain", + Query: UpdateDescriptionForSearchDomain_Operation, + Variables: &__UpdateDescriptionForSearchDomainInput{ + SearchDomainName: SearchDomainName, + NewDescription: NewDescription, + }, + } + var err_ error + + var data_ UpdateDescriptionForSearchDomainResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateEmailAction. +const UpdateEmailAction_Operation = ` +mutation UpdateEmailAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $Recipients: [String!]!, $SubjectTemplate: String, $BodyTemplate: String, $UseProxy: Boolean!) { + updateEmailAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,recipients:$Recipients,subjectTemplate:$SubjectTemplate,bodyTemplate:$BodyTemplate,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdateEmailAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + Recipients []string, + SubjectTemplate *string, + BodyTemplate *string, + UseProxy bool, +) (*UpdateEmailActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateEmailAction", + Query: UpdateEmailAction_Operation, + Variables: &__UpdateEmailActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + Recipients: Recipients, + SubjectTemplate: SubjectTemplate, + BodyTemplate: BodyTemplate, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdateEmailActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateFilterAlert. +const UpdateFilterAlert_Operation = ` +mutation UpdateFilterAlert ($SearchDomainName: RepoOrViewName!, $ID: String!, $Name: String!, $Description: String, $QueryString: String!, $ActionIdsOrNames: [String!]!, $Labels: [String!]!, $Enabled: Boolean!, $ThrottleField: String, $ThrottleTimeSeconds: Long!, $QueryOwnershipType: QueryOwnershipType!) { + updateFilterAlert(input: {viewName:$SearchDomainName,id:$ID,name:$Name,description:$Description,queryString:$QueryString,actionIdsOrNames:$ActionIdsOrNames,labels:$Labels,enabled:$Enabled,throttleField:$ThrottleField,throttleTimeSeconds:$ThrottleTimeSeconds,queryOwnershipType:$QueryOwnershipType}) { + ... FilterAlertDetails + } +} +fragment FilterAlertDetails on FilterAlert { + id + name + description + queryString + throttleTimeSeconds + throttleField + labels + enabled + actions { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func UpdateFilterAlert( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ID string, + Name string, + Description *string, + QueryString string, + ActionIdsOrNames []string, + Labels []string, + Enabled bool, + ThrottleField *string, + ThrottleTimeSeconds int64, + QueryOwnershipType QueryOwnershipType, +) (*UpdateFilterAlertResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateFilterAlert", + Query: UpdateFilterAlert_Operation, + Variables: &__UpdateFilterAlertInput{ + SearchDomainName: SearchDomainName, + ID: ID, + Name: Name, + Description: Description, + QueryString: QueryString, + ActionIdsOrNames: ActionIdsOrNames, + Labels: Labels, + Enabled: Enabled, + ThrottleField: ThrottleField, + ThrottleTimeSeconds: ThrottleTimeSeconds, + QueryOwnershipType: QueryOwnershipType, + }, + } + var err_ error + + var data_ UpdateFilterAlertResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateHumioRepoAction. +const UpdateHumioRepoAction_Operation = ` +mutation UpdateHumioRepoAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $IngestToken: String!) { + updateHumioRepoAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,ingestToken:$IngestToken}) { + __typename + } +} +` + +func UpdateHumioRepoAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + IngestToken string, +) (*UpdateHumioRepoActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateHumioRepoAction", + Query: UpdateHumioRepoAction_Operation, + Variables: &__UpdateHumioRepoActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + IngestToken: IngestToken, + }, + } + var err_ error + + var data_ UpdateHumioRepoActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateIngestBasedRetention. +const UpdateIngestBasedRetention_Operation = ` +mutation UpdateIngestBasedRetention ($RepositoryName: String!, $IngestInGB: Float) { + updateRetention(repositoryName: $RepositoryName, ingestSizeBasedRetention: $IngestInGB) { + __typename + } +} +` + +func UpdateIngestBasedRetention( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + IngestInGB *float64, +) (*UpdateIngestBasedRetentionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateIngestBasedRetention", + Query: UpdateIngestBasedRetention_Operation, + Variables: &__UpdateIngestBasedRetentionInput{ + RepositoryName: RepositoryName, + IngestInGB: IngestInGB, + }, + } + var err_ error + + var data_ UpdateIngestBasedRetentionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateLicenseKey. +const UpdateLicenseKey_Operation = ` +mutation UpdateLicenseKey ($LicenseKey: String!) { + updateLicenseKey(license: $LicenseKey) { + __typename + } +} +` + +func UpdateLicenseKey( + ctx_ context.Context, + client_ graphql.Client, + LicenseKey string, +) (*UpdateLicenseKeyResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateLicenseKey", + Query: UpdateLicenseKey_Operation, + Variables: &__UpdateLicenseKeyInput{ + LicenseKey: LicenseKey, + }, + } + var err_ error + + var data_ UpdateLicenseKeyResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateOpsGenieAction. +const UpdateOpsGenieAction_Operation = ` +mutation UpdateOpsGenieAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $ApiUrl: String!, $GenieKey: String!, $UseProxy: Boolean!) { + updateOpsGenieAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,apiUrl:$ApiUrl,genieKey:$GenieKey,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdateOpsGenieAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + ApiUrl string, + GenieKey string, + UseProxy bool, +) (*UpdateOpsGenieActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateOpsGenieAction", + Query: UpdateOpsGenieAction_Operation, + Variables: &__UpdateOpsGenieActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + ApiUrl: ApiUrl, + GenieKey: GenieKey, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdateOpsGenieActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdatePagerDutyAction. +const UpdatePagerDutyAction_Operation = ` +mutation UpdatePagerDutyAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $Severity: String!, $RoutingKey: String!, $UseProxy: Boolean!) { + updatePagerDutyAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,severity:$Severity,routingKey:$RoutingKey,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdatePagerDutyAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + Severity string, + RoutingKey string, + UseProxy bool, +) (*UpdatePagerDutyActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdatePagerDutyAction", + Query: UpdatePagerDutyAction_Operation, + Variables: &__UpdatePagerDutyActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + Severity: Severity, + RoutingKey: RoutingKey, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdatePagerDutyActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateS3ArchivingConfiguration. +const UpdateS3ArchivingConfiguration_Operation = ` +mutation UpdateS3ArchivingConfiguration ($RepositoryName: String!, $BucketName: String!, $BucketRegion: String!, $Format: S3ArchivingFormat!) { + s3ConfigureArchiving(repositoryName: $RepositoryName, bucket: $BucketName, region: $BucketRegion, format: $Format) { + __typename + } +} +` + +func UpdateS3ArchivingConfiguration( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + BucketName string, + BucketRegion string, + Format S3ArchivingFormat, +) (*UpdateS3ArchivingConfigurationResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateS3ArchivingConfiguration", + Query: UpdateS3ArchivingConfiguration_Operation, + Variables: &__UpdateS3ArchivingConfigurationInput{ + RepositoryName: RepositoryName, + BucketName: BucketName, + BucketRegion: BucketRegion, + Format: Format, + }, + } + var err_ error + + var data_ UpdateS3ArchivingConfigurationResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateScheduledSearch. +const UpdateScheduledSearch_Operation = ` +mutation UpdateScheduledSearch ($SearchDomainName: String!, $ID: String!, $Name: String!, $Description: String, $QueryString: String!, $QueryStart: String!, $QueryEnd: String!, $Schedule: String!, $TimeZone: String!, $BackfillLimit: Int!, $Enabled: Boolean!, $ActionIdsOrNames: [String!]!, $Labels: [String!]!, $QueryOwnershipType: QueryOwnershipType) { + updateScheduledSearch(input: {viewName:$SearchDomainName,id:$ID,name:$Name,description:$Description,queryString:$QueryString,queryStart:$QueryStart,queryEnd:$QueryEnd,schedule:$Schedule,timeZone:$TimeZone,backfillLimit:$BackfillLimit,enabled:$Enabled,actions:$ActionIdsOrNames,labels:$Labels,queryOwnershipType:$QueryOwnershipType}) { + ... ScheduledSearchDetails + } +} +fragment ScheduledSearchDetails on ScheduledSearch { + id + name + description + queryString + start + end + timeZone + schedule + backfillLimit + enabled + labels + actionsV2 { + __typename + ... ActionName + } + queryOwnership { + __typename + ... QueryOwnership + } +} +fragment ActionName on Action { + name +} +fragment QueryOwnership on QueryOwnership { + __typename +} +` + +func UpdateScheduledSearch( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ID string, + Name string, + Description *string, + QueryString string, + QueryStart string, + QueryEnd string, + Schedule string, + TimeZone string, + BackfillLimit int, + Enabled bool, + ActionIdsOrNames []string, + Labels []string, + QueryOwnershipType *QueryOwnershipType, +) (*UpdateScheduledSearchResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateScheduledSearch", + Query: UpdateScheduledSearch_Operation, + Variables: &__UpdateScheduledSearchInput{ + SearchDomainName: SearchDomainName, + ID: ID, + Name: Name, + Description: Description, + QueryString: QueryString, + QueryStart: QueryStart, + QueryEnd: QueryEnd, + Schedule: Schedule, + TimeZone: TimeZone, + BackfillLimit: BackfillLimit, + Enabled: Enabled, + ActionIdsOrNames: ActionIdsOrNames, + Labels: Labels, + QueryOwnershipType: QueryOwnershipType, + }, + } + var err_ error + + var data_ UpdateScheduledSearchResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateSlackAction. +const UpdateSlackAction_Operation = ` +mutation UpdateSlackAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $Fields: [SlackFieldEntryInput!]!, $Url: String!, $UseProxy: Boolean!) { + updateSlackAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,fields:$Fields,url:$Url,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdateSlackAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + Fields []SlackFieldEntryInput, + Url string, + UseProxy bool, +) (*UpdateSlackActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateSlackAction", + Query: UpdateSlackAction_Operation, + Variables: &__UpdateSlackActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + Fields: Fields, + Url: Url, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdateSlackActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateSlackPostMessageAction. +const UpdateSlackPostMessageAction_Operation = ` +mutation UpdateSlackPostMessageAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $ApiToken: String!, $Channels: [String!]!, $Fields: [SlackFieldEntryInput!]!, $UseProxy: Boolean!) { + updateSlackPostMessageAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,apiToken:$ApiToken,channels:$Channels,fields:$Fields,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdateSlackPostMessageAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + ApiToken string, + Channels []string, + Fields []SlackFieldEntryInput, + UseProxy bool, +) (*UpdateSlackPostMessageActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateSlackPostMessageAction", + Query: UpdateSlackPostMessageAction_Operation, + Variables: &__UpdateSlackPostMessageActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + ApiToken: ApiToken, + Channels: Channels, + Fields: Fields, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdateSlackPostMessageActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateStorageBasedRetention. +const UpdateStorageBasedRetention_Operation = ` +mutation UpdateStorageBasedRetention ($RepositoryName: String!, $StorageInGB: Float) { + updateRetention(repositoryName: $RepositoryName, storageSizeBasedRetention: $StorageInGB) { + __typename + } +} +` + +func UpdateStorageBasedRetention( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + StorageInGB *float64, +) (*UpdateStorageBasedRetentionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateStorageBasedRetention", + Query: UpdateStorageBasedRetention_Operation, + Variables: &__UpdateStorageBasedRetentionInput{ + RepositoryName: RepositoryName, + StorageInGB: StorageInGB, + }, + } + var err_ error + + var data_ UpdateStorageBasedRetentionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateTimeBasedRetention. +const UpdateTimeBasedRetention_Operation = ` +mutation UpdateTimeBasedRetention ($RepositoryName: String!, $RetentionInDays: Float) { + updateRetention(repositoryName: $RepositoryName, timeBasedRetention: $RetentionInDays) { + __typename + } +} +` + +func UpdateTimeBasedRetention( + ctx_ context.Context, + client_ graphql.Client, + RepositoryName string, + RetentionInDays *float64, +) (*UpdateTimeBasedRetentionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateTimeBasedRetention", + Query: UpdateTimeBasedRetention_Operation, + Variables: &__UpdateTimeBasedRetentionInput{ + RepositoryName: RepositoryName, + RetentionInDays: RetentionInDays, + }, + } + var err_ error + + var data_ UpdateTimeBasedRetentionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateVictorOpsAction. +const UpdateVictorOpsAction_Operation = ` +mutation UpdateVictorOpsAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $MessageType: String!, $NotifyUrl: String!, $UseProxy: Boolean!) { + updateVictorOpsAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,messageType:$MessageType,notifyUrl:$NotifyUrl,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdateVictorOpsAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + MessageType string, + NotifyUrl string, + UseProxy bool, +) (*UpdateVictorOpsActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateVictorOpsAction", + Query: UpdateVictorOpsAction_Operation, + Variables: &__UpdateVictorOpsActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + MessageType: MessageType, + NotifyUrl: NotifyUrl, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdateVictorOpsActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateViewConnections. +const UpdateViewConnections_Operation = ` +mutation UpdateViewConnections ($ViewName: String!, $Connections: [ViewConnectionInput!]!) { + updateView(viewName: $ViewName, connections: $Connections) { + name + } +} +` + +func UpdateViewConnections( + ctx_ context.Context, + client_ graphql.Client, + ViewName string, + Connections []ViewConnectionInput, +) (*UpdateViewConnectionsResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateViewConnections", + Query: UpdateViewConnections_Operation, + Variables: &__UpdateViewConnectionsInput{ + ViewName: ViewName, + Connections: Connections, + }, + } + var err_ error + + var data_ UpdateViewConnectionsResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by UpdateWebhookAction. +const UpdateWebhookAction_Operation = ` +mutation UpdateWebhookAction ($SearchDomainName: String!, $ActionID: String!, $ActionName: String!, $Url: String!, $Method: String!, $Headers: [HttpHeaderEntryInput!]!, $BodyTemplate: String!, $IgnoreSSL: Boolean!, $UseProxy: Boolean!) { + updateWebhookAction(input: {viewName:$SearchDomainName,id:$ActionID,name:$ActionName,url:$Url,method:$Method,headers:$Headers,bodyTemplate:$BodyTemplate,ignoreSSL:$IgnoreSSL,useProxy:$UseProxy}) { + __typename + } +} +` + +func UpdateWebhookAction( + ctx_ context.Context, + client_ graphql.Client, + SearchDomainName string, + ActionID string, + ActionName string, + Url string, + Method string, + Headers []HttpHeaderEntryInput, + BodyTemplate string, + IgnoreSSL bool, + UseProxy bool, +) (*UpdateWebhookActionResponse, error) { + req_ := &graphql.Request{ + OpName: "UpdateWebhookAction", + Query: UpdateWebhookAction_Operation, + Variables: &__UpdateWebhookActionInput{ + SearchDomainName: SearchDomainName, + ActionID: ActionID, + ActionName: ActionName, + Url: Url, + Method: Method, + Headers: Headers, + BodyTemplate: BodyTemplate, + IgnoreSSL: IgnoreSSL, + UseProxy: UseProxy, + }, + } + var err_ error + + var data_ UpdateWebhookActionResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} diff --git a/internal/api/humiographql/schema/_schema.graphql b/internal/api/humiographql/schema/_schema.graphql new file mode 100644 index 00000000..b64561dd --- /dev/null +++ b/internal/api/humiographql/schema/_schema.graphql @@ -0,0 +1,19091 @@ +""" +Directs the executor to include this field or fragment only when the `if` argument is true. +""" +directive @include( +""" +Included when true. +""" + if: Boolean! +) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +""" +Directs the executor to skip this field or fragment when the `if` argument is true. +""" +directive @skip( +""" +Included when true. +""" + if: Boolean! +) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +""" +Marks an element of a GraphQL schema as no longer supported. +""" +directive @deprecated( +""" +Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/). +""" + reason: String +) on ENUM_VALUE | FIELD_DEFINITION + +directive @preview( + reason: String! +) on ENUM_VALUE | FIELD_DEFINITION + +""" +Data for updating action security policies +""" +input ActionSecurityPoliciesInput { +""" +Data for updating action security policies +""" + emailActionEnabled: Boolean! +""" +Data for updating action security policies +""" + emailActionRecipientAllowList: [String!] +""" +Data for updating action security policies +""" + repoActionEnabled: Boolean! +""" +Data for updating action security policies +""" + opsGenieActionEnabled: Boolean! +""" +Data for updating action security policies +""" + pagerDutyActionEnabled: Boolean! +""" +Data for updating action security policies +""" + slackSingleChannelActionEnabled: Boolean! +""" +Data for updating action security policies +""" + slackMultiChannelActionEnabled: Boolean! +""" +Data for updating action security policies +""" + uploadFileActionEnabled: Boolean! +""" +Data for updating action security policies +""" + victorOpsActionEnabled: Boolean! +""" +Data for updating action security policies +""" + webhookActionEnabled: Boolean! +""" +Data for updating action security policies +""" + webhookActionUrlAllowList: [String!] +} + +""" +Data for adding a label to an alert +""" +input AddAlertLabel { +""" +Data for adding a label to an alert +""" + viewName: String! +""" +Data for adding a label to an alert +""" + id: String! +""" +Data for adding a label to an alert +""" + label: String! +} + +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field addFieldAliasMapping +""" +input AddAliasMappingInput { +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field addFieldAliasMapping +""" + schemaId: String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field addFieldAliasMapping +""" + aliasMapping: AliasMappingInput! +} + +type AddGroupMutation { + group: Group! +} + +""" +Input data to create an ingest token +""" +input AddIngestTokenV3Input { +""" +Input data to create an ingest token +""" + repositoryName: String! +""" +Input data to create an ingest token +""" + name: String! +""" +Input data to create an ingest token +""" + parser: String +""" +Input data to create an ingest token +""" + customToken: String +} + +""" +Data for adding a label to a scheduled search +""" +input AddLabelScheduledSearch { +""" +Data for adding a label to a scheduled search +""" + viewName: String! +""" +Data for adding a label to a scheduled search +""" + id: String! +""" +Data for adding a label to a scheduled search +""" + label: String! +} + +input AddLimitInput { + limitName: String! + allowLogin: Boolean! + dailyIngest: Long! + retention: Int! + allowSelfService: Boolean! + expiration: Long + contractVersion: Organizations__ContractVersion + userLimit: Int +} + +input AddLimitV2Input { + limitName: String! + allowLogin: Boolean! + dailyIngest: Long + dailyIngestContractualType: Organizations__ContractualType! + storageContractualType: Organizations__ContractualType! + dailyScanContractualType: Organizations__ContractualType! + measurementType: Organizations__MeasurementType! + dailyScan: Long + retention: Int! + maxRetention: Int! + allowSelfService: Boolean! + expiration: Long + userLimit: Int + dateType: String! + trial: Boolean! + allowFlightControl: Boolean! + repositoryLimit: Int +} + +type AddRecentQuery { + recentQueries: [RecentQuery!]! +} + +input AddRecentQueryInput { + viewName: String! + queryArguments: [InputDictionaryEntry!]! + queryString: String! + start: String! + end: String! + isLive: Boolean! + widgetType: String + options: JSON +} + +input AddRoleInput { + displayName: String! + viewPermissions: [Permission!]! + color: String + systemPermissions: [SystemPermission!] + organizationPermissions: [OrganizationPermission!] + objectAction: ObjectAction + organizationManagementPermissions: [OrganizationManagementPermission!] +} + +type AddRoleMutation { + role: Role! +} + +""" +Data for adding a star to a scheduled search +""" +input AddStarScheduledSearch { +""" +Data for adding a star to a scheduled search +""" + viewName: String! +""" +Data for adding a star to a scheduled search +""" + id: String! +} + +""" +Data for adding a star to an alert +""" +input AddStarToAlert { +""" +Data for adding a star to an alert +""" + viewName: String! +""" +Data for adding a star to an alert +""" + id: String! +} + +input AddStarToFieldInput { + fieldName: String! + searchDomainName: String! +} + +type AddStarToFieldMutation { + starredFields: [String!]! +} + +input AddStarToQueryInput { + savedQueryId: String! + searchDomainName: String! +} + +input AddSubdomainInput { + subdomain: String! +} + +""" +Data for adding to the blocklist +""" +input AddToBlocklistByIdInput { +""" +Data for adding to the blocklist +""" + pattern: String! +""" +Data for adding to the blocklist +""" + type: BlockedQueryMatcherType! +""" +Data for adding to the blocklist +""" + viewId: String +""" +Data for adding to the blocklist +""" + clusterWide: Boolean +} + +""" +Data for adding to the blocklist +""" +input AddToBlocklistInput { +""" +Data for adding to the blocklist +""" + pattern: String! +""" +Data for adding to the blocklist +""" + type: BlockedQueryMatcherType! +""" +Data for adding to the blocklist +""" + viewName: String +""" +Data for adding to the blocklist +""" + clusterWide: Boolean +} + +input AddUserInput { + username: String! + company: String + isRoot: Boolean + firstName: String + lastName: String + fullName: String + picture: String + email: String + countryCode: String + stateCode: String +} + +input AddUserInputV2 { + username: String! + company: String + isRoot: Boolean + firstName: String + lastName: String + fullName: String + picture: String + email: String + countryCode: String + stateCode: String + sendInvite: Boolean + verificationToken: String + isOrgOwner: Boolean +} + +input AddUsersToGroupInput { + users: [String!]! + groupId: String! +} + +type AddUsersToGroupMutation { + group: Group! +} + +input AliasInfoInput { + source: String! + alias: String! +} + +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for creating a new alias mapping. +""" +input AliasMappingInput { +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for creating a new alias mapping. +""" + name: String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for creating a new alias mapping. +""" + tags: [TagsInput!]! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for creating a new alias mapping. +""" + aliases: [AliasInfoInput!]! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for creating a new alias mapping. +""" + originalFieldsToKeep: [String!] +} + +input AnalyticsBrowser { + info: AnalyticsBrowserInfo! + isChrome: Boolean! + isChromeHeadless: Boolean! + isEdge: Boolean! + isFirefox: Boolean! + isIE: Boolean! + isSafari: Boolean! +} + +input AnalyticsBrowserInfo { + name: String + version: String + major: String +} + +input AnalyticsDevice { + info: AnalyticsDeviceInfo! + isConsole: Boolean! + isDesktop: Boolean! + isMobile: Boolean! + isTablet: Boolean! +} + +input AnalyticsDeviceInfo { + model: String + type: String + vendor: String +} + +input AnalyticsEngine { + info: AnalyticsInfo! + isWebkit: Boolean! +} + +input AnalyticsFeature { + name: String! + value: Boolean! +} + +input AnalyticsInfo { + name: String! + version: String! +} + +input AnalyticsLog { + category: String! + action: String! + message: String +} + +input AnalyticsLogWithTimestamp { + eventId: String! + timestamp: Long! + route: String! + action: String! + system: String! + arguments: [String!]! + feature: String + features: [AnalyticsFeature!]! + context: String! + metrics: AnalyticsMetrics! + userAgent: AnalyticsUserAgent! +} + +input AnalyticsMetrics { + fps: Int! +} + +input AnalyticsOS { + info: AnalyticsInfo! + isAndroid: Boolean! + isIOS: Boolean! + isLinux: Boolean! + isMacOS: Boolean! + isWindows: Boolean! +} + +input AnalyticsUserAgent { + browser: AnalyticsBrowser! + device: AnalyticsDevice! + engine: AnalyticsEngine! + os: AnalyticsOS! +} + +input ArgumentInput { + key: String! + value: String! +} + +""" +A gap in th array. Null values represent missing bounds +""" +type ArrayGap { +""" +[PREVIEW: API under active development] Array gap starts at this index (inclusive) +""" + startsAtIndex: Int! +""" +[PREVIEW: API under active development] Array gap ends at this index (exclusive) +""" + endsAtIndex: Int! +} + +""" +Array gaps identified for a given prefix +""" +type ArrayWithGap { +""" +[PREVIEW: API under active development] Prefix that represents a field up until the point at which a gap was identified. For instance, the field `a[0].b[1]` would give the prefix `a[0].b` as the gap occurs when indexing `b` with `1`. For `a[1].b[0]` we would get the prefix `a`. +""" + lastValidPrefix: String! +""" +[PREVIEW: API under active development] Gaps identified for array prefix +""" + gaps: [ArrayGap!]! +} + +""" +Different ways in which an assertion may fail. +""" +union AssertionFailureOnField =FieldUnexpectedlyPresent | FieldHadUnexpectedValue | FieldHadConflictingAssertions | AssertionOnFieldWasOrphaned + +""" +This occurs when an assertion was set to run on some output event that wasn't produced by the parser. That is, the assertion may be set to run on output event number 2, but the parser only produced one event. +""" +type AssertionOnFieldWasOrphaned { +""" +Field being asserted on. +""" + fieldName: String! +} + +input AssignAssetPermissionsToGroupInputType { + groupId: String! + assetId: String! + assetType: AssetPermissionsAssetType! + searchDomainId: String + assetPermissions: [AssetPermissionInputEnum!]! +} + +input AssignAssetPermissionsToUserInputType { + userId: String! + assetId: String! + assetType: AssetPermissionsAssetType! + searchDomainId: String + assetPermissions: [AssetPermissionInputEnum!]! +} + +input AssignOrganizationManagementRoleToGroupInput { + groupId: String! + roleId: String! + organizationIds: [String!]! +} + +type AssignOrganizationManagementRoleToGroupMutation { + group: GroupOrganizationManagementRole! +} + +input AssignOrganizationRoleToGroupInput { + groupId: String! + roleId: String! +} + +type AssignOrganizationRoleToGroupMutation { + group: GroupOrganizationRole! +} + +""" +Input data to assign a parser to an ingest token +""" +input AssignParserToIngestTokenInputV2 { +""" +Input data to assign a parser to an ingest token +""" + repositoryName: String! +""" +Input data to assign a parser to an ingest token +""" + tokenName: String! +""" +Input data to assign a parser to an ingest token +""" + parser: String! +} + +input AssignRoleToGroupInput { + viewId: String! + groupId: String! + roleId: String! + overrideExistingAssignmentsForView: Boolean +} + +type AssignRoleToGroupMutation { + group: SearchDomainRole! +} + +input AssignSystemRoleToGroupInput { + groupId: String! + roleId: String! +} + +type AssignSystemRoleToGroupMutation { + group: GroupSystemRole! +} + +input AssignUserRolesInSearchDomainInput { + searchDomainId: String! + roleAssignments: [UserRoleAssignmentInput!]! +} + +""" +Authentication through Auth0. +""" +type Auth0Authentication implements AuthenticationMethod{ + auth0Domain: String! + clientId: String! + allowSignup: Boolean! + redirectUrl: String! +""" +The display name of the authentication method. +""" + name: String! +} + +""" +Payload for specifying targets for batch updating query ownership +""" +input BatchUpdateQueryOwnershipInput { +""" +Payload for specifying targets for batch updating query ownership +""" + targetType: QueryOwnership_SelectionTargetType! +""" +Payload for specifying targets for batch updating query ownership +""" + ids: [String!]! +} + +type BlockIngestMutation { + repository: Repository! +} + +input BlockIngestOnOrgInput { + blockIngest: Boolean! +} + +type BooleanResultType { + result: Boolean! +} + +""" +By proxy authentication. Authentication is provided by proxy. +""" +type ByProxyAuthentication implements AuthenticationMethod{ + name: String! +} + +""" +A policy for choosing which segments to cache on local disk when overcommiting +local storage with bucket storage. + +This can be used to protect certain repositories for local storage, such that +searching other repositories does not evict them. + +A cache policy in LogScale divides segments into prioritized and non-prioritized +segments. When segments needs to be evicted from local storage, we always try +evicting non-prioritized segments before prioritized segments. + +A cache policy can be set either on one of three levels (in order of precedence): + - Repo + - Org + - Globally + + When determining the cache policy for a repo we first check if there is a cache + policy set on the repo. If none is set on the repo, we check the the org. If none + is set there either we check the global setting. + +""" +input CachePolicyInput { +""" +A policy for choosing which segments to cache on local disk when overcommiting +local storage with bucket storage. + +This can be used to protect certain repositories for local storage, such that +searching other repositories does not evict them. + +A cache policy in LogScale divides segments into prioritized and non-prioritized +segments. When segments needs to be evicted from local storage, we always try +evicting non-prioritized segments before prioritized segments. + +A cache policy can be set either on one of three levels (in order of precedence): + - Repo + - Org + - Globally + + When determining the cache policy for a repo we first check if there is a cache + policy set on the repo. If none is set on the repo, we check the the org. If none + is set there either we check the global setting. + +""" + prioritizeMillis: Long +} + +input CancelRedactEventsInput { + repositoryName: String! + redactionTaskId: String! +} + +""" +Data for clearing the error on an aggregate alert. +""" +input ClearErrorOnAggregateAlertInput { +""" +Data for clearing the error on an aggregate alert. +""" + viewName: RepoOrViewName! +""" +Data for clearing the error on an aggregate alert. +""" + id: String! +} + +""" +Data for clearing the error on an alert +""" +input ClearErrorOnAlertInput { +""" +Data for clearing the error on an alert +""" + viewName: String! +""" +Data for clearing the error on an alert +""" + id: String! +} + +""" +Data for clearing the error on a filter alert +""" +input ClearErrorOnFilterAlertInput { +""" +Data for clearing the error on a filter alert +""" + viewName: RepoOrViewName! +""" +Data for clearing the error on a filter alert +""" + id: String! +} + +""" +Data for clearing the error on a scheduled search +""" +input ClearErrorOnScheduledSearchInput { +""" +Data for clearing the error on a scheduled search +""" + viewName: String! +""" +Data for clearing the error on a scheduled search +""" + id: String! +} + +input ClearFieldConfigurationsInput { + viewOrRepositoryName: String! +} + +input ClearRecentQueriesInput { + viewOrRepositoryName: String! +} + +""" +Data for clearing the search limit on a search domain. +""" +input ClearSearchLimitForSearchDomain { +""" +Data for clearing the search limit on a search domain. +""" + id: String! +} + +""" +Input data to clone an existing parser +""" +input CloneParserInput { +""" +Input data to clone an existing parser +""" + newParserName: String! +""" +Input data to clone an existing parser +""" + repositoryName: String! +""" +Input data to clone an existing parser +""" + parserIdToClone: String! +} + +""" +Whether a column has been added or removed at the given index +""" +input ColumnChange { +""" +Whether a column has been added or removed at the given index +""" + changeKind: ColumnChangeKind! +""" +Whether a column has been added or removed at the given index +""" + index: Int! +} + +enum ColumnChangeKind { + Remove + Add +} + +input ConflictResolutionConfiguration { + entityType: AssetType! + entityName: String! + conflictResolution: MergeStrategy! +} + +type CopyDashboardMutation { + dashboard: Dashboard! +} + +type CreateActionFromPackageTemplateMutation { + action: Action! +} + +""" +Data for creating an action from a yaml template +""" +input CreateActionFromTemplateInput { +""" +Data for creating an action from a yaml template +""" + viewName: RepoOrViewName! +""" +Data for creating an action from a yaml template +""" + name: String! +""" +Data for creating an action from a yaml template +""" + yamlTemplate: YAML! +} + +""" +Data for creating an aggregate alert. +""" +input CreateAggregateAlert { +""" +Data for creating an aggregate alert. +""" + viewName: RepoOrViewName! +""" +Data for creating an aggregate alert. +""" + name: String! +""" +Data for creating an aggregate alert. +""" + description: String +""" +Data for creating an aggregate alert. +""" + queryString: String! +""" +Data for creating an aggregate alert. +""" + actionIdsOrNames: [String!]! +""" +Data for creating an aggregate alert. +""" + labels: [String!] +""" +Data for creating an aggregate alert. +""" + enabled: Boolean +""" +Data for creating an aggregate alert. +""" + throttleTimeSeconds: Long! +""" +Data for creating an aggregate alert. +""" + throttleField: String +""" +Data for creating an aggregate alert. +""" + searchIntervalSeconds: Long! +""" +Data for creating an aggregate alert. +""" + queryTimestampType: QueryTimestampType! +""" +Data for creating an aggregate alert. +""" + triggerMode: TriggerMode +""" +Data for creating an aggregate alert. +""" + runAsUserId: String +""" +Data for creating an aggregate alert. +""" + queryOwnershipType: QueryOwnershipType! +} + +""" +Data for creating an alert +""" +input CreateAlert { +""" +Data for creating an alert +""" + viewName: String! +""" +Data for creating an alert +""" + name: String! +""" +Data for creating an alert +""" + description: String +""" +Data for creating an alert +""" + queryString: String! +""" +Data for creating an alert +""" + queryStart: String! +""" +Data for creating an alert +""" + throttleTimeMillis: Long! +""" +Data for creating an alert +""" + throttleField: String +""" +Data for creating an alert +""" + runAsUserId: String +""" +Data for creating an alert +""" + enabled: Boolean +""" +Data for creating an alert +""" + actions: [String!]! +""" +Data for creating an alert +""" + labels: [String!] +""" +Data for creating an alert +""" + queryOwnershipType: QueryOwnershipType +} + +type CreateAlertFromPackageTemplateMutation { + alert: Alert! +} + +""" +Data for creating an alert from a yaml template +""" +input CreateAlertFromTemplateInput { +""" +Data for creating an alert from a yaml template +""" + viewName: RepoOrViewName! +""" +Data for creating an alert from a yaml template +""" + name: String! +""" +Data for creating an alert from a yaml template +""" + yamlTemplate: YAML! +} + +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" +input CreateAwsS3SqsIngestFeed { +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + repositoryName: RepoOrViewName! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + name: String! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + description: String +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + parser: String! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + authentication: IngestFeedAwsAuthenticationInput! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + sqsUrl: String! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + region: String! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + enabled: Boolean! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + preprocessing: IngestFeedPreprocessingInput! +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + compression: IngestFeedCompression! +} + +input CreateCustomLinkInteractionInput { + path: String! + customLinkInteractionInput: CustomLinkInteractionInput! +} + +type CreateDashboardFromPackageTemplateMutation { + dashboard: Dashboard! +} + +""" +Data for creating a dashboard from a yaml specification. +""" +input CreateDashboardFromTemplateV2Input { +""" +Data for creating a dashboard from a yaml specification. +""" + viewName: RepoOrViewName! +""" +Data for creating a dashboard from a yaml specification. +""" + name: String! +""" +Data for creating a dashboard from a yaml specification. +""" + yamlTemplate: YAML! +} + +input CreateDashboardInput { + searchDomainName: String! + name: String! + labels: [String!] + widgets: [WidgetInput!] + sections: [SectionInput!] + links: [LinkInput!] + defaultFilterId: String + filters: [FilterInput!] + parameters: [ParameterInput!] + description: String + updateFrequency: DashboardUpdateFrequencyInput +} + +input CreateDashboardLinkInteractionInput { + path: String! + dashboardLinkInteractionInput: DashboardLinkInteractionInput! +} + +type CreateDashboardMutation { + dashboard: Dashboard! +} + +""" +Data for creating an email action +""" +input CreateEmailAction { +""" +Data for creating an email action +""" + viewName: String! +""" +Data for creating an email action +""" + name: String! +""" +Data for creating an email action +""" + recipients: [String!]! +""" +Data for creating an email action +""" + subjectTemplate: String +""" +Data for creating an email action +""" + bodyTemplate: String +""" +Data for creating an email action +""" + useProxy: Boolean! +""" +Data for creating an email action +""" + attachCsv: Boolean +} + +""" +Data for creating an event forwarding rule +""" +input CreateEventForwardingRule { +""" +Data for creating an event forwarding rule +""" + repoName: String! +""" +Data for creating an event forwarding rule +""" + queryString: String! +""" +Data for creating an event forwarding rule +""" + eventForwarderId: String! +""" +Data for creating an event forwarding rule +""" + languageVersion: LanguageVersionEnum +} + +""" +Data for creating an FDR feed +""" +input CreateFdrFeed { +""" +Data for creating an FDR feed +""" + repositoryName: String! +""" +Data for creating an FDR feed +""" + name: String! +""" +Data for creating an FDR feed +""" + description: String +""" +Data for creating an FDR feed +""" + parser: String! +""" +Data for creating an FDR feed +""" + clientId: String! +""" +Data for creating an FDR feed +""" + clientSecret: String! +""" +Data for creating an FDR feed +""" + sqsUrl: String! +""" +Data for creating an FDR feed +""" + s3Identifier: String! +""" +Data for creating an FDR feed +""" + enabled: Boolean +} + +input CreateFieldAliasSchemaInput { + name: String! + fields: [SchemaFieldInput!]! + aliasMappings: [AliasMappingInput!] +} + +""" +Data for creating a filter alert +""" +input CreateFilterAlert { +""" +Data for creating a filter alert +""" + viewName: RepoOrViewName! +""" +Data for creating a filter alert +""" + name: String! +""" +Data for creating a filter alert +""" + description: String +""" +Data for creating a filter alert +""" + queryString: String! +""" +Data for creating a filter alert +""" + actionIdsOrNames: [String!]! +""" +Data for creating a filter alert +""" + labels: [String!] +""" +Data for creating a filter alert +""" + enabled: Boolean +""" +Data for creating a filter alert +""" + throttleTimeSeconds: Long +""" +Data for creating a filter alert +""" + throttleField: String +""" +Data for creating a filter alert +""" + runAsUserId: String +""" +Data for creating a filter alert +""" + queryOwnershipType: QueryOwnershipType! +} + +""" +Data for creating a LogScale repository action +""" +input CreateHumioRepoAction { +""" +Data for creating a LogScale repository action +""" + viewName: String! +""" +Data for creating a LogScale repository action +""" + name: String! +""" +Data for creating a LogScale repository action +""" + ingestToken: String! +} + +""" +Input data to create an ingest listener +""" +input CreateIngestListenerV3Input { +""" +Input data to create an ingest listener +""" + repositoryName: String! +""" +Input data to create an ingest listener +""" + port: Int! +""" +Input data to create an ingest listener +""" + protocol: IngestListenerProtocol! +""" +Input data to create an ingest listener +""" + vHost: Int +""" +Input data to create an ingest listener +""" + name: String! +""" +Input data to create an ingest listener +""" + bindInterface: String! +""" +Input data to create an ingest listener +""" + parser: String! +""" +Input data to create an ingest listener +""" + charset: String! +} + +""" +Data for creating a Kafka event forwarder +""" +input CreateKafkaEventForwarder { +""" +Data for creating a Kafka event forwarder +""" + name: String! +""" +Data for creating a Kafka event forwarder +""" + description: String! +""" +Data for creating a Kafka event forwarder +""" + properties: String! +""" +Data for creating a Kafka event forwarder +""" + topic: String! +""" +Data for creating a Kafka event forwarder +""" + enabled: Boolean +} + +""" +Data for creating a local multi-cluster connection +""" +input CreateLocalClusterConnectionInput { +""" +Data for creating a local multi-cluster connection +""" + multiClusterViewName: String! +""" +Data for creating a local multi-cluster connection +""" + targetViewName: String! +""" +Data for creating a local multi-cluster connection +""" + tags: [ClusterConnectionInputTag!] +""" +Data for creating a local multi-cluster connection +""" + queryPrefix: String +} + +""" +Data for creating an OpsGenie action +""" +input CreateOpsGenieAction { +""" +Data for creating an OpsGenie action +""" + viewName: String! +""" +Data for creating an OpsGenie action +""" + name: String! +""" +Data for creating an OpsGenie action +""" + apiUrl: String! +""" +Data for creating an OpsGenie action +""" + genieKey: String! +""" +Data for creating an OpsGenie action +""" + useProxy: Boolean! +} + +""" +The specification of an external function. +""" +input CreateOrUpdateExternalFunctionInput { +""" +The specification of an external function. +""" + name: String! +""" +The specification of an external function. +""" + procedureURL: String! +""" +The specification of an external function. +""" + parameters: [ParameterSpecificationInput!]! +""" +The specification of an external function. +""" + description: String! +""" +The specification of an external function. +""" + kind: KindInput! +} + +input CreateOrganizationPermissionTokenInput { + name: String! + expireAt: Long + ipFilterId: String + permissions: [OrganizationPermission!]! +} + +""" +Data for creating a PagerDuty action. +""" +input CreatePagerDutyAction { +""" +Data for creating a PagerDuty action. +""" + viewName: String! +""" +Data for creating a PagerDuty action. +""" + name: String! +""" +Data for creating a PagerDuty action. +""" + severity: String! +""" +Data for creating a PagerDuty action. +""" + routingKey: String! +""" +Data for creating a PagerDuty action. +""" + useProxy: Boolean! +} + +type CreateParserFromPackageTemplateMutation { + parser: Parser! +} + +""" +Data for creating a parser from a yaml template +""" +input CreateParserFromTemplateInput { +""" +Data for creating a parser from a yaml template +""" + viewName: RepoOrViewName! +""" +Data for creating a parser from a yaml template +""" + name: String! +""" +Data for creating a parser from a yaml template +""" + yamlTemplate: YAML! +} + +input CreateParserInput { + name: String! + testData: [String!]! + sourceCode: String! + repositoryName: String! + tagFields: [String!]! + force: Boolean! + languageVersion: LanguageVersionEnum +} + +""" +Input for creating a parser. +""" +input CreateParserInputV2 { +""" +Input for creating a parser. +""" + name: String! +""" +Input for creating a parser. +""" + script: String! +""" +Input for creating a parser. +""" + testCases: [ParserTestCaseInput!]! +""" +Input for creating a parser. +""" + repositoryName: RepoOrViewName! +""" +Input for creating a parser. +""" + fieldsToTag: [String!]! +""" +Input for creating a parser. +""" + fieldsToBeRemovedBeforeParsing: [String!]! +""" +Input for creating a parser. +""" + allowOverwritingExistingParser: Boolean +""" +Input for creating a parser. +""" + languageVersion: LanguageVersionInputType +} + +type CreateParserMutation { + parser: Parser! +} + +input CreatePersonalUserTokenInput { + expireAt: Long + ipFilterId: String +} + +""" +Data for creating a post message Slack action. +""" +input CreatePostMessageSlackAction { +""" +Data for creating a post message Slack action. +""" + viewName: String! +""" +Data for creating a post message Slack action. +""" + name: String! +""" +Data for creating a post message Slack action. +""" + apiToken: String! +""" +Data for creating a post message Slack action. +""" + channels: [String!]! +""" +Data for creating a post message Slack action. +""" + fields: [SlackFieldEntryInput!]! +""" +Data for creating a post message Slack action. +""" + useProxy: Boolean! +} + +""" +Data for creating a remote cluster connection +""" +input CreateRemoteClusterConnectionInput { +""" +Data for creating a remote cluster connection +""" + multiClusterViewName: String! +""" +Data for creating a remote cluster connection +""" + publicUrl: String! +""" +Data for creating a remote cluster connection +""" + token: String! +""" +Data for creating a remote cluster connection +""" + tags: [ClusterConnectionInputTag!] +""" +Data for creating a remote cluster connection +""" + queryPrefix: String +} + +type CreateRepositoryMutation { + repository: Repository! +} + +type CreateSavedQueryFromPackageTemplateMutation { + savedQuery: SavedQuery! +} + +input CreateSavedQueryInput { + name: String! + viewName: String! + queryString: String! + start: String + end: String + isLive: Boolean + widgetType: String + options: String + dashboardLinkInteractions: [DashboardLinkInteractionInput!] + customLinkInteractions: [CustomLinkInteractionInput!] + searchLinkInteractions: [SearchLinkInteractionInput!] + updateParametersInteractions: [UpdateParametersInteractionInput!] +} + +type CreateSavedQueryPayload { + savedQuery: SavedQuery! +} + +""" +Data for creating a scheduled report. +""" +input CreateScheduledReportInput { +""" +Data for creating a scheduled report. +""" + viewName: String! +""" +Data for creating a scheduled report. +""" + name: String! +""" +Data for creating a scheduled report. +""" + password: String +""" +Data for creating a scheduled report. +""" + enabled: Boolean! +""" +Data for creating a scheduled report. +""" + description: String! +""" +Data for creating a scheduled report. +""" + dashboardId: String! +""" +Data for creating a scheduled report. +""" + timeIntervalFrom: String +""" +Data for creating a scheduled report. +""" + schedule: CreateScheduledReportScheduleInput! +""" +Data for creating a scheduled report. +""" + labels: [String!]! +""" +Data for creating a scheduled report. +""" + parameters: [CreateScheduledReportParameterValueInput!]! +""" +Data for creating a scheduled report. +""" + recipients: [String!]! +""" +Data for creating a scheduled report. +""" + layout: CreateScheduledReportLayoutInput! +} + +""" +Layout of the scheduled report. +""" +input CreateScheduledReportLayoutInput { +""" +Layout of the scheduled report. +""" + paperSize: String! +""" +Layout of the scheduled report. +""" + paperOrientation: String! +""" +Layout of the scheduled report. +""" + paperLayout: String! +""" +Layout of the scheduled report. +""" + showDescription: Boolean! +""" +Layout of the scheduled report. +""" + showTitleFrontpage: Boolean! +""" +Layout of the scheduled report. +""" + showParameters: Boolean! +""" +Layout of the scheduled report. +""" + maxNumberOfRows: Int! +""" +Layout of the scheduled report. +""" + showTitleHeader: Boolean! +""" +Layout of the scheduled report. +""" + showExportDate: Boolean! +""" +Layout of the scheduled report. +""" + footerShowPageNumbers: Boolean! +} + +""" +List of parameter value configurations. +""" +input CreateScheduledReportParameterValueInput { +""" +List of parameter value configurations. +""" + id: String! +""" +List of parameter value configurations. +""" + value: String! +} + +""" +The schedule to run the report by. +""" +input CreateScheduledReportScheduleInput { +""" +The schedule to run the report by. +""" + cronExpression: String! +""" +The schedule to run the report by. +""" + timeZone: String! +""" +The schedule to run the report by. +""" + startDate: Long! +""" +The schedule to run the report by. +""" + endDate: Long +} + +""" +Data for creating a scheduled search +""" +input CreateScheduledSearch { +""" +Data for creating a scheduled search +""" + viewName: String! +""" +Data for creating a scheduled search +""" + name: String! +""" +Data for creating a scheduled search +""" + description: String +""" +Data for creating a scheduled search +""" + queryString: String! +""" +Data for creating a scheduled search +""" + queryStart: String! +""" +Data for creating a scheduled search +""" + queryEnd: String! +""" +Data for creating a scheduled search +""" + schedule: String! +""" +Data for creating a scheduled search +""" + timeZone: String! +""" +Data for creating a scheduled search +""" + backfillLimit: Int! +""" +Data for creating a scheduled search +""" + enabled: Boolean +""" +Data for creating a scheduled search +""" + actions: [String!]! +""" +Data for creating a scheduled search +""" + labels: [String!] +""" +Data for creating a scheduled search +""" + runAsUserId: String +""" +Data for creating a scheduled search +""" + queryOwnershipType: QueryOwnershipType +} + +""" +Data for creating a scheduled search from a yaml template. +""" +input CreateScheduledSearchFromTemplateInput { +""" +Data for creating a scheduled search from a yaml template. +""" + viewName: RepoOrViewName! +""" +Data for creating a scheduled search from a yaml template. +""" + name: String! +""" +Data for creating a scheduled search from a yaml template. +""" + yamlTemplate: YAML! +} + +input CreateSearchLinkInteractionInput { + path: String! + searchLinkInteractionInput: SearchLinkInteractionInput! +} + +""" +Data for creating a Slack action. +""" +input CreateSlackAction { +""" +Data for creating a Slack action. +""" + viewName: String! +""" +Data for creating a Slack action. +""" + name: String! +""" +Data for creating a Slack action. +""" + url: String! +""" +Data for creating a Slack action. +""" + fields: [SlackFieldEntryInput!]! +""" +Data for creating a Slack action. +""" + useProxy: Boolean! +} + +input CreateSystemPermissionTokenInput { + name: String! + expireAt: Long + ipFilterId: String + permissions: [SystemPermission!]! +} + +""" +Data for creating an upload file action. +""" +input CreateUploadFileAction { +""" +Data for creating an upload file action. +""" + viewName: String! +""" +Data for creating an upload file action. +""" + name: String! +""" +Data for creating an upload file action. +""" + fileName: String! +} + +""" +Data for creating a VictorOps action. +""" +input CreateVictorOpsAction { +""" +Data for creating a VictorOps action. +""" + viewName: String! +""" +Data for creating a VictorOps action. +""" + name: String! +""" +Data for creating a VictorOps action. +""" + messageType: String! +""" +Data for creating a VictorOps action. +""" + notifyUrl: String! +""" +Data for creating a VictorOps action. +""" + useProxy: Boolean! +} + +input CreateViewPermissionsTokenInput { + name: String! + expireAt: Long + ipFilterId: String + viewIds: [String!]! + permissions: [Permission!]! +} + +""" +Data for creating a webhook action. +""" +input CreateWebhookAction { +""" +Data for creating a webhook action. +""" + viewName: String! +""" +Data for creating a webhook action. +""" + name: String! +""" +Data for creating a webhook action. +""" + url: String! +""" +Data for creating a webhook action. +""" + method: String! +""" +Data for creating a webhook action. +""" + headers: [HttpHeaderEntryInput!]! +""" +Data for creating a webhook action. +""" + bodyTemplate: String! +""" +Data for creating a webhook action. +""" + ignoreSSL: Boolean! +""" +Data for creating a webhook action. +""" + useProxy: Boolean! +} + +input CustomLinkInteractionInput { + name: String! + titleTemplate: String + urlTemplate: String! + openInNewTab: Boolean! + urlEncodeArgs: Boolean + fieldInteractionConditions: [FieldInteractionConditionInput!] +} + +input DashboardLinkInteractionInput { + name: String! + titleTemplate: String + arguments: [ArgumentInput!]! + dashboardId: String + dashboardName: String + dashboardRepoOrViewName: RepoOrViewName + packageSpecifier: UnversionedPackageSpecifier + openInNewTab: Boolean! + useWidgetTimeWindow: Boolean! + fieldInteractionConditions: [FieldInteractionConditionInput!] +} + +""" +The frequency at which a dashboard updates its results. +""" +enum DashboardUpdateFrequency { + RealTime + Never +} + +input DashboardUpdateFrequencyInput { + updateFrequencyType: DashboardUpdateFrequency! +} + +""" +Data for deleting an action. +""" +input DeleteAction { +""" +Data for deleting an action. +""" + viewName: String! +""" +Data for deleting an action. +""" + id: String! +} + +""" +Data for deleting an aggregate alert. +""" +input DeleteAggregateAlert { +""" +Data for deleting an aggregate alert. +""" + viewName: RepoOrViewName! +""" +Data for deleting an aggregate alert. +""" + id: String! +} + +""" +Data for deleting an alert +""" +input DeleteAlert { +""" +Data for deleting an alert +""" + viewName: String! +""" +Data for deleting an alert +""" + id: String! +} + +""" +Data for deleting a cluster connection +""" +input DeleteClusterConnectionInput { +""" +Data for deleting a cluster connection +""" + multiClusterViewName: String! +""" +Data for deleting a cluster connection +""" + connectionId: String! +} + +input DeleteDashboardInput { + id: String! +} + +""" +The data for deleting a dashboard +""" +input DeleteDashboardInputV2 { +""" +The data for deleting a dashboard +""" + viewId: String! +""" +The data for deleting a dashboard +""" + dashboardId: String! +} + +type DeleteDashboardMutation { + dashboard: Dashboard! +} + +""" +Data for deleting an event forwarder +""" +input DeleteEventForwarderInput { +""" +Data for deleting an event forwarder +""" + id: String! +} + +""" +Data for deleting an event forwarding rule +""" +input DeleteEventForwardingRule { +""" +Data for deleting an event forwarding rule +""" + repoName: String! +""" +Data for deleting an event forwarding rule +""" + id: String! +} + +""" +Data for deleting an FDR feed +""" +input DeleteFdrFeed { +""" +Data for deleting an FDR feed +""" + repositoryName: String! +""" +Data for deleting an FDR feed +""" + id: String! +} + +input DeleteFieldAliasSchema { + schemaId: String! +} + +""" +Data for deleting a filter alert +""" +input DeleteFilterAlert { +""" +Data for deleting a filter alert +""" + viewName: RepoOrViewName! +""" +Data for deleting a filter alert +""" + id: String! +} + +""" +Data for deleting an ingest feed +""" +input DeleteIngestFeed { +""" +Data for deleting an ingest feed +""" + repositoryName: RepoOrViewName! +""" +Data for deleting an ingest feed +""" + id: String! +} + +input DeleteInteractionInput { + path: String! + id: String! +} + +input DeleteParserInput { + id: String! + repositoryName: RepoOrViewName! +} + +input DeleteSavedQueryInput { + id: String! + viewName: String! +} + +""" +Data for deleting a scheduled report. +""" +input DeleteScheduledReportInput { +""" +Data for deleting a scheduled report. +""" + viewName: String! +""" +Data for deleting a scheduled report. +""" + id: String! +} + +""" +Data for deleting a scheduled search +""" +input DeleteScheduledSearch { +""" +Data for deleting a scheduled search +""" + viewName: String! +""" +Data for deleting a scheduled search +""" + id: String! +} + +input DeleteSearchDomainByIdInput { + id: String! + deleteMessage: String +} + +""" +Data for disabling an aggregate alert. +""" +input DisableAggregateAlert { +""" +Data for disabling an aggregate alert. +""" + viewName: RepoOrViewName! +""" +Data for disabling an aggregate alert. +""" + id: String! +} + +""" +Data for disabling an alert +""" +input DisableAlert { +""" +Data for disabling an alert +""" + viewName: RepoOrViewName! +""" +Data for disabling an alert +""" + id: String! +} + +""" +Data for disabling an event forwarder +""" +input DisableEventForwarderInput { +""" +Data for disabling an event forwarder +""" + id: String! +} + +input DisableFieldAliasSchemaOnOrgInput { + schemaId: String! +} + +input DisableFieldAliasSchemaOnViewInput { + viewName: String! + schemaId: String! +} + +""" +Data for disabling a filter alert +""" +input DisableFilterAlert { +""" +Data for disabling a filter alert +""" + viewName: RepoOrViewName! +""" +Data for disabling a filter alert +""" + id: String! +} + +""" +Data for disabling access to IOCs (indicators of compromise) for an organization +""" +input DisableOrganizationIocAccess { +""" +Data for disabling access to IOCs (indicators of compromise) for an organization +""" + organizationId: String! +} + +""" +Data for disabling a scheduled report. +""" +input DisableScheduledReportInput { +""" +Data for disabling a scheduled report. +""" + viewName: String! +""" +Data for disabling a scheduled report. +""" + id: String! +} + +""" +Data for disabling a scheduled search +""" +input DisableStarScheduledSearch { +""" +Data for disabling a scheduled search +""" + viewName: String! +""" +Data for disabling a scheduled search +""" + id: String! +} + +input DynamicConfigInputObject { + config: DynamicConfig! + value: String! +} + +""" +An email action. +""" +type EmailAction implements Action{ +""" +List of email addresses to send an email to. +""" + recipients: [String!]! +""" +Subject of the email. Can be templated with values from the result. +""" + subjectTemplate: String +""" +Body of the email. Can be templated with values from the result. +""" + bodyTemplate: String +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +Whether the result set should be be attached as a CSV file. +""" + attachCsv: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +Data for enabling an aggregate alert. +""" +input EnableAggregateAlert { +""" +Data for enabling an aggregate alert. +""" + viewName: RepoOrViewName! +""" +Data for enabling an aggregate alert. +""" + id: String! +} + +""" +Data for enabling an alert +""" +input EnableAlert { +""" +Data for enabling an alert +""" + viewName: RepoOrViewName! +""" +Data for enabling an alert +""" + id: String! +} + +""" +Data for enabling an event forwarder +""" +input EnableEventForwarderInput { +""" +Data for enabling an event forwarder +""" + id: String! +} + +input EnableFieldAliasSchemaOnOrgInput { + schemaId: String! +} + +input EnableFieldAliasSchemaOnViewsInput { + viewNames: [String!]! + schemaId: String! +} + +""" +Data for enabling a filter alert +""" +input EnableFilterAlert { +""" +Data for enabling a filter alert +""" + viewName: RepoOrViewName! +""" +Data for enabling a filter alert +""" + id: String! +} + +""" +Data for enabling access to IOCs (indicators of compromise) for an organization +""" +input EnableOrganizationIocAccess { +""" +Data for enabling access to IOCs (indicators of compromise) for an organization +""" + organizationId: String! +} + +""" +Data for enabling a scheduled report. +""" +input EnableScheduledReportInput { +""" +Data for enabling a scheduled report. +""" + viewName: String! +""" +Data for enabling a scheduled report. +""" + id: String! +} + +""" +Data for enabling a scheduled search +""" +input EnableStarScheduledSearch { +""" +Data for enabling a scheduled search +""" + viewName: String! +""" +Data for enabling a scheduled search +""" + id: String! +} + +input EnableWorkerQueryTracingInputType { + quotaKey: String! + expiry: DateTime! +} + +""" +Enable or disable language restrictions +""" +input EnabledInput { +""" +Enable or disable language restrictions +""" + version: LanguageVersionEnum! +""" +Enable or disable language restrictions +""" + enabled: Boolean! +} + +input EnforceSubdomainsInput { + enforce: Boolean! +} + +""" +Information about an enrolled collector +""" +type EnrolledCollector { + id: String! + configId: String + machineId: String! +} + +""" +Enterprise only authentication. +""" +type EnterpriseOnlyAuthentication implements AuthenticationMethod{ + name: String! +} + +""" +A single field in an event with a name and a value +""" +type EventField { +""" +The name of the field +""" + fieldName: String! +""" +The value of the field +""" + value: String! +} + +""" +A single field in an event with a key and a value +""" +type Field { +""" +The key of the field +""" + key: String! +""" +The value of the field +""" + value: String! +} + +input FieldConfigurationInput { + viewId: String! + fieldName: String! + json: JSON! +} + +""" +Assertion results can be uniquely identified by the output event index and the field name they operate on. So if the same field on the same event has multiple assertions attached, this failure is produced. +""" +type FieldHadConflictingAssertions { +""" +Field being asserted on. +""" + fieldName: String! +} + +""" +An assertion was made that a field had some value, and this assertion failed due to an unexpected value for the field. +""" +type FieldHadUnexpectedValue { +""" +Field being asserted on. +""" + fieldName: String! +""" +Value that was asserted to be contained in the field. +""" + expectedValue: String! +""" +The actual value of the field. Note that this is null in the case where the field wasn't present at all. +""" + actualValue: String +} + +""" +Asserts that a given field has an expected value after having been parsed. +""" +input FieldHasValueInput { +""" +Asserts that a given field has an expected value after having been parsed. +""" + fieldName: String! +""" +Asserts that a given field has an expected value after having been parsed. +""" + expectedValue: String! +} + +input FieldInteractionConditionInput { + fieldName: String! + operator: FieldConditionOperatorType! + argument: String! +} + +""" +An assertion was made that a field should not be present, and this assertion failed. +""" +type FieldUnexpectedlyPresent { +""" +Field being asserted on. +""" + fieldName: String! +""" +The value that the field contained. +""" + actualValue: String! +} + +""" +A dashboard parameter where suggestions are taken from uploaded files. +""" +type FileDashboardParameter implements DashboardParameter{ +""" +The name of the file to perform lookups in. +""" + fileName: String! +""" +The column where the value of suggestions are taken from, +""" + valueColumn: String! +""" +The column where the label of suggestions are taken from, +""" + labelColumn: String +""" +Fields and values, where an entry in a file must match one of the given values for each field. +""" + valueFilters: [FileParameterValueFilter!]! +""" +Regex patterns used to block parameter input. +""" + invalidInputPatterns: [String!] +""" +Message when parameter input is blocked. +""" + invalidInputMessage: String +""" +The ID of the parameter. +""" + id: String! +""" +The label or 'name' displayed next to the input for the variable to make it more human-readable. +""" + label: String! +""" +The value assigned to the parameter on dashboard load, if no other value is specified. +""" + defaultValueV2: String +""" +A number that determines the order in which parameters are displayed on a dashboard. If null, the parameter is ordered after other parameters in alphanumerical order. +""" + order: Int +""" +A number that determines the width of a parameter. +""" + width: Int +""" +[PREVIEW: The multi-value parameters feature is still in development.] A flag indicating whether the parameter supports having multiple values +""" + isMultiParam: Boolean +""" +[PREVIEW: The multi-value parameters feature is still in development.] The value assigned to the multi-value parameter on dashboard load, if no other value is specified. This replaces defaultValue whenever isMultiParam is true +""" + defaultMultiValues: [String!] +} + +""" +A filter to reduce entries from files down to those with a matching value in the field. +""" +type FileParameterValueFilter { + field: String! + values: [String!]! +} + +input FilterInput { + id: String! + name: String! + prefix: String! +} + +""" +A dashboard parameter with a fixed list of values to select from. +""" +type FixedListDashboardParameter implements DashboardParameter{ + values: [FixedListParameterOption!]! +""" +The ID of the parameter. +""" + id: String! +""" +The label or 'name' displayed next to the input for the variable to make it more human-readable. +""" + label: String! +""" +The value assigned to the parameter on dashboard load, if no other value is specified. +""" + defaultValueV2: String +""" +A number that determines the order in which parameters are displayed on a dashboard. If null, the parameter is ordered after other parameters in alphanumerical order. +""" + order: Int +""" +A number that determines the width of a parameter. +""" + width: Int +""" +[PREVIEW: The multi-value parameters feature is still in development.] A flag indicating whether the parameter supports having multiple values +""" + isMultiParam: Boolean +""" +[PREVIEW: The multi-value parameters feature is still in development.] The value assigned to the multi-value parameter on dashboard load, if no other value is specified. This replaces defaultValue whenever isMultiParam is true +""" + defaultMultiValues: [String!] +} + +""" +An option in a fixed list parameter. +""" +type FixedListParameterOption { + label: String! + value: String! +} + +type FleetConfigurationTest { + collectorIds: [String!]! + configId: String! +} + +""" +A dashboard parameter without restrictions or suggestions. +""" +type FreeTextDashboardParameter implements DashboardParameter{ +""" +Regex patterns used to block parameter input. +""" + invalidInputPatterns: [String!] +""" +Message when parameter input is blocked. +""" + invalidInputMessage: String +""" +The ID of the parameter. +""" + id: String! +""" +The label or 'name' displayed next to the input for the variable to make it more human-readable. +""" + label: String! +""" +The value assigned to the parameter on dashboard load, if no other value is specified. +""" + defaultValueV2: String +""" +A number that determines the order in which parameters are displayed on a dashboard. If null, the parameter is ordered after other parameters in alphanumerical order. +""" + order: Int +""" +A number that determines the width of a parameter. +""" + width: Int +""" +[PREVIEW: The multi-value parameters feature is still in development.] A flag indicating whether the parameter supports having multiple values +""" + isMultiParam: Boolean +""" +[PREVIEW: The multi-value parameters feature is still in development.] The value assigned to the multi-value parameter on dashboard load, if no other value is specified. This replaces defaultValue whenever isMultiParam is true +""" + defaultMultiValues: [String!] +} + +""" +Input list of function names +""" +input FunctionListInput { +""" +Input list of function names +""" + version: LanguageVersionEnum! +""" +Input list of function names +""" + functions: [String!]! +} + +""" +The organization management roles of the group. +""" +type GroupOrganizationManagementRole { + role: Role! +} + +input GroupRoleAssignment { + groupId: String! + roleId: String! +} + +""" +A http request header. +""" +type HttpHeaderEntry { +""" +Key of a http(s) header. +""" + header: String! +""" +Value of a http(s) header. +""" + value: String! +} + +""" +Http(s) Header entry. +""" +input HttpHeaderEntryInput { +""" +Http(s) Header entry. +""" + header: String! +""" +Http(s) Header entry. +""" + value: String! +} + +""" +A LogScale repository action. +""" +type HumioRepoAction implements Action{ +""" +Humio ingest token for the dataspace that the action should ingest into. +""" + ingestToken: String! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +input IPFilterIdInput { + id: String! +} + +input IPFilterInput { + name: String! + ipFilter: String! +} + +input IPFilterUpdateInput { + id: String! + name: String + ipFilter: String +} + +type Ignored implements contractual{ + includeUsage: Boolean! +} + +""" +How to authenticate to AWS. +""" +input IngestFeedAwsAuthenticationInput { +""" +How to authenticate to AWS. +""" + kind: IngestFeedAwsAuthenticationKind! +""" +How to authenticate to AWS. +""" + roleArn: String +} + +""" +The kind of AWS authentication to use. +""" +enum IngestFeedAwsAuthenticationKind { +""" +IAM role authentication +""" + IamRole +} + +""" +The preprocessing to apply to an ingest feed before parsing. +""" +input IngestFeedPreprocessingInput { +""" +The preprocessing to apply to an ingest feed before parsing. +""" + kind: IngestFeedPreprocessingKind! +} + +input IngestPartitionInput { + id: Int! + nodeIds: [Int!]! +} + +input InputData { + id: String! +} + +input InputDictionaryEntry { + key: String! + value: String! +} + +input InstallPackageFromRegistryInput { + viewName: RepoOrViewName! + packageId: VersionedPackageSpecifier! + queryOwnershipType: QueryOwnershipType +} + +type InstallPackageFromRegistryResult { + package: Package2! +} + +type InstallPackageFromZipResult { + wasSuccessful: Boolean! +} + +type InteractionId { + id: String! +} + +""" +A Kafka event forwarder +""" +type KafkaEventForwarder implements EventForwarder{ +""" +The Kafka topic the events should be forwarded to +""" + topic: String! +""" +The Kafka producer configuration used to forward events in the form of properties (x.y.z=abc). See https://library.humio.com/humio-server/ingesting-data-event-forwarders.html#kafka-configuration. +""" + properties: String! +""" +Id of the event forwarder +""" + id: String! +""" +Name of the event forwarder +""" + name: String! +""" +Description of the event forwarder +""" + description: String! +""" +Is the event forwarder enabled +""" + enabled: Boolean! +} + +""" +Defines how the external function is executed. +""" +input KindInput { +""" +Defines how the external function is executed. +""" + name: KindEnum! +""" +Defines how the external function is executed. +""" + parametersDefiningKeyFields: [String!] +""" +Defines how the external function is executed. +""" + fixedKeyFields: [String!] +} + +type Limited implements contractual{ + limit: Long! + includeUsage: Boolean! +} + +input LinkInput { + name: String! + token: String! +} + +""" +A widget that lists links to other dashboards. +""" +type LinkWidget implements Widget{ + labels: [String!]! + id: String! + title: String! + description: String + x: Int! + y: Int! + width: Int! + height: Int! +} + +""" +A local cluster connection. +""" +type LocalClusterConnection implements ClusterConnection{ +""" +Id of the local view to connect with +""" + targetViewId: String! +""" +Name of the local view to connect with +""" + targetViewName: RepoOrViewName! + targetViewType: LocalTargetType! +""" +Id of the connection +""" + id: String! +""" +Cluster identity of the connection +""" + clusterId: String! +""" +Cluster connection tags +""" + tags: [ClusterConnectionTag!]! +""" +Cluster connection query prefix +""" + queryPrefix: String! +} + +""" +Indicates whether the target of a local cluster connection is a view or a repo +""" +enum LocalTargetType { + View + Repo +} + +input LoginBridgeInput { + name: String! + description: String! + issuer: String! + remoteId: String! + loginUrl: String! + relayStateUrl: String! + samlEntityId: String! + privateSamlCertificate: String! + publicSamlCertificate: String! + allowedUsers: [String!]! + groupAttribute: String! + groups: [String!]! + organizationIdAttributeName: String! + additionalAttributes: String + organizationNameAttribute: String + generateUserName: Boolean! + termsDescription: String! + termsLink: String! +} + +input LoginBridgeUpdateInput { + name: String + description: String + issuer: String + remoteId: String + loginUrl: String + relayStateUrl: String + samlEntityId: String + privateSamlCertificate: String + publicSamlCertificate: String + allowedUsers: [String!] + groupAttribute: String + groups: [String!] + organizationIdAttributeName: String + additionalAttributes: String + organizationNameAttribute: String + generateUserName: Boolean + termsDescription: String + termsLink: String +} + +input MarkLimitDeletedInput { + limitName: String! + deleted: Boolean! +} + +enum MergeStrategy { + Theirs + Ours +} + +input MigrateLimitsInput { + createLogLimit: Boolean! + defaultLimit: String +} + +type Mutation { +""" +[PREVIEW: Feature still in development] Will clear the search limit and excluded repository making future searches done on this view behave normally, i.e. having no search time-limit applied +""" + ClearSearchLimitForSearchDomain( +""" +Data for clearing the search limit on a search domain. +""" + input: ClearSearchLimitForSearchDomain! + ): View! +""" +[PREVIEW: Feature still in development] Will update search limit, which will restrict future searches to the specified limit, a list of repository names can be supplied and will not be restricted by this limit. +""" + SetSearchLimitForSearchDomain( +""" +Data for updating search limit on a search domain. +""" + input: SetSearchLimitForSearchDomain! + ): View! +""" +Client accepts LogScale's Terms and Conditions without providing any additional info +""" + acceptTermsAndConditions: Account! +""" +Activates a user account supplying additional personal info. By activating the account the client accepts LogScale's Terms and Conditions: https://www.humio.com/terms-and-conditions +""" + activateAccount( +""" +The first name of the user. +""" + firstName: String! +""" +The last name of the user. +""" + lastName: String! +""" +The email address of the user. +""" + email: String! +""" +The name of company the user represents or is associated with. +""" + company: String! +""" +The two letter ISO 3166-1 Alpha-2 country code for the country where the company is located. +""" + countryCode: String! +""" +Optional country subdivision following ISO 3166-2. +""" + stateCode: String +""" +Optional zip code. Required for community mode. +""" + zip: String +""" +Optional phone number. Required for community mode. +""" + phoneNumber: String + utmParams: UtmParams + ): Account! +""" +Add a label to an alert. +""" + addAlertLabelV2( +""" +Data for adding a label to an alert +""" + input: AddAlertLabel! + ): Alert! +""" +Add a new filter to a dashboard's list of filters. +""" + addDashboardFilter( + name: String! + prefixFilter: String! + id: String! + searchDomainName: String! + ): Dashboard! +""" +Add a label to a dashboard. +""" + addDashboardLabel( + id: String! + label: String! + ): Dashboard! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Adds a field alias mapping to an existing schema. Returns the ID of the alias mapping if created successfully. +""" + addFieldAliasMapping( + input: AddAliasMappingInput! + ): String! +""" +[PREVIEW: Internal testing.] Enable functions for use with specified language version. +""" + addFunctionsToAllowList( + input: FunctionListInput! + ): Boolean! +""" +Creates a new group. +""" + addGroup( + displayName: String! + lookupName: String + ): AddGroupMutation! +""" +Create a new Ingest API Token. +""" + addIngestTokenV3( + input: AddIngestTokenV3Input! + ): IngestToken! +""" +Add a Limit to the given organization +""" + addLimit( + input: AddLimitInput! + ): Boolean! +""" +Add a Limit to the given organization +""" + addLimitV2( + input: AddLimitV2Input! + ): LimitV2! + addLoginBridgeAllowedUsers( + userID: String! + ): LoginBridge! +""" +Add or update default Query Quota Settings +""" + addOrUpdateQueryQuotaDefaultSettings( + input: QueryQuotaDefaultSettingsInput! + ): QueryQuotaDefaultSettings! +""" +Add or update existing Query Quota User Settings +""" + addOrUpdateQueryQuotaUserSettings( + input: QueryQuotaUserSettingsInput! + ): QueryQuotaUserSettings! +""" +Adds a query to the list of recent queries. The query is a JSON encoded query and visualization structure produced by the UI. +""" + addRecentQuery( + input: AddRecentQueryInput! + ): AddRecentQuery! +""" +Add a label to a scheduled search. +""" + addScheduledSearchLabel( +""" +Data for adding a label to a scheduled search +""" + input: AddLabelScheduledSearch! + ): ScheduledSearch! +""" +Add a star to an alert. +""" + addStarToAlertV2( +""" +Data for adding a star to an alert +""" + input: AddStarToAlert! + ): Alert! +""" +Add a star to a dashboard. +""" + addStarToDashboard( + id: String! + ): Dashboard! + addStarToField( + input: AddStarToFieldInput! + ): AddStarToFieldMutation! +""" +Add a star to a scheduled search. +""" + addStarToScheduledSearch( +""" +Data for adding a star to a scheduled search +""" + input: AddStarScheduledSearch! + ): ScheduledSearch! +""" +Add a star to a repository or view. +""" + addStarToSearchDomain( + name: String! + ): SearchDomain! +""" +[PREVIEW: Requires the feature enabled for the organization.] Adds a subdomain to the organization. Becomes primary subdomain if no primary has been set, and secondary otherwise +""" + addSubdomain( + input: AddSubdomainInput! + ): Organization! +""" +Blocklist a query based on a pattern based on a regex or exact match. +""" + addToBlocklist( +""" +Data for adding to the blocklist +""" + input: AddToBlocklistInput! + ): [BlockedQuery!]! +""" +Blocklist a query based on a pattern based on a regex or exact match. +""" + addToBlocklistById( +""" +Data for adding to the blocklist +""" + input: AddToBlocklistByIdInput! + ): [BlockedQuery!]! +""" +[PREVIEW: Under development] +""" + addToLogCollectorConfigurationTest( + configId: String! + collectorIds: [String!]! + ): FleetConfigurationTest! +""" +Add or invite a user. Calling this with an invitation token, will activate the account. By activating the account the client accepts LogScale's Terms and Conditions: https://www.humio.com/terms-and-conditions +""" + addUserV2( + input: AddUserInputV2! + ): userOrPendingUser! +""" +Adds users to an existing group. +""" + addUsersToGroup( + input: AddUsersToGroupInput! + ): AddUsersToGroupMutation! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Assigns asset permissions to group. Unassignment can be done by providing an empty list of asset permissions for an asset +""" + assignAssetPermissionsToGroup( + input: AssignAssetPermissionsToGroupInputType! + ): Group! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Assigns asset permissions to user. Unassignment can be done by providing an empty list of asset permissions for an asset +""" + assignAssetPermissionsToUser( + input: AssignAssetPermissionsToUserInputType! + ): User! +""" +[PREVIEW: Under development] +""" + assignLogCollectorConfiguration( + configId: String + id: String! + ): Boolean! +""" +[PREVIEW: Under development] +""" + assignLogCollectorsToConfiguration( + configId: String + ids: [String!] + ): [EnrolledCollector!]! +""" +[PREVIEW: Experimental feature to allow assigning permissions to manage a subset of organizations.] Assigns an organization management role to a group for the provided organizations. +""" + assignOrganizationManagementRoleToGroup( + input: AssignOrganizationManagementRoleToGroupInput! + ): AssignOrganizationManagementRoleToGroupMutation! +""" +[PREVIEW: No note] Assigns a organization role to a group. +""" + assignOrganizationRoleToGroup( + input: AssignOrganizationRoleToGroupInput! + ): AssignOrganizationRoleToGroupMutation! +""" +Assign an ingest token to be associated with a parser. +""" + assignParserToIngestTokenV2( + input: AssignParserToIngestTokenInputV2! + ): IngestToken! +""" +Assigns a role to a group for a given view. If called with overrideExistingAssignmentsForView=false, this mutation can assign multiple roles for the same view. Calling with overrideExistingAssignmentsForView=false is thus only available if the MultipleViewRoleBindings feature is enabled. +""" + assignRoleToGroup( + input: AssignRoleToGroupInput! + ): AssignRoleToGroupMutation! +""" +Assigns a system role to a group. +""" + assignSystemRoleToGroup( + input: AssignSystemRoleToGroupInput! + ): AssignSystemRoleToGroupMutation! +""" +Assign node tasks. This is not a replacement, but will add to the existing assigned node tasks. Returns the set of assigned tasks after the assign operation has completed. +""" + assignTasks( +""" +ID of the node to assign node tasks to. +""" + nodeID: Int! +""" +List of tasks to assign. +""" + tasks: [NodeTaskEnum!]! + ): [NodeTaskEnum!]! +""" +[PREVIEW: This mutation is dependent on the MultipleViewRoleBindings feature being enabled.] Assigns roles for the user in the search domain. This mutation allows assigning multiple roles for the same view and is thus dependent on the MultipleViewRoleBindings feature being enabled. +""" + assignUserRolesInSearchDomain( + input: AssignUserRolesInSearchDomainInput! + ): [User!]! +""" +Batch update query ownership to run queries on behalf of the organization for triggers and shared dashboards. +""" + batchUpdateQueryOwnership( + input: BatchUpdateQueryOwnershipInput! + ): Boolean! +""" +Block ingest to the specified repository for a number of seconds (at most 1 year) into the future +""" + blockIngest( + repositoryName: String! + seconds: Int! + ): BlockIngestMutation! +""" +Set whether the organization is blocking ingest and dataspaces are pausing ingest +""" + blockIngestOnOrg( + input: BlockIngestOnOrgInput! + ): Organization! +""" +Cancel a previously submitted redaction. Returns true if the redaction was cancelled, false otherwise. Cancellation is best effort. If some events have already been redacted, they are not restored. +""" + cancelRedactEvents( + input: CancelRedactEventsInput! + ): Boolean! + changeUserAndGroupRolesForSearchDomain( + searchDomainId: String! + groups: [GroupRoleAssignment!]! + users: [UserRoleAssignment!]! + ): [UserOrGroup!]! +""" +Set CID of provisioned organization +""" + clearCid: Organization! +""" +Clear the error status on an aggregate alert. The status will be updated if the error reoccurs. +""" + clearErrorOnAggregateAlert( +""" +Data for clearing the error on an aggregate alert. +""" + input: ClearErrorOnAggregateAlertInput! + ): AggregateAlert! +""" +Clear the error status on an alert. The status will be updated if the error reoccurs. +""" + clearErrorOnAlert( +""" +Data for clearing the error on an alert +""" + input: ClearErrorOnAlertInput! + ): Alert! +""" +Clear the error status on a filter alert. The status will be updated if the error reoccurs. +""" + clearErrorOnFilterAlert( +""" +Data for clearing the error on a filter alert +""" + input: ClearErrorOnFilterAlertInput! + ): FilterAlert! +""" +Clear the error status on a scheduled search. The status will be updated if the error reoccurs. +""" + clearErrorOnScheduledSearch( +""" +Data for clearing the error on a scheduled search +""" + input: ClearErrorOnScheduledSearchInput! + ): ScheduledSearch! +""" +Clears UI configurations for all fields for the current user +""" + clearFieldConfigurations( + input: ClearFieldConfigurationsInput! + ): Boolean! +""" +Clear recent queries for current user on a given view or repository. +""" + clearRecentQueries( + input: ClearRecentQueriesInput! + ): Boolean! +""" +Create a clone of an existing parser. +""" + cloneParser( + input: CloneParserInput! + ): Parser! +""" +Unregisters a node from the cluster. +""" + clusterUnregisterNode( +""" +Force removal of the node. I hope you know what you are doing! +""" + force: Boolean! +""" +ID of the node to unregister. +""" + nodeID: Int! + ): UnregisterNodeMutation! +""" +Create a clone of a dashboard. +""" + copyDashboard( + id: String! +""" +The name of the repository or view where the dashboard to be copied to. +""" + targetSearchDomainName: String +""" +The name of the repository or view where the dashboard to be copied from. +""" + sourceSearchDomainName: String! +""" +The name the copied dashboard should have. +""" + name: String! + ): CopyDashboardMutation! +""" +Create an action from a package action template. +""" + createActionFromPackageTemplate( +""" +The name of the view the package is installed in. +""" + viewName: String! +""" +The id of the package to fetch the action template from. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the action template in the package. +""" + actionTemplateName: String! +""" +The name of the new action to create. +""" + overrideName: String + ): CreateActionFromPackageTemplateMutation! +""" +Create an action from yaml template +""" + createActionFromTemplate( +""" +Data for creating an action from a yaml template +""" + input: CreateActionFromTemplateInput! + ): Action! +""" +Create an aggregate alert. +""" + createAggregateAlert( +""" +Data for creating an aggregate alert. +""" + input: CreateAggregateAlert! + ): AggregateAlert! +""" +Create an alert. +""" + createAlert( +""" +Data for creating an alert +""" + input: CreateAlert! + ): Alert! +""" +Create an alert from a package alert template. +""" + createAlertFromPackageTemplate( +""" +The name of the view or repo the package is installed in. +""" + searchDomainName: String! +""" +The id of the package to fetch the alert template from. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the alert template in the package. +""" + alertTemplateName: String! +""" +The name of the new alert to create. +""" + alertName: String! + ): CreateAlertFromPackageTemplateMutation! +""" +Create an alert from yaml template +""" + createAlertFromTemplate( +""" +Data for creating an alert from a yaml template +""" + input: CreateAlertFromTemplateInput! + ): Alert! +""" +Create an ingest feed that uses AWS S3 and SQS +""" + createAwsS3SqsIngestFeed( +""" +Data for creating an ingest feed that uses AWS S3 and SQS +""" + input: CreateAwsS3SqsIngestFeed! + ): IngestFeed! +""" +[PREVIEW: in development.] Create a custom link interaction. +""" + createCustomLinkInteraction( + input: CreateCustomLinkInteractionInput! + ): InteractionId! +""" +Create a dashboard. +""" + createDashboard( + input: CreateDashboardInput! + ): CreateDashboardMutation! +""" +Create a dashboard from a package dashboard template. +""" + createDashboardFromPackageTemplate( +""" +The name of the view the package is installed in. +""" + viewName: String! +""" +The id of the package to fetch the dashboard template from. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the dashboard template in the package. +""" + dashboardTemplateName: String! +""" +The name of the new dashboard to create. +""" + overrideName: String + ): CreateDashboardFromPackageTemplateMutation! +""" +Create a dashboard from a yaml specification. +""" + createDashboardFromTemplateV2( +""" +Data for creating a dashboard from a yaml specification. +""" + input: CreateDashboardFromTemplateV2Input! + ): Dashboard! +""" +[PREVIEW: in development.] Create a dashboard link interaction. +""" + createDashboardLinkInteraction( + input: CreateDashboardLinkInteractionInput! + ): InteractionId! +""" +Gets or create a new demo data view. +""" + createDemoDataRepository( + demoDataType: String! + ): Repository! +""" +Create an email action. +""" + createEmailAction( +""" +Data for creating an email action +""" + input: CreateEmailAction! + ): EmailAction! +""" +Create an organization. Root operation. +""" + createEmptyOrganization( + name: String! + description: String + organizationId: String + subdomain: String + cid: String + ): Organization! +""" +Create an event forwarding rule on a repository and return it +""" + createEventForwardingRule( +""" +Data for creating an event forwarding rule +""" + input: CreateEventForwardingRule! + ): EventForwardingRule! +""" +Create an FDR feed +""" + createFdrFeed( +""" +Data for creating an FDR feed +""" + input: CreateFdrFeed! + ): FdrFeed! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Creates a schema. If another schema already exists with the same name, then this overwrites it. +""" + createFieldAliasSchema( + input: CreateFieldAliasSchemaInput! + ): FieldAliasSchema! +""" +Create a filter alert. +""" + createFilterAlert( +""" +Data for creating a filter alert +""" + input: CreateFilterAlert! + ): FilterAlert! +""" +[PREVIEW: Under development] +""" + createFleetInstallToken( + name: String! + configId: String + ): FleetInstallationToken! +""" +Create a LogScale repository action. +""" + createHumioRepoAction( +""" +Data for creating a LogScale repository action +""" + input: CreateHumioRepoAction! + ): HumioRepoAction! +""" +Create a new IP filter. +""" + createIPFilter( + input: IPFilterInput! + ): IPFilter! +""" +Create a new ingest listener. +""" + createIngestListenerV3( + input: CreateIngestListenerV3Input! + ): IngestListener! +""" +Create a Kafka event forwarder and return it +""" + createKafkaEventForwarder( +""" +Data for creating a Kafka event forwarder +""" + input: CreateKafkaEventForwarder! + ): KafkaEventForwarder! +""" +[PREVIEW: Experimental feature, not ready for production.] Create a cluster connection to a local view. +""" + createLocalClusterConnection( +""" +Data for creating a local multi-cluster connection +""" + input: CreateLocalClusterConnectionInput! + ): LocalClusterConnection! +""" +[PREVIEW: Under development] Creates a log collector configuration. +""" + createLogCollectorConfiguration( + name: String! + draft: String + ): LogCollectorConfiguration! +""" +[PREVIEW: Under development] +""" + createLogCollectorGroup( + name: String! + filter: String + configIds: [String!] + ): LogCollectorGroup! +""" +Create a lookup file from a package lookup file template. +""" + createLookupFileFromPackageTemplate( +""" +The name of the view the package is installed in. +""" + viewName: RepoOrViewName! +""" +The id of the package to fetch the lookup file template from. +""" + packageId: VersionedPackageSpecifier! +""" +The filename of the lookup file template in the package. +""" + lookupFileTemplateName: String! +""" +The name of the new lookup file to create. +""" + overrideName: String + ): FileNameAndPath! +""" +Create an OpsGenie action. +""" + createOpsGenieAction( +""" +Data for creating an OpsGenie action +""" + input: CreateOpsGenieAction! + ): OpsGenieAction! +""" +[PREVIEW: Feature still in development] +""" + createOrUpdateCrossOrganizationView( + name: String! + limitIds: [String!]! + filter: String + repoFilters: [RepoFilterInput!] + ): View! +""" +[PREVIEW: Experimental prototype not ready for production use] Creates or updates an external function specification. +""" + createOrUpdateExternalFunction( + input: CreateOrUpdateExternalFunctionInput! + ): ExternalFunctionSpecificationOutput! +""" +Create a organization permissions token for organizational-level access. +""" + createOrganizationPermissionsToken( + input: CreateOrganizationPermissionTokenInput! + ): String! +""" +Create a metric view, usage view and log view for each organization. (Root operation) +""" + createOrganizationsViews( + includeDebugView: Boolean + specificOrganization: String + ): Boolean! +""" +Create a PagerDuty action. +""" + createPagerDutyAction( +""" +Data for creating a PagerDuty action. +""" + input: CreatePagerDutyAction! + ): PagerDutyAction! +""" +Create a parser. +""" + createParser( + input: CreateParserInput! + ): CreateParserMutation! +""" +Create a parser from a package parser template. +""" + createParserFromPackageTemplate( +""" +The name of the view the package is installed in. +""" + viewName: String! +""" +The id of the package to fetch the parser template from. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the parser template in the package. +""" + parserTemplateName: String! +""" +The name of the new parser to create. +""" + overrideName: String + ): CreateParserFromPackageTemplateMutation! +""" +Create a parser from a yaml specification +""" + createParserFromTemplate( +""" +Data for creating a parser from a yaml template +""" + input: CreateParserFromTemplateInput! + ): Parser! +""" +Create a parser. +""" + createParserV2( + input: CreateParserInputV2! + ): Parser! +""" +Create a personal user token for the user. It will inherit the same permissions as the user. +""" + createPersonalUserToken( + input: CreatePersonalUserTokenInput! + ): String! +""" +Create a new sharable link to a dashboard. +""" + createReadonlyToken( + id: String! + name: String! + ipFilterId: String +""" +Ownership of the queries run by this shared dashboard. If value is User, ownership wil be based the calling user +""" + queryOwnershipType: QueryOwnershipType + ): DashboardLink! +""" +[PREVIEW: Experimental feature, not ready for production.] Create a cluster connection to a remote view. +""" + createRemoteClusterConnection( +""" +Data for creating a remote cluster connection +""" + input: CreateRemoteClusterConnectionInput! + ): RemoteClusterConnection! +""" +Create a new repository. +""" + createRepository( + name: String! + description: String + retentionInMillis: Long + retentionInIngestSizeBytes: Long + retentionInStorageSizeBytes: Long + organizationId: String + type: RepositoryType + repositoryId: String + dataType: RepositoryDataType +""" +The limit the repository should be attached to, only a cloud feature. If not specified a default will be found and used +""" + limitId: String + ): CreateRepositoryMutation! +""" +Adds a role. Only usable if roles are not managed externally, e.g. in LDAP. +""" + createRole( + input: AddRoleInput! + ): AddRoleMutation! +""" +Create a saved query. +""" + createSavedQuery( + input: CreateSavedQueryInput! + ): CreateSavedQueryPayload! +""" +Create a saved query from a package saved query template. +""" + createSavedQueryFromPackageTemplate( +""" +The name of the view the package is installed in. +""" + viewName: String! +""" +The id of the package to fetch the saved query template from. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the saved query template in the package. +""" + savedQueryTemplateName: String! +""" +The name of the new saved query to create. +""" + overrideName: String + ): CreateSavedQueryFromPackageTemplateMutation! +""" +Create a scheduled report. +""" + createScheduledReport( +""" +Data for creating a scheduled report. +""" + input: CreateScheduledReportInput! + ): ScheduledReport! +""" +Create a scheduled search. +""" + createScheduledSearch( +""" +Data for creating a scheduled search +""" + input: CreateScheduledSearch! + ): ScheduledSearch! +""" +Create a scheduled search from a package scheduled search template. +""" + createScheduledSearchFromPackageTemplate( +""" +The name of the view or repo the package is installed in. +""" + searchDomainName: RepoOrViewName! +""" +The id of the package to fetch the scheduled search template from. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the scheduled search template in the package. +""" + scheduledSearchTemplateName: String! +""" +The name of the new scheduled search to create. +""" + scheduledSearchName: String! + ): ScheduledSearch! +""" +Create a scheduled search from a yaml specification. +""" + createScheduledSearchFromTemplate( +""" +Data for creating a scheduled search from a yaml template. +""" + input: CreateScheduledSearchFromTemplateInput! + ): ScheduledSearch! +""" +[PREVIEW: in development.] Create a search link interaction. +""" + createSearchLinkInteraction( + input: CreateSearchLinkInteractionInput! + ): InteractionId! +""" +Create a Slack action. +""" + createSlackAction( +""" +Data for creating a Slack action. +""" + input: CreateSlackAction! + ): SlackAction! +""" +Create a post message Slack action. +""" + createSlackPostMessageAction( +""" +Data for creating a post message Slack action. +""" + input: CreatePostMessageSlackAction! + ): SlackPostMessageAction! +""" +Create a system permissions token for system-level access. +""" + createSystemPermissionsToken( + input: CreateSystemPermissionTokenInput! + ): String! +""" +Create an upload file action. +""" + createUploadFileAction( +""" +Data for creating an upload file action. +""" + input: CreateUploadFileAction! + ): UploadFileAction! +""" +Create a VictorOps action. +""" + createVictorOpsAction( +""" +Data for creating a VictorOps action. +""" + input: CreateVictorOpsAction! + ): VictorOpsAction! +""" +Create a new view. +""" + createView( + name: String! + description: String + connections: [ViewConnectionInput!] + federatedViews: [String!] + isFederated: Boolean + ): View! +""" +Create a view permission token. The permissions will take effect across all the views. +""" + createViewPermissionsToken( + input: CreateViewPermissionsTokenInput! + ): String! +""" +Create a webhook action. +""" + createWebhookAction( +""" +Data for creating a webhook action. +""" + input: CreateWebhookAction! + ): WebhookAction! +""" +Delete an action. +""" + deleteAction( +""" +Data for deleting an action. +""" + input: DeleteAction! + ): Boolean! +""" +Delete an aggregate alert. +""" + deleteAggregateAlert( +""" +Data for deleting an aggregate alert. +""" + input: DeleteAggregateAlert! + ): Boolean! +""" +Delete an alert. +""" + deleteAlert( +""" +Data for deleting an alert +""" + input: DeleteAlert! + ): Boolean! +""" +[PREVIEW: Experimental feature, not ready for production.] Delete a cluster connection from a view. +""" + deleteClusterConnection( +""" +Data for deleting a cluster connection +""" + input: DeleteClusterConnectionInput! + ): Boolean! +""" +Delete a dashboard. +""" + deleteDashboard( + input: DeleteDashboardInput! + ): DeleteDashboardMutation! +""" +Delete a dashboard by looking up the view with the given viewId and then the dashboard in the view with the given dashboardId. +""" + deleteDashboardV2( + input: DeleteDashboardInputV2! + ): SearchDomain! +""" +Delete an event forwarder +""" + deleteEventForwarder( +""" +Data for deleting an event forwarder +""" + input: DeleteEventForwarderInput! + ): Boolean! +""" +Delete an event forwarding rule on a repository +""" + deleteEventForwardingRule( +""" +Data for deleting an event forwarding rule +""" + input: DeleteEventForwardingRule! + ): Boolean! +""" +[PREVIEW: Experimental prototype not ready for production use] Deletes a given external function specification. +""" + deleteExternalFunction( + input: deleteExternalFunctionInput! + ): Boolean! +""" +Delete an FDR feed +""" + deleteFdrFeed( +""" +Data for deleting an FDR feed +""" + input: DeleteFdrFeed! + ): Boolean! +""" +Delete a feature flag. +""" + deleteFeatureFlag( + feature: String! + ): Boolean! +""" +[PREVIEW: This functionality is still under development and can change without warning.] deletes an alias mapping +""" + deleteFieldAliasSchema( + input: DeleteFieldAliasSchema! + ): Boolean! +""" +Delete a filter alert. +""" + deleteFilterAlert( +""" +Data for deleting a filter alert +""" + input: DeleteFilterAlert! + ): Boolean! +""" +[PREVIEW: Under development] +""" + deleteFleetInstallToken( + token: String! + ): Boolean! +""" +Delete IP filter. +""" + deleteIPFilter( + input: IPFilterIdInput! + ): Boolean! +""" +For deleting an identity provider. Root operation. +""" + deleteIdentityProvider( + id: String! + ): Boolean! +""" +Delete an ingest feed +""" + deleteIngestFeed( +""" +Data for deleting an ingest feed +""" + input: DeleteIngestFeed! + ): Boolean! +""" +Delete an ingest listener. +""" + deleteIngestListener( + id: String! + ): BooleanResultType! +""" +[PREVIEW: in development.] Delete an interaction. +""" + deleteInteraction( + input: DeleteInteractionInput! + ): Boolean! +""" +[PREVIEW: Under development] +""" + deleteLogCollectorConfiguration( + configId: String! + versionId: Int! + ): Boolean! +""" +[PREVIEW: Under development] +""" + deleteLogCollectorGroup( + id: String! + ): Boolean! +""" +[PREVIEW: Under development] +""" + deleteLostCollectors( + dryRun: Boolean! + days: Int! + ): Int! +""" +Delete notification from the system. Requires root. +""" + deleteNotification( + notificationId: String! + ): Boolean! +""" +Delete a parser. +""" + deleteParser( + input: DeleteParserInput! + ): BooleanResultType! +""" +Remove a shared link to a dashboard. +""" + deleteReadonlyToken( + id: String! + token: String! + ): BooleanResultType! +""" +Deletes a saved query. +""" + deleteSavedQuery( + input: DeleteSavedQueryInput! + ): BooleanResultType! +""" +Delete a scheduled report. +""" + deleteScheduledReport( + input: DeleteScheduledReportInput! + ): Boolean! +""" +Delete a scheduled search. +""" + deleteScheduledSearch( +""" +Data for deleting a scheduled search +""" + input: DeleteScheduledSearch! + ): Boolean! +""" +Delete a repository or view. +""" + deleteSearchDomain( + name: String! + deleteMessage: String + ): BooleanResultType! +""" +Delete a repository or view. +""" + deleteSearchDomainById( + input: DeleteSearchDomainByIdInput! + ): Boolean! +""" +Delete a token +""" + deleteToken( + input: InputData! + ): Boolean! +""" +Disable an aggregate alert. +""" + disableAggregateAlert( +""" +Data for disabling an aggregate alert. +""" + input: DisableAggregateAlert! + ): Boolean! +""" +Disable an alert. +""" + disableAlert( +""" +Data for disabling an alert +""" + input: DisableAlert! + ): Boolean! +""" +Removes demo view. +""" + disableDemoDataForUser: Boolean! +""" +Disables an event forwarder +""" + disableEventForwarder( +""" +Data for disabling an event forwarder +""" + input: DisableEventForwarderInput! + ): Boolean! +""" +Disable a feature. +""" + disableFeature( + feature: FeatureFlag! + ): Boolean! +""" +Disable a feature for a specific organization. +""" + disableFeatureForOrg( + orgId: String! + feature: FeatureFlag! + ): Boolean! +""" +Disable a feature for a specific user. +""" + disableFeatureForUser( + feature: FeatureFlag! + userId: String! + ): Boolean! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Disables the schema on this organization +""" + disableFieldAliasSchemaOnOrg( + input: DisableFieldAliasSchemaOnOrgInput! + ): Boolean! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Disables the schema on the given view or repository. +""" + disableFieldAliasSchemaOnView( + input: DisableFieldAliasSchemaOnViewInput! + ): Boolean! +""" +Disable a filter alert. +""" + disableFilterAlert( +""" +Data for disabling a filter alert +""" + input: DisableFilterAlert! + ): Boolean! +""" +[PREVIEW: Under development] +""" + disableLogCollectorDebugLogging: Boolean! +""" +[PREVIEW: Under development] +""" + disableLogCollectorInstanceDebugLogging( + id: String! + ): Boolean! +""" +Disable access to IOCs (indicators of compromise) for an organization. (Requires Organization Manager Permission) +""" + disableOrganizationIocAccess( +""" +Data for disabling access to IOCs (indicators of compromise) for an organization +""" + input: DisableOrganizationIocAccess! + ): Organization! +""" +Disable a scheduled report. +""" + disableScheduledReport( + input: DisableScheduledReportInput! + ): Boolean! +""" +Disable execution of a scheduled search. +""" + disableScheduledSearch( +""" +Data for disabling a scheduled search +""" + input: DisableStarScheduledSearch! + ): ScheduledSearch! +""" +[PREVIEW: Internal debugging tool, do not use without explicit instruction from support] Disable query tracing on worker nodes for queries with the given quota key +""" + disableWorkerQueryTracing( +""" +The quota key to disable tracing for +""" + quotaKey: String! + ): Boolean! +""" +Dismiss notification for specific user, if allowed by notification type. +""" + dismissNotification( + notificationId: String! + ): Boolean! +""" +Enable an aggregate alert. +""" + enableAggregateAlert( +""" +Data for enabling an aggregate alert. +""" + input: EnableAggregateAlert! + ): Boolean! +""" +Enable an alert. +""" + enableAlert( +""" +Data for enabling an alert +""" + input: EnableAlert! + ): Boolean! +""" +Gets or create a new demo data view. +""" + enableDemoDataForUser( + demoDataType: String! + ): View! +""" +Enables an event forwarder +""" + enableEventForwarder( +""" +Data for enabling an event forwarder +""" + input: EnableEventForwarderInput! + ): Boolean! +""" +Enable a feature. +""" + enableFeature( + feature: FeatureFlag! + ): Boolean! +""" +Enable a feature for a specific organization. +""" + enableFeatureForOrg( + orgId: String! + feature: FeatureFlag! + ): Boolean! +""" +Enable a feature for a specific user. +""" + enableFeatureForUser( + feature: FeatureFlag! + userId: String! + ): Boolean! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Enables the schema on this organization. Field alias mappings in this schema will be active during search across all views and repositories within this org. +""" + enableFieldAliasSchemaOnOrg( + input: EnableFieldAliasSchemaOnOrgInput! + ): Boolean! +""" +[PREVIEW: This functionality is still under development and can change without warning.] +Enables the schema on the given list of views or repositories. +Field alias mappings in this schema will be active during search within this view or repository. +If at least one view fails to be enabled on the given view, then no changes are performed on any of the views. + +""" + enableFieldAliasSchemaOnViews( + input: EnableFieldAliasSchemaOnViewsInput! + ): Boolean! +""" +Enable a filter alert. +""" + enableFilterAlert( +""" +Data for enabling a filter alert +""" + input: EnableFilterAlert! + ): Boolean! +""" +[PREVIEW: Under development] +""" + enableLogCollectorDebugLogging( + url: String + token: String! + level: String! + repository: String + ): Boolean! +""" +[PREVIEW: Under development] +""" + enableLogCollectorInstanceDebugLogging( + id: String! + url: String + token: String! + level: String! + repositoryName: String + ): Boolean! +""" +Enable access to IOCs (indicators of compromise) for an organization. (Requires Organization Manager Permission). +""" + enableOrganizationIocAccess( +""" +Data for enabling access to IOCs (indicators of compromise) for an organization +""" + input: EnableOrganizationIocAccess! + ): Organization! +""" +Enable a scheduled report. +""" + enableScheduledReport( + input: EnableScheduledReportInput! + ): Boolean! +""" +Enable execution of a scheduled search. +""" + enableScheduledSearch( +""" +Data for enabling a scheduled search +""" + input: EnableStarScheduledSearch! + ): ScheduledSearch! +""" +[PREVIEW: Internal debugging tool, do not use without explicit instruction from support] Enable query tracing on worker nodes for queries with the given quota key +""" + enableWorkerQueryTracing( + input: EnableWorkerQueryTracingInputType! + ): Boolean! +""" +Extend a Cloud Trial. (Requires Root Permissions) +""" + extendCloudTrial( + organizationId: String! + days: Int! + ): Boolean! +""" +Set the primary bucket target for the organization. +""" + findOrCreateBucketStorageEntity( + organizationId: String! + ): Int! +""" +Installs a package in a specific view. +""" + installPackageFromRegistryV2( + InstallPackageFromRegistryInput: InstallPackageFromRegistryInput! + ): InstallPackageFromRegistryResult! +""" +Installs a package from file provided in multipart/form-data (name=file) in a specific view. +""" + installPackageFromZip( +""" +The name of the view the package is installed in. +""" + viewName: String! +""" +Overwrite existing installed package +""" + overwrite: Boolean +""" +[PREVIEW: The query ownership feature is still in development] Ownership of the queries run by the triggers (e.g. alerts and scheduled searches) that are installed as part of this package. If value is User, ownership will be based on the calling user. +""" + queryOwnershipType: QueryOwnershipType + ): InstallPackageFromZipResult! + killQuery( + viewName: String! + pattern: String! + ): BooleanResultType! +""" +[PREVIEW: Internal testing.] Enable a or disable language restrictions for specified version. +""" + languageRestrictionsEnable( + input: EnabledInput! + ): Boolean! +""" +[PREVIEW: Feature still in development] +""" + linkChildOrganization( + childId: String! + ): OrganizationLink! +""" +Log UI Action. +""" + logAnalytics( + input: AnalyticsLog! + ): Boolean! +""" +[PREVIEW: New analytics implementation] Log UI Action. +""" + logAnalyticsBatch( + input: [AnalyticsLogWithTimestamp!]! + ): Boolean! +""" +[PREVIEW: This feature is under development] Logs a service level indicator to the humio repo with #kind=frontend. +""" + logFrontendServiceLevelIndicators( + input: [ServiceLevelIndicatorLogArg!]! + ): Boolean! +""" +Logs out of a users session. +""" + logoutOfSession: Boolean! +""" +Set a limits deleted mark +""" + markLimitDeleted( + input: MarkLimitDeletedInput! + ): Boolean! +""" +Migrate all organizations to the new Limits model (requires root). +""" + migrateToNewLimits( + input: MigrateLimitsInput! + ): Boolean! +""" +For setting up a new Azure AD OIDC idp. Root operation. +""" + newAzureAdOidcIdentityProvider( + name: String! + tenantId: String! + clientID: String! + clientSecret: String! + domains: [String!]! + enableDebug: Boolean + scopeClaim: String + ): OidcIdentityProvider! +""" +Create new file +""" + newFile( + fileName: String! + name: String! + ): UploadedFileSnapshot! +""" +For setting up a new OIDC idp. Root operation. +""" + newOIDCIdentityProvider( + input: OidcConfigurationInput! + ): OidcIdentityProvider! + newSamlIdentityProvider( +""" +Optional specify the ID externally (root only) +""" + id: String + name: String! + signOnUrl: String! + idpCertificateInBase64: String! + idpEntityId: String! + domains: [String!]! + groupMembershipAttribute: String + userAttribute: String + enableDebug: Boolean +""" +Only used internal +""" + adminAttribute: String +""" +Only used internal +""" + adminAttributeMatch: String +""" +If multiple Idp's are defined the default idp is used whenever redirecting to login +""" + defaultIdp: Boolean +""" +Only used internal +""" + humioOwned: Boolean +""" +Lazy create users during login +""" + lazyCreateUsers: Boolean + ): SamlIdentityProvider! +""" +Create notification. Required permissions depends on targets. + Examples: + mutation{notify(Target:Group, ids: ["GroupId1", "GroupId2"],...)} #Notify users in group1 and group2 + mutation{notify(Target:OrgRoot, ids: ["OrgId1", "OrgId2"],...)} # Notify org roots in org1 and org2 + mutation{notify(Target:Root,...)} #Notify all root users + mutation{notify(Target:All,...)} # Notify all users + mutation{notify(Target:All,["UserId1", "UserId2", "UserId3"],...)} #Notify user 1, 2 & 3 + +""" + notify( + input: NotificationInput! + ): Notification! +""" +Override whether feature should be rolled out. +""" + overrideRolledOutFeatureFlag( + feature: FeatureFlag! + rollOut: Boolean! + ): Boolean! +""" +Proxy mutation through a specific organization. Root operation. +""" + proxyOrganization( + organizationId: String! + ): Organization! +""" +[PREVIEW: Under development] Updates a log collector configuration. +""" + publishLogCollectorConfiguration( + id: String! + yaml: String + currentVersion: Int! + ): LogCollectorConfiguration! +""" +Recover the organization with the given id. +""" + recoverOrganization( + organizationId: String! + ): Organization! +""" +Redact events matching a certain query within a certain time interval. Returns the id of the submitted redaction task +""" + redactEvents( + input: RedactEventsInputType! + ): String! +""" +Refresh the list of regions +""" + refreshRegions: Boolean! +""" +Remove a label from an alert. +""" + removeAlertLabelV2( +""" +Data for removing a label from an alert +""" + input: RemoveAlertLabel! + ): Alert! +""" +Remove a filter from a dashboard's list of filters. +""" + removeDashboardFilter( + id: String! + filterId: String! + ): Dashboard! +""" +Remove a label from a dashboard. +""" + removeDashboardLabel( + id: String! + label: String! + ): Dashboard! +""" +Gets or create a new demo data view. +""" + removeDemoDataRepository( + demoDataType: String! + ): Boolean! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Removes a field alias mapping to an existing schema. +""" + removeFieldAliasMapping( + input: RemoveAliasMappingInput! + ): Boolean! +""" +Remove file +""" + removeFile( + fileName: String! + name: String! + ): BooleanResultType! +""" +Remove an item on the query blocklist. +""" + removeFromBlocklist( +""" +Data for removing a blocklist entry +""" + input: RemoveFromBlocklistInput! + ): Boolean! +""" +[PREVIEW: Under development] +""" + removeFromLogCollectorConfigurationTest( + configId: String! + collectorIds: [String!]! + ): FleetConfigurationTest! +""" +[PREVIEW: Internal testing.] Disable functions for use with specified language version. +""" + removeFunctionsFromAllowList( + input: FunctionListInput! + ): Boolean! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] Removes the global default cache policy +""" + removeGlobalDefaultCachePolicy: Boolean! +""" +Removes a group. Only usable if roles are not managed externally, e.g. in LDAP. +""" + removeGroup( + groupId: String! + ): RemoveGroupMutation! +""" +Remove an Ingest Token. +""" + removeIngestToken( +""" +The name of the repository to remove the ingest token from. +""" + repositoryName: String! +""" +The name of the token to delete. +""" + name: String! + ): BooleanResultType! +""" +Remove a limit in the given organization +""" + removeLimit( + input: RemoveLimitInput! + ): Boolean! + removeLoginBridge: Boolean! + removeLoginBridgeAllowedUsers( + userID: String! + ): LoginBridge! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] Removes the default cache policy of the current organization. +""" + removeOrgDefaultCachePolicy: Boolean! +""" +Remove the organization with the given id (needs to be the same organization ID as the requesting user is in). +""" + removeOrganization( + organizationId: String! + ): Boolean! +""" +Remove the bucket config for the organization. +""" + removeOrganizationBucketConfig: Organization! +""" +Remove a parser. +""" + removeParser( + input: RemoveParserInput! + ): RemoveParserMutation! + removeQueryQuotaDefaultSettings: Boolean! + removeQueryQuotaUserSettings( + username: String! + ): Boolean! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] Removes the cache policy of a repository +""" + removeRepoCachePolicy( +""" +Data to remove a repository cache policy +""" + input: RemoveRepoCachePolicyInput! + ): Boolean! +""" +Removes a role. Only usable if roles are not managed externally, e.g. in LDAP. +""" + removeRole( + roleId: String! + ): BooleanResultType! +""" +Remove a label from a scheduled search. +""" + removeScheduledSearchLabel( +""" +Data for removing a label +""" + input: RemoveLabelScheduledSearch! + ): ScheduledSearch! +""" +[PREVIEW: Requires the feature enabled for the organization.] Removes a secondary subdomain from the organization +""" + removeSecondarySubdomain( + input: RemoveSecondarySubdomainInput! + ): Organization! +""" +Temporary mutation to remove all size based retention for all organizations. +""" + removeSizeBasedRetentionForAllOrganizations: [String!]! +""" +Remove a star from an alert. +""" + removeStarFromAlertV2( +""" +Data for removing a star from an alert +""" + input: RemoveStarFromAlert! + ): Alert! +""" +Remove a star from a dashboard. +""" + removeStarFromDashboard( + id: String! + ): Dashboard! + removeStarFromField( + input: RemoveStarToFieldInput! + ): RemoveStarToFieldMutation! +""" +Remove a star from a scheduled search. +""" + removeStarFromScheduledSearch( +""" +Data for removing a star +""" + input: RemoveStarScheduledSearch! + ): ScheduledSearch! +""" +Remove a star from a repository or view. +""" + removeStarFromSearchDomain( + name: String! + ): SearchDomain! +""" +[PREVIEW: Requires the feature enabled for the organization.] Remove the subdomain settings for the organization. +""" + removeSubdomainSettings: Organization! +""" +Remove a user. +""" + removeUser( + input: RemoveUserInput! + ): RemoveUserMutation! +""" +Remove a user. +""" + removeUserById( + input: RemoveUserByIdInput! + ): RemoveUserByIdMutation! +""" +Removes users from an existing group. +""" + removeUsersFromGroup( + input: RemoveUsersFromGroupInput! + ): RemoveUsersFromGroupMutation! +""" +Rename a dashboard. +""" + renameDashboard( + id: String! + name: String! + ): Dashboard! +""" +Rename a Repository or View. +""" + renameSearchDomain( +""" +Old name for Repository or View +""" + name: String! +""" +New name for Repository or View. Note that this changes the URLs for accessing the Repository or View. +""" + renameTo: String! + ): SearchDomain! +""" +Rename a Repository or View. +""" + renameSearchDomainById( + input: RenameSearchDomainByIdInput! + ): SearchDomain! + renameWidget( + id: String! + widgetId: String! + title: String! + ): Dashboard! +""" +Resend an invite to a pending user. +""" + resendInvitation( + input: TokenInput! + ): Boolean! +""" +[PREVIEW: Feature still in development] Resets the flight recorder settings to default for the given vhost +""" + resetFlightRecorderSettings( +""" +The vhost to change the settings for. +""" + vhost: Int! + ): Boolean! +""" +Sets the quota and rate to the given value or resets it to defaults +""" + resetQuota( +""" +Data for resetting quota +""" + input: ResetQuotaInput! + ): Boolean! + resetToFactorySettings: Account! +""" +[PREVIEW: BETA feature.] Restore a deleted search domain. +""" + restoreDeletedSearchDomain( + input: RestoreDeletedSearchDomainInput! + ): SearchDomain! +""" +Resubmit marketo lead. Requires root level privileges and an organization owner in the organization (the lead). +""" + resubmitMarketoLead( + input: ResubmitMarketoLeadData! + ): Boolean! +""" +Revoke a pending user. Once revoked, the invitation link sent to the user becomes invalid. +""" + revokePendingUser( + input: TokenInput! + ): Boolean! +""" +Revoke the specified session. Can be a single session, all sessions for a user or all sessions in an organization. +""" + revokeSession( + input: RevokeSessionInput! + ): Boolean! +""" +Rollback the organization with the given id. +""" + rollbackOrganization( + organizationId: String! + ): Boolean! +""" +Rotate a token +""" + rotateToken( + input: RotateTokenInputData! + ): String! +""" +[PREVIEW: This feature is under development] Manually start the organization inconsistency job. This job will check for inconsistencies like orphaned entities, references to non-existent entities. The job can be run in a dry-run mode that only logs what would have happened. +""" + runInconsistencyCheck( + input: RunInconsistencyCheckInput! + ): String! +""" +Configures S3 archiving for a repository. E.g. bucket and region. +""" + s3ConfigureArchiving( + repositoryName: String! + bucket: String! + region: String! + format: S3ArchivingFormat! + tagOrderInName: [String!] + startFromDateTime: DateTime + ): BooleanResultType! +""" +Disables the archiving job for the repository. +""" + s3DisableArchiving( + repositoryName: String! + ): BooleanResultType! +""" +Enables the archiving job for the repository. +""" + s3EnableArchiving( + repositoryName: String! + ): BooleanResultType! +""" +Mark all segment files as unarchived. +""" + s3ResetArchiving( + repositoryName: String! + ): BooleanResultType! +""" +Scheduled report result failed. +""" + scheduledReportResultFailed( + input: ScheduledReportResultFailedInput! + ): Boolean! +""" +Scheduled report result succeeded. +""" + scheduledReportResultSucceeded( + input: ScheduledReportResultSucceededInput! + ): Boolean! +""" +[PREVIEW: Feature still in development] Set to true to allow moving existing segments between nodes to achieve a better data distribution +""" + setAllowRebalanceExistingSegments( +""" +true if the cluster should allow moving existing segments between nodes to achieve a better data distribution +""" + allowRebalanceExistingSegments: Boolean! + ): Boolean! +""" +[PREVIEW: Feature still in development] Set whether or not to allow updating the desired digesters automatically +""" + setAllowUpdateDesiredDigesters( +""" +Whether or not to allow updating the desired digesters automatically +""" + allowUpdateDesiredDigesters: Boolean! + ): Boolean! +""" +Automatically search when arriving at the search page +""" + setAutomaticSearching( + name: String! + automaticSearch: Boolean! + ): setAutomaticSearching! +""" +Set CID of provisioned organization +""" + setCid( + cid: String! + ): Organization! +""" +Set a duration from now, until which this host will be considered alive by LogScale, even when it's offline. +""" + setConsideredAliveFor( +""" +ID of the node to consider alive. +""" + nodeID: Int! +""" +Amount of millis that the node will be considered alive for (from now). +""" + aliveForMillis: Long + ): DateTime +""" +Set a time in the future, until which this host will be considered alive by LogScale, even when it's offline. +""" + setConsideredAliveUntil( +""" +ID of the node to consider alive. +""" + nodeID: Int! +""" +Time in the future +""" + aliveUntil: DateTime + ): DateTime +""" +Mark a filter as the default for a dashboard. This filter will automatically be active when the dashboard is opened. +""" + setDefaultDashboardFilter( + id: String! + filterId: String + ): Dashboard! +""" +Set the query that should be loaded on entering the search page in a specific view. +""" + setDefaultSavedQuery( + input: SetDefaultSavedQueryInput! + ): BooleanResultType! +""" +[PREVIEW: Feature still in development] Sets the digest replication factor to the supplied value +""" + setDigestReplicationFactor( +""" +The replication factor for segments newly written to digest nodes. Applies until the segments are moved to storage nodes. +""" + digestReplicationFactor: Int! + ): Int! +""" +Set a dynamic config. Requires root level access. +""" + setDynamicConfig( + input: DynamicConfigInputObject! + ): Boolean! +""" +[PREVIEW: Requires the feature enabled for the organization.] Configures whether subdomains are enforced for the organization +""" + setEnforceSubdomains( + input: EnforceSubdomainsInput! + ): Organization! +""" +Save UI styling and other properties for a field. These will be used whenever that field is added to a table or event list in LogScale's UI. +""" + setFieldConfiguration( + input: FieldConfigurationInput! + ): Boolean! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] Sets the global default cache policy. This policy will be applied to a repo if neither a repo or org cache policy is set. +""" + setGlobalDefaultCachePolicy( +""" +Data to set a global default cache policy +""" + input: SetGlobalDefaultCachePolicyInput! + ): Boolean! +""" +[PREVIEW: Feature still in development] Toggle whether the specified host should be prepared for eviction from the cluster. If preparing for eviction, the cluster will attempt to move data and work away from the host. +""" + setIsBeingEvicted( +""" +ID of the node to set the isBeingEvicted flag for. +""" + vhost: Int! +""" +Eviction flag indicating whether a node should be prepared for eviction from the cluster. +""" + isBeingEvicted: Boolean! + ): Boolean! +""" +Remove a limit in the given organization +""" + setLimitDisplayName( + input: SetLimitDisplayNameInput! + ): Boolean! + setLoginBridge( + input: LoginBridgeInput! + ): LoginBridge! + setLoginBridgeTermsState( + accepted: Boolean! + ): LoginBridge! +""" +[PREVIEW: Under development] +""" + setLostCollectorDays( + days: Int + ): Boolean! +""" +[PREVIEW: Feature still in development] Sets the percentage of all hosts relevant to a particular cluster rebalance operation that need to be alive before we allow the system to automatically execute the operation to the supplied value. Cluster rebalance operations currently include reassigning digest work, and moving existing segments to balance disk usage. +""" + setMinHostAlivePercentageToEnableClusterRebalancing( +""" +Percentage of all hosts relevant to a particular cluster rebalance operation that need to be alive before we allow the system to automatically execute the operation. Cluster rebalance operations currently include reassigning digest work, and moving existing segments to balance disk usage. Must be between 0 and 100, both inclusive +""" + minHostAlivePercentageToEnableClusterRebalancing: Int! + ): Int! +""" +[PREVIEW: Feature still in development] Sets the duration old object sampling will run for before dumping results and restarting +""" + setOldObjectSampleDurationMinutes( +""" +The vhost to change the setting for. +""" + vhost: Int! +""" +The duration old object sampling will run for before dumping results and restarting +""" + oldObjectSampleDurationMinutes: Long! + ): Long! +""" +[PREVIEW: Feature still in development] Toggles the OldObjectSample event on or off +""" + setOldObjectSampleEnabled( +""" +The vhost to change the setting for. +""" + vhost: Int! +""" +true to enable the OldObjectSample event +""" + oldObjectSampleEnabled: Boolean! + ): Boolean! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] Sets the default cache policy of the current organization. This policy will be applied to repos within the current organizatio if a repo cache policy is set. +""" + setOrgDefaultCachePolicy( +""" +Data to set a organization default cache policy +""" + input: SetOrgDefaultCachePolicyInput! + ): Boolean! +""" +Set the primary bucket target for the organization. +""" + setOrganizationBucket1( + targetBucketId1: String! + ): Organization! +""" +Set the secondary bucket target for the organization. +""" + setOrganizationBucket2( + targetBucketId2: String! + ): Organization! +""" +[PREVIEW: Requires the feature enabled for the organization.] Set the primary domain for the organization. If a primary domain is already set the existing primary domain is converted to a secondary domain +""" + setPrimarySubdomain( + input: SetPrimarySubdomainInput! + ): Organization! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] Sets the cache policy of a repository. +""" + setRepoCachePolicy( +""" +Data to set a repo cache policy +""" + input: SetRepoCachePolicyInput! + ): Boolean! +""" +[PREVIEW: Feature still in development] Sets the segment replication factor to the supplied value +""" + setSegmentReplicationFactor( +""" +replication factor for segment storage +""" + segmentReplicationFactor: Int! + ): Int! +""" +[PREVIEW: Requires the feature enabled for the organization.] Set the subdomain settings for an organization. This overrides previously configured settings +""" + setSubdomainSettings( + input: SetSubdomainSettingsInput! + ): Organization! +""" +Set current tag groupings for a repository. +""" + setTagGroupings( +""" +The name of the repository on which to apply the new tag groupings. +""" + repositoryName: String! +""" +The tag groupings to set for the repository. +""" + tagGroupings: [TagGroupingRuleInput!]! + ): [TagGroupingRule!]! +""" +[PREVIEW: Under development] +""" + setWantedLogCollectorVersion( + id: String! + version: String + timeOfUpdate: DateTime + ): Boolean! +""" +Star a saved query in user settings. +""" + starQuery( + input: AddStarToQueryInput! + ): BooleanResultType! +""" +[PREVIEW: Under development] +""" + startLogCollectorConfigurationTest( + configId: String! + collectorIds: [String!]! + ): FleetConfigurationTest! +""" +[PREVIEW: Feature still in development] Stops all running queries including streaming queries +""" + stopAllQueries( +""" +Input to stopping queries. +""" + input: StopQueriesInput + ): Boolean! +""" +[PREVIEW: Feature still in development] Stops all historical queries, ignores live and streaming queries +""" + stopHistoricalQueries( +""" +Input to stopping queries. +""" + input: StopQueriesInput + ): Boolean! +""" +[PREVIEW: Under development] +""" + stopLogCollectorConfigurationTest( + configId: String! + ): FleetConfigurationTest! +""" +Stops all streaming queries +""" + stopStreamingQueries( +""" +Input to stopping queries. +""" + input: StopQueriesInput + ): Boolean! +""" +Tests whether the Iam role is setup correctly and that there is a connection to the SQS queue. +""" + testAwsS3SqsIngestFeed( +""" +Data for testing an ingest feed that uses AWS S3 and SQS +""" + input: TestAwsS3SqsIngestFeed! + ): Boolean! +""" +Test an email action +""" + testEmailAction( +""" +Data for testing an email action +""" + input: TestEmailAction! + ): TestResult! +""" +[PREVIEW: Not used by UI yet. Output is subject to change.] Test an FDR feed. +""" + testFdrFeed( +""" +Data for testing an FDR feed. +""" + input: TestFdrFeed! + ): TestFdrResult! +""" +Test a Humio repo action. +""" + testHumioRepoAction( +""" +Data for testing a Humio repo action +""" + input: TestHumioRepoAction! + ): TestResult! +""" +Test that a Kafka event forwarder can connect to the specified Kafka server and topic. +Note that this may create the topic on the broker if the Kafka broker is configured to automatically create +topics. +""" + testKafkaEventForwarderV2( +""" +Data for testing a Kafka event forwarder +""" + input: TestKafkaEventForwarder! + ): TestResult! +""" +Test an OpsGenie action. +""" + testOpsGenieAction( +""" +Data for testing an OpsGenie action +""" + input: TestOpsGenieAction! + ): TestResult! +""" +Test a PagerDuty action. +""" + testPagerDutyAction( +""" +Data for testing a PagerDuty action. +""" + input: TestPagerDutyAction! + ): TestResult! +""" +Test a parser on some test events. If the parser fails to run, an error is returned. Otherwise, a list of results, one for each test event, is returned. +""" + testParser( + input: TestParserInputV2! + ): TestParserResultV2! +""" +Test a parser on some test cases. +""" + testParserV2( + input: ParserTestRunInput! + ): ParserTestRunOutput! +""" +Test a Slack action. +""" + testSlackAction( +""" +Data for testing a Slack action. +""" + input: TestSlackAction! + ): TestResult! +""" +Test a post message Slack action. +""" + testSlackPostMessageAction( +""" +Data for testing a post message Slack action. +""" + input: TestPostMessageSlackAction! + ): TestResult! +""" +Test an upload file action +""" + testUploadFileAction( +""" +Data for testing an upload file action. +""" + input: TestUploadFileAction! + ): TestResult! +""" +Test a VictorOps action. +""" + testVictorOpsAction( +""" +Data for testing a VictorOps action. +""" + input: TestVictorOpsAction! + ): TestResult! +""" +Test a webhook action. +""" + testWebhookAction( +""" +Data for testing a webhook action. +""" + input: TestWebhookAction! + ): TestResult! +""" +Will attempt to trigger a poll on an ingest feed. +""" + triggerPollIngestFeed( +""" +Data for trigger polling an ingest feed +""" + input: TriggerPollIngestFeed! + ): Boolean! +""" +Un-associates a token with its currently assigned parser. +""" + unassignIngestToken( +""" +The name of the repository the ingest token belongs to. +""" + repositoryName: String! +""" +The name of the token. +""" + tokenName: String! + ): UnassignIngestTokenMutation! +""" +[PREVIEW: Experimental feature to allow unassigning permissions to manage a subset of organizations.] Removes the organization management role assigned to the group for the provided organizations. +""" + unassignOrganizationManagementRoleFromGroup( + input: UnassignOrganizationManagementRoleFromGroupInput! + ): UnassignSystemRoleFromGroup! +""" +[PREVIEW: No note] Removes the organization role assigned to the group. +""" + unassignOrganizationRoleFromGroup( + input: RemoveOrganizationRoleFromGroupInput! + ): UnassignOrganizationRoleFromGroup! +""" +Removes the role assigned to the group for a given view. +""" + unassignRoleFromGroup( + input: RemoveRoleFromGroupInput! + ): UnassignRoleFromGroup! +""" +[PREVIEW: No note] Removes the system role assigned to the group. +""" + unassignSystemRoleFromGroup( + input: RemoveSystemRoleFromGroupInput! + ): UnassignSystemRoleFromGroup! +""" +Unassign node tasks. Returns the set of assigned tasks after the unassign operation has completed. +""" + unassignTasks( +""" +ID of the node to assign node tasks to. +""" + nodeID: Int! +""" +List of tasks to unassign. +""" + tasks: [NodeTaskEnum!]! + ): [NodeTaskEnum!]! + unassignUserRoleForSearchDomain( + userId: String! + searchDomainId: String! +""" +If specified, only unassigns the role with the specified id. If not specified, unassigns all user roles for the user in the search domain. +""" + roleId: String + ): User! +""" +Unblock ingest to the specified repository. (Requires ManageCluster Permission) +""" + unblockIngest( + repositoryName: String! + ): UnblockIngestMutation! +""" +[PREVIEW: Under development] +""" + unenrollLogCollectors( + ids: [String!] + ): [EnrolledCollector!]! +""" +Uninstalls a package from a specific view. +""" + uninstallPackage( +""" +The id of the package to uninstall. +""" + packageId: UnversionedPackageSpecifier! +""" +The name of the view the package to uninstall is installed in. +""" + viewName: String! + ): BooleanResultType! +""" +[PREVIEW: Feature still in development] +""" + unlinkChildOrganization( + childId: String! + ): Boolean! +""" +Unset a dynamic config. Requires Manage Cluster permission. +""" + unsetDynamicConfig( + input: UnsetDynamicConfigInputObject! + ): Boolean! +""" +Unset the secondary bucket target for the organization. +""" + unsetOrganizationBucket2: Organization! +""" +Unstar a saved query in user settings. +""" + unstarQuery( + input: RemoveStarFromQueryInput! + ): SavedQueryStarredUpdate! +""" +Update the action security policies for the organization +""" + updateActionSecurityPolicies( + input: ActionSecurityPoliciesInput! + ): Organization! +""" +Update an aggregate alert. +""" + updateAggregateAlert( +""" +Data for updating an aggregate alert. +""" + input: UpdateAggregateAlert! + ): AggregateAlert! +""" +Update an alert. +""" + updateAlert( +""" +Data for updating an alert +""" + input: UpdateAlert! + ): Alert! +""" +Update an ingest feed, which uses AWS S3 and SQS +""" + updateAwsS3SqsIngestFeed( +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + input: UpdateAwsS3SqsIngestFeed! + ): IngestFeed! +""" +[PREVIEW: in development.] Update a custom link interaction. +""" + updateCustomLinkInteraction( + input: UpdateCustomLinkInteractionInput! + ): InteractionId! +""" +Update a dashboard. +""" + updateDashboard( + input: UpdateDashboardInput! + ): UpdateDashboardMutation! +""" +Update a dashboard filter. +""" + updateDashboardFilter( + id: String! + filterId: String! + name: String! + prefixFilter: String! + ): Dashboard! +""" +[PREVIEW: in development.] Update a dashboard link interaction. +""" + updateDashboardLinkInteraction( + input: UpdateDashboardLinkInteractionInput! + ): InteractionId! +""" +Update a dashboard token to run as another user +""" + updateDashboardToken( + viewId: String! +""" +Deprecated in favor of queryOwnershipType. If field is set to anything else than the calling user id, an exception will be thrown. +""" + userId: String + dashboardToken: String! +""" +Ownership of the query run by this shared dashboard. If value is User, ownership will be based on the calling user. +""" + queryOwnershipType: QueryOwnershipType + ): View! +""" +Updates the default queryprefix for a group. +""" + updateDefaultQueryPrefix( + input: UpdateDefaultQueryPrefixInput! + ): UpdateDefaultQueryPrefixMutation! +""" +Updates the default role for a group. +""" + updateDefaultRole( + input: UpdateDefaultRoleInput! + ): updateDefaultRoleMutation! + updateDescriptionForSearchDomain( + name: String! + newDescription: String! + ): UpdateDescriptionMutation! +""" +[PREVIEW: Under development] Updates a log collector configuration. +""" + updateDraftLogCollectorConfiguration( + id: String! + draft: String + ): LogCollectorConfiguration! +""" +Update an email action. +""" + updateEmailAction( +""" +Data for updating an email action. +""" + input: UpdateEmailAction! + ): EmailAction! +""" +Update an event forwarding rule on a repository and return it +""" + updateEventForwardingRule( +""" +Data for updating an event forwarding rule +""" + input: UpdateEventForwardingRule! + ): EventForwardingRule! +""" +Update an FDR feed with the supplied changes. Note that the input fields to this method, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + updateFdrFeed( +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + input: UpdateFdrFeed! + ): FdrFeed! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] FDR feed administrator control update +""" + updateFdrFeedControl( +""" +Data for updating the administrator control of an FDR feed. +""" + input: UpdateFdrFeedControl! + ): FdrFeedControl! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Updates an alias mapping on a schema. +""" + updateFieldAliasMapping( + input: UpdateFieldAliasMappingInput! + ): String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Updates an existing schema. +""" + updateFieldAliasSchema( + input: UpdateFieldAliasSchemaInput! + ): FieldAliasSchema! +""" +Change file +""" + updateFile( + fileName: String! + name: String! +""" +The rows within the offset and limit. They will overwrite all existing rows that are also within the offset and limit. +""" + changedRows: [[String!]!]! +""" +Table headers +""" + headers: [String!]! +""" +List of column changes that will be applied to all rows in the file. Ordering is important, as the first change in the list will be executed first, and the next change will be executed on the resulting rows. +""" + columnChanges: [ColumnChange!]! +""" +Used to find when to stop replacing rows, by adding the limit to the offset. If no offset is given, the file will be truncated to match the updated rows. +""" + limit: Int +""" +Starting index to replace the old rows with the updated ones. It does not take into account the header row. +""" + offset: Int + ): UploadedFileSnapshot! +""" +Update a filter alert. +""" + updateFilterAlert( +""" +Data for updating a filter alert +""" + input: UpdateFilterAlert! + ): FilterAlert! +""" +[PREVIEW: Under development] +""" + updateFleetInstallTokenConfigId( + token: String! + configId: String + ): FleetInstallationToken! +""" +[PREVIEW: Under development] +""" + updateFleetInstallTokenName( + token: String! + name: String! + ): FleetInstallationToken! +""" +Updates the group. +""" + updateGroup( + input: UpdateGroupInput! + ): UpdateGroupMutation! +""" +Update a LogScale repository action. +""" + updateHumioRepoAction( +""" +Data for updating a LogScale repository action. +""" + input: UpdateHumioRepoAction! + ): HumioRepoAction! +""" +Update IP filter. +""" + updateIPFilter( + input: IPFilterUpdateInput! + ): IPFilter! +""" +Update an ingest listener. +""" + updateIngestListenerV3( + input: UpdateIngestListenerV3Input! + ): IngestListener! +""" +Sets the ingest partition scheme of the LogScale cluster. Requires ManageCluster permission. Be aware that the ingest partition scheme is normally automated, and changes will be overwritten by the automation. This mutation should generally not be used unless the automation is temporarily disabled. +""" + updateIngestPartitionScheme( +""" +The list of ingest partitions. If partitions are missing in the input, they are left unchanged. +""" + partitions: [IngestPartitionInput!]! + ): BooleanResultType! +""" +Update a Kafka event forwarder and return it +""" + updateKafkaEventForwarder( +""" +Data for updating a Kafka event forwarder +""" + input: UpdateKafkaEventForwarder! + ): KafkaEventForwarder! +""" +Update the license key for the LogScale cluster. If there is an existing license on this cluster this operation requires permission to manage cluster. +""" + updateLicenseKey( + license: String! + ): License! +""" +Update the limit with the given name, only the arguments defined will be updated +""" + updateLimit( + input: UpdateLimitInput! + ): Boolean! +""" +Update the limit with the given name, only the arguments defined will be updated +""" + updateLimitV2( + input: UpdateLimitInputV2! + ): LimitV2! +""" +[PREVIEW: Experimental feature, not ready for production.] Update a cluster connection to a local view. +""" + updateLocalClusterConnection( +""" +Data for updating a local cluster connection +""" + input: UpdateLocalClusterConnectionInput! + ): LocalClusterConnection! +""" +[PREVIEW: Under development] +""" + updateLogCollectorConfigurationDescription( + configId: String! + description: String + ): LogCollectorConfiguration! +""" +[PREVIEW: Under development] +""" + updateLogCollectorConfigurationName( + configId: String! + name: String! + ): LogCollectorConfiguration! +""" +[PREVIEW: Under development] +""" + updateLogCollectorGroupConfigIds( + id: String! + configIds: [String!] + ): LogCollectorGroup! +""" +[PREVIEW: Under development] +""" + updateLogCollectorGroupFilter( + id: String! + filter: String + ): LogCollectorGroup! +""" +[PREVIEW: Under development] +""" + updateLogCollectorGroupName( + id: String! + name: String! + ): LogCollectorGroup! +""" +[PREVIEW: Under development] +""" + updateLogCollectorGroupWantedVersion( + id: String! + wantedVersion: String + ): LogCollectorGroup! + updateLoginBridge( + input: LoginBridgeUpdateInput! + ): LoginBridge! +""" +Override the globally configured maximum number of auto shards. +""" + updateMaxAutoShardCount( + repositoryName: String! +""" +New override value. Set to zero to remove current override. +""" + maxAutoShardCount: Int! + ): Repository! +""" +Override the globally configured maximum size of ingest requests. +""" + updateMaxIngestRequestSize( + repositoryName: String! +""" +New override value. Set to zero to remove current override. +""" + maxIngestRequestSize: Int! + ): Repository! + updateOIDCIdentityProvider( + input: UpdateOidcConfigurationInput! + ): OidcIdentityProvider! +""" +Update an OpsGenie action. +""" + updateOpsGenieAction( +""" +Data for updating an OpsGenie action +""" + input: UpdateOpsGenieAction! + ): OpsGenieAction! +""" +For manually fixing bad references. Root operation. +""" + updateOrganizationForeignKey( + id: String! + foreignType: Organizations__ForeignType! + operation: Organizations__Operation! + ): Organization! +""" +Update information about the organization +""" + updateOrganizationInfo( + name: String! + countryCode: String! + industry: String! + useCases: [Organizations__UseCases!]! + ): Organization! +""" +For manually updating contract limits. System operation. +""" + updateOrganizationLimits( + input: OrganizationLimitsInput! + ): Organization! +""" +Update mutability of the organization +""" + updateOrganizationMutability( + organizationId: String! + blockIngest: Boolean! + readonly: Boolean! + ): Organization! +""" +Update a note for a given organization. Requires root. +""" + updateOrganizationNotes( + notes: String! + ): Boolean! +""" +Update the permissions of an organization permission token. +""" + updateOrganizationPermissionsTokenPermissions( + input: UpdateOrganizationPermissionsTokenPermissionsInput! + ): String! +""" +Update an users organizations root state +""" + updateOrganizationRoot( + userId: String! + organizationRoot: Boolean! + ): Organization! +""" +Update the subscription of the organization. Root operation. +""" + updateOrganizationSubscription( + input: UpdateSubscriptionInputObject! + ): Organization! +""" +Updates a package in a specific view. +""" + updatePackageFromRegistryV2( + UpdatePackageFromRegistryInput: UpdatePackageFromRegistryInput! + ): PackageUpdateResult! +""" +Updates a package from file provided in multipart/form-data (name=file) in a specific view. +""" + updatePackageFromZip( +""" +The name of the view the package is installed in. +""" + viewName: String! +""" +how to handle conflicts +""" + conflictResolutions: [ConflictResolutionConfiguration!]! +""" +[PREVIEW: The query ownership feature is still in development] Ownership of the queries run by the triggers (e.g. alerts and scheduled searches) that are installed as part of this package. If value is User, ownership will be based on the calling user. +""" + queryOwnershipType: QueryOwnershipType + ): BooleanResultType! +""" +Update a PagerDuty action. +""" + updatePagerDutyAction( +""" +Data for updating a PagerDuty action +""" + input: UpdatePagerDutyAction! + ): PagerDutyAction! +""" +Update a parser. +""" + updateParser( + input: UpdateParserInput! + ): UpdateParserMutation! +""" +Update a parser. Only the provided fields are updated on the parser, and the remaining fields not provided are unchanged. +""" + updateParserV2( + input: UpdateParserInputV2! + ): Parser! +""" +Update the viewers profile. +""" + updateProfile( + firstName: String + lastName: String + ): Account! +""" +Updates queryprefix for a group in a view. +""" + updateQueryPrefix( + input: UpdateQueryPrefixInput! + ): UpdateQueryPrefixMutation! +""" +Update the readonly dashboard ip filter +""" + updateReadonlyDashboardIPFilter( + ipFilter: String + ): Boolean! +""" +[PREVIEW: Experimental feature, not ready for production.] Update a cluster connection to a remote view. +""" + updateRemoteClusterConnection( +""" +Data for updating a remote cluster connection +""" + input: UpdateRemoteClusterConnectionInput! + ): RemoteClusterConnection! +""" +Change the data type of a repository. +""" + updateRepositoryDataType( + input: UpdateRepoDataTypeInputObject! + ): Boolean! +""" +Change the limit id of a repository. +""" + updateRepositoryLimitId( + input: UpdateRepoLimitIdInputObject! + ): Boolean! +""" +Change the type of a repository. Only useful in Cloud setups. +""" + updateRepositoryType( + name: String! + type: String! + ): BooleanResultType! +""" +Change the usage tag of a repository. +""" + updateRepositoryUsageTag( + name: String! + usageTag: String! + ): Boolean! +""" +Update the retention policy of a repository. +""" + updateRetention( +""" +The name of the repository to change retention for. +""" + repositoryName: String! +""" +The maximum time (in days) to keep data. Data old than this will be deleted. +""" + timeBasedRetention: Float +""" +Sets retention (in gigabytes) based on the size of data when it arrives to LogScale, that is before parsing and compression. LogScale will keep `at most` this amount of data. +""" + ingestSizeBasedRetention: Float +""" +Sets retention (in gigabytes) based on the size of data when it is stored in LogScale, that is after parsing and compression. LogScale will keep `at most` this amount of data. +""" + storageSizeBasedRetention: Float +""" +Sets time (in days) to keep backups before they are deleted. +""" + timeBasedBackupRetention: Float + ): UpdateRetentionMutation! + updateRole( + input: UpdateRoleInput! + ): UpdateRoleMutation! + updateSamlIdentityProvider( + id: String! + name: String! + signOnUrl: String! + idpCertificateInBase64: String! + idpEntityId: String! + domains: [String!]! + groupMembershipAttribute: String + userAttribute: String + enableDebug: Boolean +""" +Only used internal +""" + adminAttribute: String +""" +Only used internal +""" + adminAttributeMatch: String +""" +If multiple Idp's are defined the default idp is used whenever redirecting to login +""" + defaultIdp: Boolean +""" +Only used internal +""" + humioOwned: Boolean +""" +Lazy create users during login +""" + lazyCreateUsers: Boolean + ): SamlIdentityProvider! +""" +Updates a saved query. +""" + updateSavedQuery( + input: UpdateSavedQueryInput! + ): UpdateSavedQueryPayload! +""" +Update a scheduled report. Only the supplied property values are updated. +""" + updateScheduledReport( + input: UpdateScheduledReportInput! + ): ScheduledReport! +""" +Update a scheduled search. +""" + updateScheduledSearch( +""" +Data for updating a scheduled search +""" + input: UpdateScheduledSearch! + ): ScheduledSearch! +""" +[PREVIEW: in development.] Update a search link interaction. +""" + updateSearchLinkInteraction( + input: UpdateSearchLinkInteractionInput! + ): InteractionId! +""" +Update session settings for the organization. +""" + updateSessionSettings( + input: SessionInput! + ): Organization! +""" +[PREVIEW: This mutation is dictated by the needs of the LogScale UI, and may include unstable or ephemeral settings.] Set flags for UI states and help messages. +""" + updateSettings( + isWelcomeMessageDismissed: Boolean + isGettingStartedMessageDismissed: Boolean + isCommunityMessageDismissed: Boolean + isPackageDocsMessageDismissed: Boolean + isEventListOrderedWithNewestAtBottom: Boolean + isFieldPanelOpenByDefault: Boolean + automaticallySearch: Boolean + automaticallyHighlighting: Boolean + uiTheme: UiTheme + isDarkModeMessageDismissed: Boolean + isResizableQueryFieldMessageDismissed: Boolean + featureAnnouncementsToDismiss: [FeatureAnnouncement!] + defaultTimeZone: String + ): UserSettings! +""" +Update the shared dashboards security policies for the organization. Updating the policies will update or delete all existing tokens that do not fit into the changes. For instance, enforcing an IP filter will set the IP filter on all shared dashboard tokens. Disabling shared dashboard tokens, will delete all shared dashboard tokens. +""" + updateSharedDashboardsSecurityPolicies( + input: SharedDashboardsSecurityPoliciesInput! + ): Organization! +""" +Update a Slack action. +""" + updateSlackAction( +""" +Data for updating a Slack action +""" + input: UpdateSlackAction! + ): SlackAction! +""" +Update a post-message Slack action. +""" + updateSlackPostMessageAction( +""" +Data for updating a post-message Slack action +""" + input: UpdatePostMessageSlackAction! + ): SlackPostMessageAction! +""" +[PREVIEW: Requires the feature enabled for the organization.] Update the social login options for the organization +""" + updateSocialLoginSettings( + input: [SocialLoginSettingsInput!]! + ): Organization! +""" +Update the permissions of a system permission token. +""" + updateSystemPermissionsTokenPermissions( + input: UpdateSystemPermissionsTokenPermissionsInput! + ): String! +""" +Update the token security policies for the organization. Updating the policies will update or delete all existing tokens that do not fit into the changes. For instance, enforcing an IP filter for personal user tokens will set the IP filter on all tokens of that type. Disabling a token type, will delete all tokens of that type. Finally setting an enforce expiration after will set that on all tokens that are above the interval and keep their current expiration if inside the interval. Tokens below the expiration will be deleted. +""" + updateTokenSecurityPolicies( + input: TokenSecurityPoliciesInput! + ): Organization! +""" +Update an upload file action. +""" + updateUploadFileAction( +""" +Data for updating an upload file action. +""" + input: UpdateUploadFileAction! + ): UploadFileAction! +""" +Updates a user. Requires Root Permission. +""" + updateUser( + input: AddUserInput! + ): UpdateUserMutation! +""" +Updates a user. +""" + updateUserById( + input: UpdateUserByIdInput! + ): UpdateUserByIdMutation! +""" +Update user default settings for the organization. +""" + updateUserDefaultSettings( + input: UserDefaultSettingsInput! + ): Organization! +""" +Update a VictorOps action. +""" + updateVictorOpsAction( +""" +Data for updating a VictorOps action. +""" + input: UpdateVictorOpsAction! + ): VictorOpsAction! +""" +Update a view. +""" + updateView( + viewName: String! + connections: [ViewConnectionInput!]! + ): View! +""" +Update the permissions of a view permission token. +""" + updateViewPermissionsTokenPermissions( + input: UpdateViewPermissionsTokenPermissionsInput! + ): String! +""" +Update a webhook action. +""" + updateWebhookAction( +""" +Data for updating a webhook action +""" + input: UpdateWebhookAction! + ): WebhookAction! +""" +Upgrade the account. +""" + upgradeAccount( + input: UpgradeAccountData! + ): Boolean! +} + +""" +This authentication type can be used to use LogScale without authentication. This should only be considered for testing and development purposes, it is not recommended for production systems and prevents LogScale from doing proper Audit Logging. +""" +type NoAuthentication implements AuthenticationMethod{ + name: String! +} + +""" +A widget get text, links, etc. +""" +type NoteWidget implements Widget{ + backgroundColor: String + textColor: String + text: String! + id: String! + title: String! + description: String + x: Int! + y: Int! + width: Int! + height: Int! +} + +input NotificationInput { + message: String! + target: Targets! + ids: [String!] + title: String! + dismissable: Boolean! + severity: NotificationSeverity! + link: String + linkDescription: String + notificationType: NotificationTypes! +} + +""" +Authentication through OAuth Identity Providers. +""" +type OAuthAuthentication implements AuthenticationMethod{ + name: String! + uiLoginFlow: Boolean! + google: OAuthProvider + github: OAuthProvider + bitbucket: OAuthProvider + oidc: OIDCProvider +} + +""" +An OAuth Identity Provider. +""" +type OAuthProvider { + id: String! + clientId: String! + redirectUrl: String! +} + +""" +An OIDC identity provider +""" +type OIDCProvider { + id: String! + clientId: String! + redirectUrl: String! + authorizationEndpoint: String + serviceName: String + scopes: [String!]! + federatedIdp: String +} + +enum ObjectAction { + Unknown + ReadOnlyAndHidden + ReadWriteAndVisible +} + +input OidcConfigurationInput { + name: String! + clientID: String! + clientSecret: String! + issuer: String! + tokenEndpointAuthMethod: String! + authorizationEndpoint: String! + tokenEndpoint: String + userInfoEndpoint: String + registrationEndpoint: String + groupsClaim: String + JWKSEndpoint: String + domains: [String!]! + scopes: [String!]! + userClaim: String + enableDebug: Boolean! + defaultIdp: Boolean + humioOwned: Boolean + lazyCreateUsers: Boolean + federatedIdp: String + scopeClaim: String +} + +type OidcIdentityProviderAuth implements AuthenticationMethodAuth{ + redirectUrl: String! + authType: String! + name: String! + scopes: [String!]! + serviceName: String! + authorizeEndpoint: String! + clientId: String! + federatedIdp: String +} + +""" +Represents information about a LogScale License. +""" +type OnPremLicense implements License{ +""" +The time at which the license expires. +""" + expiresAt: DateTime! +""" +The time at which the license was issued. +""" + issuedAt: DateTime! +""" +license id. +""" + uid: String! +""" +The maximum number of user accounts allowed in LogScale. Unlimited if undefined. +""" + maxUsers: Int +""" +The name of the entity the license was issued to. +""" + owner: String! +""" +Indicates whether the license allows running LogScale as a SaaS platform. +""" + isSaaS: Boolean! +""" +Indicates whether the license is an OEM license. +""" + isOem: Boolean! +} + +""" +An OpsGenie action +""" +type OpsGenieAction implements Action{ +""" +OpsGenie webhook url to send the request to. +""" + apiUrl: String! +""" +Key to authenticate with OpsGenie. +""" + genieKey: String! +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +input OrganizationLimitsInput { + ingest: Long! + retention: Int! + users: Int! + expiration: Long! + allowSelfService: Boolean + contractVersion: Organizations__ContractVersion +} + +""" +A link between two organizations +""" +type OrganizationLink { + parentOrganization: Organization! + childOrganization: Organization! +} + +""" +Query running with organization based ownership +""" +type OrganizationOwnership implements QueryOwnership{ +""" +Organization owning and running the query +""" + organization: Organization! +""" +Id of organization owning and running the query +""" + id: String! +} + +""" +Organization permissions token. The token allows the caller to work with organization-level permissions. +""" +type OrganizationPermissionsToken implements Token{ +""" +The set of permissions on the token +""" + permissions: [String!]! +""" +The id of the token. +""" + id: String! +""" +The name of the token. +""" + name: String! +""" +The time at which the token expires. +""" + expireAt: Long +""" +The ip filter on the token. +""" + ipFilter: String +""" +The ip filter on the token. +""" + ipFilterV2: IPFilter +""" +The date the token was created. +""" + createdAt: Long! +} + +enum Organizations__ContractualType { + Limited + Unlimited + Ignored +} + +enum Organizations__ForeignType { + Unknown + Role + Group + Idp + View + User +} + +enum Organizations__Operation { + Remove + Add +} + +""" +An event produced by a parser in a test run +""" +type OutputEvent { +""" +The fields of the event +""" + fields: [EventField!]! +} + +type PackageUpdateResult { + package: Package2! +} + +""" +A PagerDuty action. +""" +type PagerDutyAction implements Action{ +""" +Severity level to give to the message. +""" + severity: String! +""" +Routing key to authenticate with PagerDuty. +""" + routingKey: String! +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +input ParameterFilePropertiesInput { + fileName: String! + valueColumn: String! + labelColumn: String + valueFilters: [ParameterFileValueFilter!]! + invalidInputPatterns: [String!] + invalidInputMessage: String +} + +input ParameterFileValueFilter { + field: String! + values: [String!]! +} + +input ParameterFixedListOption { + label: String! + value: String! +} + +input ParameterFixedListPropertiesInput { + values: [ParameterFixedListOption!]! +} + +input ParameterFreeTextPropertiesInput { + invalidInputPatterns: [String!] + invalidInputMessage: String +} + +input ParameterInput { + id: String! + label: String! + defaultValue: String + order: Int + width: Int + freeTextOptions: ParameterFreeTextPropertiesInput + queryOptions: ParameterQueryPropertiesInput + fixedListOptions: ParameterFixedListPropertiesInput + fileOptions: ParameterFilePropertiesInput + isMultiParam: Boolean + defaultMultiValues: [String!] +} + +""" +A widget that contains dashboard parameters. +""" +type ParameterPanel implements Widget{ + parameterIds: [String!]! + id: String! + title: String! + description: String + x: Int! + y: Int! + width: Int! + height: Int! +} + +input ParameterQueryPropertiesInput { + queryString: String! + timeWindow: String! + optionValueField: String! + optionLabelField: String! + useDashboardTimeIfSet: Boolean! + invalidInputPatterns: [String!] + invalidInputMessage: String +} + +""" +The specification of a parameter +""" +input ParameterSpecificationInput { +""" +The specification of a parameter +""" + name: String! +""" +The specification of a parameter +""" + parameterType: ParameterTypeEnum! +""" +The specification of a parameter +""" + minLong: Long +""" +The specification of a parameter +""" + maxLong: Long +""" +The specification of a parameter +""" + minDouble: Float +""" +The specification of a parameter +""" + maxDouble: Float +""" +The specification of a parameter +""" + minLength: Int +""" +The specification of a parameter +""" + defaultValue: [String!] +} + +""" +The result of parsing a single test event +""" +type ParseEventResult { +""" +The status of parsing the test event +""" + status: ParseEventStatus! +""" +A potential error message +""" + errorMessage: String +""" +The parsed events. Can be empty if the test was dropped by the parser or contain one or more events +""" + events: [ParsedEvent!]! +} + +""" +Staus of parsing a test event +""" +enum ParseEventStatus { +""" +The event was parsed successfully +""" + success +""" +There was an error parsing the event +""" + parseError +""" +There was an error extracting a timestamp from the event +""" + timestampError +} + +""" +A parsed event +""" +type ParsedEvent { +""" +The fields of the event +""" + fields: [Field!]! +} + +""" +Assertions on the shape of a given test case output event. It is a key-pair value, where the index of the output event is the key, and the assertions are the value. +""" +input ParserTestCaseAssertionsForOutputInput { +""" +Assertions on the shape of a given test case output event. It is a key-pair value, where the index of the output event is the key, and the assertions are the value. +""" + outputEventIndex: Int! +""" +Assertions on the shape of a given test case output event. It is a key-pair value, where the index of the output event is the key, and the assertions are the value. +""" + assertions: ParserTestCaseOutputAssertionsInput! +} + +""" +Contains any test failures that relates to a specific output event. This is a key-value pair, where the index of the output event is the key, and the failures are the value. +""" +type ParserTestCaseFailuresForOutput { +""" +The index of the output event which these failures pertain to. Note that there may be failures pointing to non-existing output events, if e.g. an assertion was made on an output event which was not produced. +""" + outputEventIndex: Int! +""" +Failures for the output event. +""" + failures: ParserTestCaseOutputFailures! +} + +""" +A test case for a parser. +""" +input ParserTestCaseInput { +""" +A test case for a parser. +""" + event: ParserTestEventInput! +""" +A test case for a parser. +""" + outputAssertions: [ParserTestCaseAssertionsForOutputInput!] +} + +""" +Assertions on the shape of a given test case output event. +""" +input ParserTestCaseOutputAssertionsInput { +""" +Assertions on the shape of a given test case output event. +""" + fieldsNotPresent: [String!] +""" +Assertions on the shape of a given test case output event. +""" + fieldsHaveValues: [FieldHasValueInput!] +} + +""" +Failures for an output event. +""" +type ParserTestCaseOutputFailures { +""" +Any errors produced by the parser when creating an output event. +""" + parsingErrors: [String!]! +""" +Any assertion failures on the given output event. Note that all assertion failures can be uniquely identified by the output event index and the field name they operate on. +""" + assertionFailuresOnFields: [AssertionFailureOnField!]! +""" +[PREVIEW: API under active development] Fields where the name begins with `#` even though they are not a tag. In LogScale, field names beginning with `#` are treated specially, and should only be constructed through the tagging mechanism. Fields which do begin with `#`, but are not proper tags, will be effectively unsearchable. +""" + falselyTaggedFields: [String!]! +""" +[PREVIEW: API under active development] Any arrays with gaps in them. That is, if the fields `a[0]` and `a[2]` exist on an event, but not `a[1]`, we consider the array `a` to have a gap. This means LogScale will not include the `a[2]` field when doing array-based searches, since it considers `a[0]` to be the last element of the array. +""" + arraysWithGaps: [ArrayWithGap!]! +} + +""" +The output for parsing and verifying a test case +""" +type ParserTestCaseResult { +""" +The events produced by the parser. Contains zero to many events, as a parser can both drop events, or produce multiple output events from a single input. +""" + outputEvents: [OutputEvent!]! +""" +Any failures produced during testing. If the list is empty, the test case can be considered to have passed. If the list contains elements, they are key-value pairs to be treated as a map-construct, where the index of the output event is the key, and the failures are the value. +""" + outputFailures: [ParserTestCaseFailuresForOutput!]! +} + +""" +An event for a parser to parse during testing. +""" +input ParserTestEventInput { +""" +An event for a parser to parse during testing. +""" + rawString: String! +} + +""" +A parser test result, where an unexpected error occurred during parsing. +""" +type ParserTestRunAborted { + errorMessage: String! +} + +""" +A parser test result, where all test cases were parsed and assertions run. Each result is given in the same order as the test cases were put in, so they can be matched by index. +""" +type ParserTestRunCompleted { +""" +The results for running each test case. +""" + results: [ParserTestCaseResult!]! +} + +""" +Input for testing a parser +""" +input ParserTestRunInput { +""" +Input for testing a parser +""" + repositoryName: RepoOrViewName! +""" +Input for testing a parser +""" + parserName: String! +""" +Input for testing a parser +""" + script: String! +""" +Input for testing a parser +""" + fieldsToTag: [String!]! +""" +Input for testing a parser +""" + fieldsToBeRemovedBeforeParsing: [String!]! +""" +Input for testing a parser +""" + testCases: [ParserTestCaseInput!]! +""" +Input for testing a parser +""" + languageVersion: LanguageVersionInputType +} + +""" +The output of running all the parser test cases. +""" +union ParserTestRunOutput =ParserTestRunCompleted | ParserTestRunAborted + +enum Purposes { + MSP + ITOps + IOT + SecOps + DevOps +} + +""" +A dashboard parameter where suggestions are sourced from query results from LogScale. +""" +type QueryBasedDashboardParameter implements DashboardParameter{ +""" +The LogScale query executed to find suggestions for the parameter value. +""" + queryString: String! +""" +The time window (relative to now) in which LogScale will search for suggestions. E.g. 24h or 30d. +""" + timeWindow: String! +""" +The field in the result set used as the 'value' of the suggestions. +""" + optionValueField: String! +""" +The field in the result set used as the 'label' (the text in the dropdown) of the suggestions. +""" + optionLabelField: String! +""" +If true, the parameters search time window will automatically change to match the dashboard's global time when active. +""" + useDashboardTimeIfSet: Boolean! +""" +Regex patterns used to block parameter input. +""" + invalidInputPatterns: [String!] +""" +Message when parameter input is blocked. +""" + invalidInputMessage: String +""" +The ID of the parameter. +""" + id: String! +""" +The label or 'name' displayed next to the input for the variable to make it more human-readable. +""" + label: String! +""" +The value assigned to the parameter on dashboard load, if no other value is specified. +""" + defaultValueV2: String +""" +A number that determines the order in which parameters are displayed on a dashboard. If null, the parameter is ordered after other parameters in alphanumerical order. +""" + order: Int +""" +A number that determines the width of a parameter. +""" + width: Int +""" +[PREVIEW: The multi-value parameters feature is still in development.] A flag indicating whether the parameter supports having multiple values +""" + isMultiParam: Boolean +""" +[PREVIEW: The multi-value parameters feature is still in development.] The value assigned to the multi-value parameter on dashboard load, if no other value is specified. This replaces defaultValue whenever isMultiParam is true +""" + defaultMultiValues: [String!] +} + +""" +A widget with a visualization of a query result. +""" +type QueryBasedWidget implements Widget{ + queryString: String! + start: String! + end: String! + isLive: Boolean! + widgetType: String! +""" +An optional JSON value containing styling and other settings for the widget. This is solely used by the UI. +""" + options: JSON +""" +[PREVIEW: Widget based interaction feature is under preview.] +""" + interactions: [QueryBasedWidgetInteraction!]! + id: String! + title: String! + description: String + x: Int! + y: Int! + width: Int! + height: Int! +} + +""" +The type of query ownership +""" +enum QueryOwnershipType { +""" +Queries run on behalf of user +""" + User +""" +Queries run on behalf of the organization +""" + Organization +} + +""" +The target type to select +""" +enum QueryOwnership_SelectionTargetType { +""" +A single trigger or shared dashboard +""" + PersistentQuery +""" +All triggers and shared dashboard connected to this view +""" + View +""" +All triggers and shared dashboards within the organization +""" + Organization +} + +""" +Default Query Quota Settings for users which have not had specific settings assigned +""" +type QueryQuotaDefaultSettings { +""" +List of the rules that apply +""" + settings: [QueryQuotaIntervalSetting!]! +} + +input QueryQuotaDefaultSettingsInput { + settings: [QueryQuotaIntervalSettingInput!]! +} + +input QueryQuotaIntervalSettingInput { + interval: QueryQuotaInterval! + measurementKind: QueryQuotaMeasurementKind! + value: Long + valueKind: QueryQuotaIntervalSettingKind! +} + +input QueryQuotaUserSettingsInput { + username: String! + settings: [QueryQuotaIntervalSettingInput!]! +} + +input RedactEventsInputType { + repositoryName: String! + start: DateTime! + end: DateTime! + query: String! + userMessage: String +} + +""" +A remote cluster connection. +""" +type RemoteClusterConnection implements ClusterConnection{ +""" +Public URL of the remote cluster to connect with +""" + publicUrl: String! +""" +Id of the connection +""" + id: String! +""" +Cluster identity of the connection +""" + clusterId: String! +""" +Cluster connection tags +""" + tags: [ClusterConnectionTag!]! +""" +Cluster connection query prefix +""" + queryPrefix: String! +} + +""" +Data for removing a label from an alert +""" +input RemoveAlertLabel { +""" +Data for removing a label from an alert +""" + viewName: String! +""" +Data for removing a label from an alert +""" + id: String! +""" +Data for removing a label from an alert +""" + label: String! +} + +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field removeFieldAliasMapping +""" +input RemoveAliasMappingInput { +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field removeFieldAliasMapping +""" + schemaId: String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field removeFieldAliasMapping +""" + aliasMappingId: String! +} + +""" +Data for removing a blocklist entry +""" +input RemoveFromBlocklistInput { +""" +Data for removing a blocklist entry +""" + id: String! +} + +type RemoveGroupMutation { + group: Group! +} + +""" +Data for removing a label +""" +input RemoveLabelScheduledSearch { +""" +Data for removing a label +""" + viewName: String! +""" +Data for removing a label +""" + id: String! +""" +Data for removing a label +""" + label: String! +} + +input RemoveLimitInput { + limitName: String! +} + +input RemoveOrganizationRoleFromGroupInput { + groupId: String! + roleId: String! +} + +input RemoveParserInput { + id: String! + repositoryName: String! +} + +type RemoveParserMutation { + parser: Parser! +} + +""" +Data to remove a repository cache policy +""" +input RemoveRepoCachePolicyInput { +""" +Data to remove a repository cache policy +""" + repositoryName: String! +} + +input RemoveRoleFromGroupInput { + viewId: String! + groupId: String! + roleId: String! +} + +input RemoveSecondarySubdomainInput { + subdomain: String! +} + +""" +Data for removing a star from an alert +""" +input RemoveStarFromAlert { +""" +Data for removing a star from an alert +""" + viewName: String! +""" +Data for removing a star from an alert +""" + id: String! +} + +input RemoveStarFromQueryInput { + savedQueryId: String! + searchDomainName: String! +} + +""" +Data for removing a star +""" +input RemoveStarScheduledSearch { +""" +Data for removing a star +""" + viewName: String! +""" +Data for removing a star +""" + id: String! +} + +input RemoveStarToFieldInput { + fieldName: String! + searchDomainName: String! +} + +type RemoveStarToFieldMutation { + starredFields: [String!]! +} + +input RemoveSystemRoleFromGroupInput { + groupId: String! + roleId: String! +} + +input RemoveUserByIdInput { + id: String! +} + +type RemoveUserByIdMutation { + user: User! +} + +input RemoveUserInput { + username: String! +} + +type RemoveUserMutation { + user: User! +} + +input RemoveUsersFromGroupInput { + users: [String!]! + groupId: String! +} + +type RemoveUsersFromGroupMutation { + group: Group! +} + +input RenameSearchDomainByIdInput { + id: String! + newName: String! + renameMessage: String +} + +input RepoFilterInput { + name: String! + filter: String! +} + +""" +Data for a reported warning or error. +""" +input ReportErrorInput { +""" +Data for a reported warning or error. +""" + errorType: String! +""" +Data for a reported warning or error. +""" + errorMessage: String! +} + +""" +Data for resetting quota +""" +input ResetQuotaInput { +""" +Data for resetting quota +""" + newQuota: Long +""" +Data for resetting quota +""" + newRate: Long +} + +input RestoreDeletedSearchDomainInput { + id: String! +} + +input ResubmitMarketoLeadData { + utmParams: UtmParams + zip: String +} + +input RevokeSessionInput { + id: String! + revocationType: SessionRevocation__Type! +} + +input RotateTokenInputData { + id: String! +} + +input RunInconsistencyCheckInput { + dryRun: Boolean! +} + +""" +This authentication type implements the SAML 2.0 Web Browser SSO Profile. +""" +type SAMLAuthentication implements AuthenticationMethod{ + name: String! +} + +type SamlIdentityProviderAuth implements AuthenticationMethodAuth{ + name: String! + authType: String! +} + +type SavedQueryIsStarred { + id: String! + isStarred: Boolean! +} + +type SavedQueryStarredUpdate { + savedQuery: SavedQueryIsStarred! +} + +""" +Data for reporting a failed report generation attempt. +""" +input ScheduledReportResultFailedInput { +""" +Data for reporting a failed report generation attempt. +""" + reportErrors: [ReportErrorInput!]! +} + +""" +Data for reporting a successful report generation attempt. +""" +input ScheduledReportResultSucceededInput { +""" +Data for reporting a successful report generation attempt. +""" + filename: String! +} + +input SchemaFieldInput { + name: String! + description: String +} + +input SearchLinkInteractionInput { + name: String! + titleTemplate: String + repoOrViewName: RepoOrViewName + queryString: String! + isLive: Boolean! + arguments: [ArgumentInput!]! + openInNewTab: Boolean! + useWidgetTimeWindow: Boolean! + fieldInteractionConditions: [FieldInteractionConditionInput!] +} + +input SectionInput { + id: String! + title: String + description: String + collapsed: Boolean! + timeSelector: TimeIntervalInput + widgetIds: [String!]! + order: Int! +} + +input ServiceLevelIndicatorLogArg { + frontendVersion: String! + content: JSON! +} + +input SessionInput { + maxInactivityPeriod: Long! + forceReauthenticationAfter: Long! +} + +enum SessionRevocation__Type { + Organization + User + Session +} + +input SetDefaultSavedQueryInput { + savedQueryId: String + viewName: String! +} + +""" +Data to set a global default cache policy +""" +input SetGlobalDefaultCachePolicyInput { +""" +Data to set a global default cache policy +""" + policy: CachePolicyInput! +} + +input SetLimitDisplayNameInput { + limitName: String! + displayName: String +} + +""" +Data to set a organization default cache policy +""" +input SetOrgDefaultCachePolicyInput { +""" +Data to set a organization default cache policy +""" + policy: CachePolicyInput! +} + +input SetPrimarySubdomainInput { + subdomain: String! +} + +""" +Data to set a repo cache policy +""" +input SetRepoCachePolicyInput { +""" +Data to set a repo cache policy +""" + repositoryName: String! +""" +Data to set a repo cache policy +""" + policy: CachePolicyInput! +} + +""" +Data for updating search limit on a search domain. +""" +input SetSearchLimitForSearchDomain { +""" +Data for updating search limit on a search domain. +""" + id: String! +""" +Data for updating search limit on a search domain. +""" + searchLimitMs: Long! +""" +Data for updating search limit on a search domain. +""" + excludedRepoIds: [String!]! +} + +input SetSubdomainSettingsInput { + primarySubdomain: String! + secondarySubdomains: [String!] + enforceSubdomains: Boolean! +} + +""" +Data for updating shared dashboards security policies +""" +input SharedDashboardsSecurityPoliciesInput { +""" +Data for updating shared dashboards security policies +""" + sharedDashboardsEnabled: Boolean! +""" +Data for updating shared dashboards security policies +""" + enforceIpFilterId: String +} + +""" +A Slack action +""" +type SlackAction implements Action{ +""" +Slack webhook url to send the request to. +""" + url: String! +""" +Fields to include within the Slack message. Can be templated with values from the result. +""" + fields: [SlackFieldEntry!]! +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +Field entry in a Slack message +""" +type SlackFieldEntry { +""" +Key of a Slack field. +""" + fieldName: String! +""" +Value of a Slack field. +""" + value: String! +} + +""" +Slack message field entry. +""" +input SlackFieldEntryInput { +""" +Slack message field entry. +""" + fieldName: String! +""" +Slack message field entry. +""" + value: String! +} + +""" +A slack post-message action. +""" +type SlackPostMessageAction implements Action{ +""" +Api token to authenticate with Slack. +""" + apiToken: String! +""" +List of Slack channels to message. +""" + channels: [String!]! +""" +Fields to include within the Slack message. Can be templated with values from the result. +""" + fields: [SlackFieldEntry!]! +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +input SocialLoginSettingsInput { + socialProviderProfile: SocialProviderProfile! + filter: SocialLoginField! + allowList: [String!]! +} + +input StopQueriesInput { + clusterWide: Boolean +} + +""" +System permissions token. The token allows the caller to work with system-level permissions. +""" +type SystemPermissionsToken implements Token{ +""" +The set of permissions on the token +""" + permissions: [String!]! +""" +The id of the token. +""" + id: String! +""" +The name of the token. +""" + name: String! +""" +The time at which the token expires. +""" + expireAt: Long +""" +The ip filter on the token. +""" + ipFilter: String +""" +The ip filter on the token. +""" + ipFilterV2: IPFilter +""" +The date the token was created. +""" + createdAt: Long! +} + +""" +The grouping rule for a given tag. +""" +input TagGroupingRuleInput { +""" +The grouping rule for a given tag. +""" + tagName: String! +""" +The grouping rule for a given tag. +""" + groupCount: Int! +} + +input TagsInput { + name: String! + value: String! +} + +enum Targets { + All + Group + Root + OrgRoot +} + +""" +Data for testing an ingest feed that uses AWS S3 and SQS +""" +input TestAwsS3SqsIngestFeed { +""" +Data for testing an ingest feed that uses AWS S3 and SQS +""" + repositoryName: RepoOrViewName! +""" +Data for testing an ingest feed that uses AWS S3 and SQS +""" + authentication: IngestFeedAwsAuthenticationInput! +""" +Data for testing an ingest feed that uses AWS S3 and SQS +""" + sqsUrl: String! +""" +Data for testing an ingest feed that uses AWS S3 and SQS +""" + region: String! +} + +""" +Data for testing an email action +""" +input TestEmailAction { +""" +Data for testing an email action +""" + viewName: String! +""" +Data for testing an email action +""" + name: String! +""" +Data for testing an email action +""" + recipients: [String!]! +""" +Data for testing an email action +""" + subjectTemplate: String +""" +Data for testing an email action +""" + bodyTemplate: String +""" +Data for testing an email action +""" + useProxy: Boolean! +""" +Data for testing an email action +""" + attachCsv: Boolean +""" +Data for testing an email action +""" + triggerName: String! +""" +Data for testing an email action +""" + eventData: String! +} + +""" +Collection of errors, which occurred during test. +""" +type TestFdrErrorResult { +""" +List of test errors. +""" + errors: [error!]! +} + +""" +Data for testing an FDR feed. +""" +input TestFdrFeed { +""" +Data for testing an FDR feed. +""" + repositoryName: String! +""" +Data for testing an FDR feed. +""" + feedId: String +""" +Data for testing an FDR feed. +""" + clientId: String +""" +Data for testing an FDR feed. +""" + clientSecret: String +""" +Data for testing an FDR feed. +""" + sqsUrl: String +""" +Data for testing an FDR feed. +""" + s3Identifier: String +} + +""" +An error, which occurred when making a request towards an AWS resource. +""" +type TestFdrRequestError { +""" +Name of the AWS resource, which the request was made towards. +""" + resourceName: String! +""" +Message specifying the request error. +""" + message: String! +} + +""" +Result of testing an FDR feed. +""" +union TestFdrResult =TestFdrErrorResult | TestFdrSuccessResult + +""" +Test was a success. +""" +type TestFdrSuccessResult { +""" +This field is always 'true' +""" + result: Boolean! +} + +""" +A validation error related to a particular input field. +""" +type TestFdrValidationError { +""" +Name of the field, which the error relates to. +""" + fieldName: String! +""" +Message specifying the validation error. +""" + message: String! +} + +""" +Data for testing a Humio repo action +""" +input TestHumioRepoAction { +""" +Data for testing a Humio repo action +""" + viewName: String! +""" +Data for testing a Humio repo action +""" + name: String! +""" +Data for testing a Humio repo action +""" + ingestToken: String! +""" +Data for testing a Humio repo action +""" + triggerName: String! +""" +Data for testing a Humio repo action +""" + eventData: String! +} + +""" +Data for testing a Kafka event forwarder +""" +input TestKafkaEventForwarder { +""" +Data for testing a Kafka event forwarder +""" + name: String! +""" +Data for testing a Kafka event forwarder +""" + description: String! +""" +Data for testing a Kafka event forwarder +""" + properties: String! +""" +Data for testing a Kafka event forwarder +""" + topic: String! +""" +Data for testing a Kafka event forwarder +""" + enabled: Boolean +} + +""" +Data for testing an OpsGenie action +""" +input TestOpsGenieAction { +""" +Data for testing an OpsGenie action +""" + viewName: String! +""" +Data for testing an OpsGenie action +""" + name: String! +""" +Data for testing an OpsGenie action +""" + apiUrl: String! +""" +Data for testing an OpsGenie action +""" + genieKey: String! +""" +Data for testing an OpsGenie action +""" + useProxy: Boolean! +""" +Data for testing an OpsGenie action +""" + triggerName: String! +""" +Data for testing an OpsGenie action +""" + eventData: String! +} + +""" +Data for testing a PagerDuty action. +""" +input TestPagerDutyAction { +""" +Data for testing a PagerDuty action. +""" + viewName: String! +""" +Data for testing a PagerDuty action. +""" + name: String! +""" +Data for testing a PagerDuty action. +""" + severity: String! +""" +Data for testing a PagerDuty action. +""" + routingKey: String! +""" +Data for testing a PagerDuty action. +""" + useProxy: Boolean! +""" +Data for testing a PagerDuty action. +""" + triggerName: String! +""" +Data for testing a PagerDuty action. +""" + eventData: String! +} + +""" +An error occurred while running the parser and no events were parsed +""" +type TestParserErrorResult { +""" +An error message +""" + errorMessage: String! +} + +""" +Input for testing a parser +""" +input TestParserInputV2 { +""" +Input for testing a parser +""" + repositoryName: String! +""" +Input for testing a parser +""" + parserId: String! +""" +Input for testing a parser +""" + parserName: String! +""" +Input for testing a parser +""" + parserScript: String! +""" +Input for testing a parser +""" + testData: [String!]! +} + +""" +The result of running the parser on all the test events +""" +union TestParserResultV2 =TestParserSuccessResultV2 | TestParserErrorResult + +""" +The parser produced results for each test event +""" +type TestParserSuccessResultV2 { +""" +The results of parsing the test events +""" + results: [ParseEventResult!]! +} + +""" +Data for testing a post message Slack action. +""" +input TestPostMessageSlackAction { +""" +Data for testing a post message Slack action. +""" + viewName: String! +""" +Data for testing a post message Slack action. +""" + name: String! +""" +Data for testing a post message Slack action. +""" + apiToken: String! +""" +Data for testing a post message Slack action. +""" + channels: [String!]! +""" +Data for testing a post message Slack action. +""" + fields: [SlackFieldEntryInput!]! +""" +Data for testing a post message Slack action. +""" + useProxy: Boolean! +""" +Data for testing a post message Slack action. +""" + triggerName: String! +""" +Data for testing a post message Slack action. +""" + eventData: String! +} + +""" +The result of the test +""" +type TestResult { +""" +True if the test was a success, false otherwise +""" + success: Boolean! +""" +A message explaining the test result +""" + message: String! +} + +""" +Data for testing a Slack action. +""" +input TestSlackAction { +""" +Data for testing a Slack action. +""" + viewName: String! +""" +Data for testing a Slack action. +""" + name: String! +""" +Data for testing a Slack action. +""" + url: String! +""" +Data for testing a Slack action. +""" + fields: [SlackFieldEntryInput!]! +""" +Data for testing a Slack action. +""" + useProxy: Boolean! +""" +Data for testing a Slack action. +""" + triggerName: String! +""" +Data for testing a Slack action. +""" + eventData: String! +} + +""" +Data for testing an upload file action. +""" +input TestUploadFileAction { +""" +Data for testing an upload file action. +""" + viewName: String! +""" +Data for testing an upload file action. +""" + name: String! +""" +Data for testing an upload file action. +""" + fileName: String! +""" +Data for testing an upload file action. +""" + triggerName: String! +""" +Data for testing an upload file action. +""" + eventData: String! +} + +""" +Data for testing a VictorOps action. +""" +input TestVictorOpsAction { +""" +Data for testing a VictorOps action. +""" + viewName: String! +""" +Data for testing a VictorOps action. +""" + name: String! +""" +Data for testing a VictorOps action. +""" + messageType: String! +""" +Data for testing a VictorOps action. +""" + notifyUrl: String! +""" +Data for testing a VictorOps action. +""" + useProxy: Boolean! +""" +Data for testing a VictorOps action. +""" + triggerName: String! +""" +Data for testing a VictorOps action. +""" + eventData: String! +} + +""" +Data for testing a webhook action. +""" +input TestWebhookAction { +""" +Data for testing a webhook action. +""" + viewName: String! +""" +Data for testing a webhook action. +""" + name: String! +""" +Data for testing a webhook action. +""" + url: String! +""" +Data for testing a webhook action. +""" + method: String! +""" +Data for testing a webhook action. +""" + headers: [HttpHeaderEntryInput!]! +""" +Data for testing a webhook action. +""" + bodyTemplate: String! +""" +Data for testing a webhook action. +""" + ignoreSSL: Boolean! +""" +Data for testing a webhook action. +""" + useProxy: Boolean! +""" +Data for testing a webhook action. +""" + triggerName: String! +""" +Data for testing a webhook action. +""" + eventData: String! +} + +input TimeIntervalInput { + start: String! + end: String! +} + +input TokenInput { + token: String! +} + +""" +Data for updating token security policies +""" +input TokenSecurityPoliciesInput { +""" +Data for updating token security policies +""" + personalUserTokensEnabled: Boolean! +""" +Data for updating token security policies +""" + personalUserTokensEnforceExpirationAfterMs: Long +""" +Data for updating token security policies +""" + personalUserTokensEnforceIpFilterId: String +""" +Data for updating token security policies +""" + viewPermissionTokensEnabled: Boolean! +""" +Data for updating token security policies +""" + viewPermissionTokensEnforceExpirationAfterMs: Long +""" +Data for updating token security policies +""" + viewPermissionTokensEnforceIpFilterId: String +""" +Data for updating token security policies +""" + viewPermissionTokensAllowPermissionUpdates: Boolean! +""" +Data for updating token security policies +""" + organizationPermissionTokensEnabled: Boolean! +""" +Data for updating token security policies +""" + organizationPermissionTokensEnforceExpirationAfterMs: Long +""" +Data for updating token security policies +""" + organizationPermissionTokensEnforceIpFilterId: String +""" +Data for updating token security policies +""" + organizationPermissionTokensAllowPermissionUpdates: Boolean! +""" +Data for updating token security policies +""" + systemPermissionTokensEnabled: Boolean +""" +Data for updating token security policies +""" + systemPermissionTokensEnforceExpirationAfterMs: Long +""" +Data for updating token security policies +""" + systemPermissionTokensEnforceIpFilterId: String +""" +Data for updating token security policies +""" + systemPermissionTokensAllowPermissionUpdates: Boolean +} + +""" +Represents information about an on-going trial of LogScale. +""" +type TrialLicense implements License{ +""" +The time at which the trial ends. +""" + expiresAt: DateTime! +""" +The time at which the trial started. +""" + issuedAt: DateTime! +} + +""" +Data for trigger polling an ingest feed +""" +input TriggerPollIngestFeed { +""" +Data for trigger polling an ingest feed +""" + repositoryName: RepoOrViewName! +""" +Data for trigger polling an ingest feed +""" + id: String! +} + +type UnassignIngestTokenMutation { + repository: Repository! +} + +input UnassignOrganizationManagementRoleFromGroupInput { + groupId: String! + roleId: String! + organizationIds: [String!]! +} + +type UnassignOrganizationRoleFromGroup { + group: Group! +} + +type UnassignRoleFromGroup { + group: Group! +} + +type UnassignSystemRoleFromGroup { + group: Group! +} + +type UnblockIngestMutation { + repository: Repository! +} + +""" +A widget that represents an unknown widget type. +""" +type UnknownWidget implements Widget{ + id: String! + title: String! + description: String + x: Int! + y: Int! + width: Int! + height: Int! +} + +type Unlimited implements contractual{ + includeUsage: Boolean! +} + +type UnregisterNodeMutation { + cluster: Cluster! +} + +input UnsetDynamicConfigInputObject { + config: DynamicConfig! +} + +""" +Data for updating an aggregate alert. +""" +input UpdateAggregateAlert { +""" +Data for updating an aggregate alert. +""" + viewName: RepoOrViewName! +""" +Data for updating an aggregate alert. +""" + id: String! +""" +Data for updating an aggregate alert. +""" + name: String! +""" +Data for updating an aggregate alert. +""" + description: String +""" +Data for updating an aggregate alert. +""" + queryString: String! +""" +Data for updating an aggregate alert. +""" + actionIdsOrNames: [String!]! +""" +Data for updating an aggregate alert. +""" + labels: [String!]! +""" +Data for updating an aggregate alert. +""" + enabled: Boolean! +""" +Data for updating an aggregate alert. +""" + throttleTimeSeconds: Long! +""" +Data for updating an aggregate alert. +""" + throttleField: String +""" +Data for updating an aggregate alert. +""" + searchIntervalSeconds: Long! +""" +Data for updating an aggregate alert. +""" + queryTimestampType: QueryTimestampType! +""" +Data for updating an aggregate alert. +""" + triggerMode: TriggerMode! +""" +Data for updating an aggregate alert. +""" + runAsUserId: String +""" +Data for updating an aggregate alert. +""" + queryOwnershipType: QueryOwnershipType! +} + +""" +Data for updating an alert +""" +input UpdateAlert { +""" +Data for updating an alert +""" + viewName: String! +""" +Data for updating an alert +""" + id: String! +""" +Data for updating an alert +""" + name: String! +""" +Data for updating an alert +""" + description: String +""" +Data for updating an alert +""" + queryString: String! +""" +Data for updating an alert +""" + queryStart: String! +""" +Data for updating an alert +""" + throttleTimeMillis: Long! +""" +Data for updating an alert +""" + throttleField: String +""" +Data for updating an alert +""" + runAsUserId: String +""" +Data for updating an alert +""" + enabled: Boolean! +""" +Data for updating an alert +""" + actions: [String!]! +""" +Data for updating an alert +""" + labels: [String!]! +""" +Data for updating an alert +""" + queryOwnershipType: QueryOwnershipType +} + +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" +input UpdateAwsS3SqsIngestFeed { +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + repositoryName: RepoOrViewName! +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + id: String! +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + name: String +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + description: UpdateIngestFeedDescription +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + parser: String +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + authentication: IngestFeedAwsAuthenticationInput +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + sqsUrl: String +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + region: String +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + enabled: Boolean +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + preprocessing: IngestFeedPreprocessingInput +""" +Data for updating an ingest feed which uses AWS S3 with SQS. The update is a delta update. +""" + compression: IngestFeedCompression +} + +input UpdateCustomLinkInteractionInput { + path: String! + interactionId: String! + customLinkInteractionInput: CustomLinkInteractionInput! +} + +input UpdateDashboardInput { + id: String! + name: String + labels: [String!] + widgets: [WidgetInput!] + sections: [SectionInput!] + links: [LinkInput!] + defaultFilterId: String + filters: [FilterInput!] + parameters: [ParameterInput!] + description: String + timeJumpSizeInMs: Int + updateFrequency: DashboardUpdateFrequencyInput + defaultSharedTimeStart: String + defaultSharedTimeEnd: String + defaultSharedTimeEnabled: Boolean +} + +input UpdateDashboardLinkInteractionInput { + path: String! + interactionId: String! + dashboardLinkInteractionInput: DashboardLinkInteractionInput! +} + +type UpdateDashboardMutation { + dashboard: Dashboard! +} + +input UpdateDefaultQueryPrefixInput { + queryPrefix: String + groupId: String! +} + +type UpdateDefaultQueryPrefixMutation { + group: Group! +} + +input UpdateDefaultRoleInput { + roleId: String + groupId: String! +} + +""" +Type for updating the description. If the description should be cleared, supply an `UpdateDescription` object with no value or a `null` value. If the description should be changed, supply an `UpdateDescription`object with the desired value. +""" +input UpdateDescription { +""" +Type for updating the description. If the description should be cleared, supply an `UpdateDescription` object with no value or a `null` value. If the description should be changed, supply an `UpdateDescription`object with the desired value. +""" + value: String +} + +type UpdateDescriptionMutation { + description: String! +} + +""" +Data for updating an email action. +""" +input UpdateEmailAction { +""" +Data for updating an email action. +""" + viewName: String! +""" +Data for updating an email action. +""" + id: String! +""" +Data for updating an email action. +""" + name: String! +""" +Data for updating an email action. +""" + recipients: [String!]! +""" +Data for updating an email action. +""" + subjectTemplate: String +""" +Data for updating an email action. +""" + bodyTemplate: String +""" +Data for updating an email action. +""" + useProxy: Boolean! +""" +Data for updating an email action. +""" + attachCsv: Boolean +} + +""" +Data for updating an event forwarding rule +""" +input UpdateEventForwardingRule { +""" +Data for updating an event forwarding rule +""" + repoName: String! +""" +Data for updating an event forwarding rule +""" + id: String! +""" +Data for updating an event forwarding rule +""" + queryString: String! +""" +Data for updating an event forwarding rule +""" + eventForwarderId: String! +""" +Data for updating an event forwarding rule +""" + languageVersion: LanguageVersionEnum +} + +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" +input UpdateFdrFeed { +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + repositoryName: String! +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + id: String! +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + name: String +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + description: UpdateDescription +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + parser: String +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + clientId: String +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + clientSecret: String +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + sqsUrl: String +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + s3Identifier: String +""" +Data for updating an FDR feed. Note that the fields, apart from `id` and `repositoryName`, only need to be supplied if the field should be changed. +""" + enabled: Boolean +} + +""" +Data for updating the administrator control of an FDR feed. +""" +input UpdateFdrFeedControl { +""" +Data for updating the administrator control of an FDR feed. +""" + repositoryName: String! +""" +Data for updating the administrator control of an FDR feed. +""" + id: String! +""" +Data for updating the administrator control of an FDR feed. +""" + maxNodes: UpdateLong +""" +Data for updating the administrator control of an FDR feed. +""" + fileDownloadParallelism: UpdateLong +} + +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" +input UpdateFieldAliasMappingInput { +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" + schemaId: String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" + aliasMappingId: String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" + name: String +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" + tags: [TagsInput!] +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" + aliases: [AliasInfoInput!] +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasMapping +""" + originalFieldsToKeep: [String!] +} + +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasSchema +""" +input UpdateFieldAliasSchemaInput { +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasSchema +""" + id: String! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasSchema +""" + name: String +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasSchema +""" + fields: [SchemaFieldInput!] +""" +[PREVIEW: This functionality is still under development and can change without warning.] Input object for field updateFieldAliasSchema +""" + aliasMappings: [AliasMappingInput!] +} + +""" +Data for updating a filter alert +""" +input UpdateFilterAlert { +""" +Data for updating a filter alert +""" + viewName: RepoOrViewName! +""" +Data for updating a filter alert +""" + id: String! +""" +Data for updating a filter alert +""" + name: String! +""" +Data for updating a filter alert +""" + description: String +""" +Data for updating a filter alert +""" + queryString: String! +""" +Data for updating a filter alert +""" + actionIdsOrNames: [String!]! +""" +Data for updating a filter alert +""" + labels: [String!]! +""" +Data for updating a filter alert +""" + enabled: Boolean! +""" +Data for updating a filter alert +""" + throttleTimeSeconds: Long +""" +Data for updating a filter alert +""" + throttleField: String +""" +Data for updating a filter alert +""" + runAsUserId: String +""" +Data for updating a filter alert +""" + queryOwnershipType: QueryOwnershipType! +} + +input UpdateGroupInput { + groupId: String! + displayName: String + lookupName: String +} + +type UpdateGroupMutation { + group: Group! +} + +""" +Data for updating a LogScale repository action. +""" +input UpdateHumioRepoAction { +""" +Data for updating a LogScale repository action. +""" + viewName: String! +""" +Data for updating a LogScale repository action. +""" + id: String! +""" +Data for updating a LogScale repository action. +""" + name: String! +""" +Data for updating a LogScale repository action. +""" + ingestToken: String! +} + +""" +Type for updating the description. If the description should be cleared, supply an `UpdateDescription` object with no value or a `null` value. If the description should be changed, supply an `UpdateDescription`object with the desired value. +""" +input UpdateIngestFeedDescription { +""" +Type for updating the description. If the description should be cleared, supply an `UpdateDescription` object with no value or a `null` value. If the description should be changed, supply an `UpdateDescription`object with the desired value. +""" + description: String +} + +""" +Input data to update an ingest listener +""" +input UpdateIngestListenerV3Input { +""" +Input data to update an ingest listener +""" + id: String! +""" +Input data to update an ingest listener +""" + repositoryName: String! +""" +Input data to update an ingest listener +""" + port: Int! +""" +Input data to update an ingest listener +""" + protocol: IngestListenerProtocol! +""" +Input data to update an ingest listener +""" + vHost: Int +""" +Input data to update an ingest listener +""" + name: String! +""" +Input data to update an ingest listener +""" + bindInterface: String! +""" +Input data to update an ingest listener +""" + parser: String! +""" +Input data to update an ingest listener +""" + charset: String! +} + +""" +Data for updating a Kafka event forwarder +""" +input UpdateKafkaEventForwarder { +""" +Data for updating a Kafka event forwarder +""" + id: String! +""" +Data for updating a Kafka event forwarder +""" + name: String! +""" +Data for updating a Kafka event forwarder +""" + description: String! +""" +Data for updating a Kafka event forwarder +""" + properties: String! +""" +Data for updating a Kafka event forwarder +""" + topic: String! +""" +Data for updating a Kafka event forwarder +""" + enabled: Boolean +} + +input UpdateLimitInput { + limitName: String! + allowLogin: Boolean + dailyIngest: Long + retention: Int + allowSelfService: Boolean + expiration: Long + contractVersion: Organizations__ContractVersion + userLimit: Int +} + +input UpdateLimitInputV2 { + id: String! + name: String + allowLogin: Boolean + dailyIngest: Long + dailyIngestContractualType: Organizations__ContractualType + storageContractualType: Organizations__ContractualType + dailyScanContractualType: Organizations__ContractualType + measurementType: Organizations__MeasurementType + dailyScan: Long + retention: Int + maxRetention: Int + allowSelfService: Boolean + expiration: Long + userLimit: Int + dateType: String + trial: Boolean + allowFlightControl: Boolean + repositoryLimit: Int +} + +""" +Data for updating a local cluster connection +""" +input UpdateLocalClusterConnectionInput { +""" +Data for updating a local cluster connection +""" + multiClusterViewName: String! +""" +Data for updating a local cluster connection +""" + connectionId: String! +""" +Data for updating a local cluster connection +""" + targetViewName: String +""" +Data for updating a local cluster connection +""" + tags: [ClusterConnectionInputTag!] +""" +Data for updating a local cluster connection +""" + queryPrefix: String +} + +""" +If the value should be cleared, supply an `UpdateLong` object the with no value or a `null` value. If the setting should be changed, supply a `UpdateLong` object with the desired value. +""" +input UpdateLong { +""" +If the value should be cleared, supply an `UpdateLong` object the with no value or a `null` value. If the setting should be changed, supply a `UpdateLong` object with the desired value. +""" + value: Int +} + +input UpdateOidcConfigurationInput { + id: String! + name: String! + clientID: String! + clientSecret: String! + issuer: String! + tokenEndpointAuthMethod: String! + authorizationEndpoint: String! + tokenEndpoint: String + userInfoEndpoint: String + registrationEndpoint: String + groupsClaim: String + JWKSEndpoint: String + domains: [String!]! + scopes: [String!]! + userClaim: String! + enableDebug: Boolean! + defaultIdp: Boolean + humioOwned: Boolean + lazyCreateUsers: Boolean + federatedIdp: String + scopeClaim: String +} + +""" +Data for updating an OpsGenie action +""" +input UpdateOpsGenieAction { +""" +Data for updating an OpsGenie action +""" + viewName: String! +""" +Data for updating an OpsGenie action +""" + id: String! +""" +Data for updating an OpsGenie action +""" + name: String! +""" +Data for updating an OpsGenie action +""" + apiUrl: String! +""" +Data for updating an OpsGenie action +""" + genieKey: String! +""" +Data for updating an OpsGenie action +""" + useProxy: Boolean! +} + +input UpdateOrganizationPermissionsTokenPermissionsInput { + id: String! + permissions: [OrganizationPermission!]! +} + +input UpdatePackageFromRegistryInput { + viewName: RepoOrViewName! + packageId: VersionedPackageSpecifier! + conflictResolutions: [ConflictResolutionConfiguration!]! + queryOwnershipType: QueryOwnershipType +} + +""" +Data for updating a PagerDuty action +""" +input UpdatePagerDutyAction { +""" +Data for updating a PagerDuty action +""" + viewName: String! +""" +Data for updating a PagerDuty action +""" + id: String! +""" +Data for updating a PagerDuty action +""" + name: String! +""" +Data for updating a PagerDuty action +""" + severity: String! +""" +Data for updating a PagerDuty action +""" + routingKey: String! +""" +Data for updating a PagerDuty action +""" + useProxy: Boolean! +} + +input UpdateParametersInteractionInput { + name: String! + titleTemplate: String + arguments: [ArgumentInput!]! + useWidgetTimeWindow: Boolean! + fieldInteractionConditions: [FieldInteractionConditionInput!] +} + +""" +Input for updating a parser. +""" +input UpdateParserInput { +""" +Input for updating a parser. +""" + repositoryName: String +""" +Input for updating a parser. +""" + id: String +""" +Input for updating a parser. +""" + name: String +""" +Input for updating a parser. +""" + testData: [String!] +""" +Input for updating a parser. +""" + sourceCode: String +""" +Input for updating a parser. +""" + tagFields: [String!] +""" +Input for updating a parser. +""" + fieldsToBeRemovedBeforeParsing: [String!] +""" +Input for updating a parser. +""" + languageVersion: LanguageVersionEnum +} + +""" +Input for updating a parser. +""" +input UpdateParserInputV2 { +""" +Input for updating a parser. +""" + repositoryName: RepoOrViewName! +""" +Input for updating a parser. +""" + id: String! +""" +Input for updating a parser. +""" + name: String +""" +Input for updating a parser. +""" + script: UpdateParserScriptInput +""" +Input for updating a parser. +""" + testCases: [ParserTestCaseInput!] +""" +Input for updating a parser. +""" + fieldsToTag: [String!] +""" +Input for updating a parser. +""" + fieldsToBeRemovedBeforeParsing: [String!] +} + +type UpdateParserMutation { + parser: Parser! +} + +""" +Input for updating the parser script. +""" +input UpdateParserScriptInput { +""" +Input for updating the parser script. +""" + script: String! +""" +Input for updating the parser script. +""" + languageVersion: LanguageVersionInputType +} + +""" +Data for updating a post-message Slack action +""" +input UpdatePostMessageSlackAction { +""" +Data for updating a post-message Slack action +""" + viewName: String! +""" +Data for updating a post-message Slack action +""" + id: String! +""" +Data for updating a post-message Slack action +""" + name: String! +""" +Data for updating a post-message Slack action +""" + apiToken: String! +""" +Data for updating a post-message Slack action +""" + channels: [String!]! +""" +Data for updating a post-message Slack action +""" + fields: [SlackFieldEntryInput!]! +""" +Data for updating a post-message Slack action +""" + useProxy: Boolean! +} + +input UpdateQueryPrefixInput { + queryPrefix: String! + viewId: String! + groupId: String! +} + +type UpdateQueryPrefixMutation { + group: Group! +} + +""" +Data for updating a remote cluster connection +""" +input UpdateRemoteClusterConnectionInput { +""" +Data for updating a remote cluster connection +""" + multiClusterViewName: String! +""" +Data for updating a remote cluster connection +""" + connectionId: String! +""" +Data for updating a remote cluster connection +""" + publicUrl: String +""" +Data for updating a remote cluster connection +""" + token: String +""" +Data for updating a remote cluster connection +""" + tags: [ClusterConnectionInputTag!] +""" +Data for updating a remote cluster connection +""" + queryPrefix: String +} + +input UpdateRepoDataTypeInputObject { + dataspaceId: String! + repoDataType: RepositoryDataType! +} + +input UpdateRepoLimitIdInputObject { + dataspaceId: String! + limitId: String! +} + +type UpdateRetentionMutation { + repository: SearchDomain! +} + +input UpdateRoleInput { + roleId: String! + displayName: String! + viewPermissions: [Permission!]! + description: String + color: String + systemPermissions: [SystemPermission!] + organizationPermissions: [OrganizationPermission!] + objectAction: ObjectAction + organizationManagementPermissions: [OrganizationManagementPermission!] +} + +type UpdateRoleMutation { + role: Role! +} + +input UpdateSavedQueryInput { + id: String! + name: String + viewName: String! + queryString: String + start: String + end: String + isLive: Boolean + widgetType: String + options: String + dashboardLinkInteractions: [DashboardLinkInteractionInput!] + customLinkInteractions: [CustomLinkInteractionInput!] + searchLinkInteractions: [SearchLinkInteractionInput!] + updateParametersInteractions: [UpdateParametersInteractionInput!] +} + +type UpdateSavedQueryPayload { + savedQuery: SavedQuery! +} + +""" +Data for updating a scheduled report. +""" +input UpdateScheduledReportInput { +""" +Data for updating a scheduled report. +""" + viewName: String! +""" +Data for updating a scheduled report. +""" + id: String! +""" +Data for updating a scheduled report. +""" + name: String +""" +Data for updating a scheduled report. +""" + password: String +""" +Data for updating a scheduled report. +""" + enabled: Boolean +""" +Data for updating a scheduled report. +""" + description: String +""" +Data for updating a scheduled report. +""" + dashboardId: String +""" +Data for updating a scheduled report. +""" + timeIntervalFrom: String +""" +Data for updating a scheduled report. +""" + schedule: UpdateScheduledReportScheduleInput +""" +Data for updating a scheduled report. +""" + labels: [String!] +""" +Data for updating a scheduled report. +""" + parameters: [UpdateScheduledReportParameterValueInput!] +""" +Data for updating a scheduled report. +""" + recipients: [String!] +""" +Data for updating a scheduled report. +""" + layout: UpdateScheduledReportLayoutInput +} + +""" +Layout of the scheduled report. +""" +input UpdateScheduledReportLayoutInput { +""" +Layout of the scheduled report. +""" + paperSize: String +""" +Layout of the scheduled report. +""" + paperOrientation: String +""" +Layout of the scheduled report. +""" + paperLayout: String +""" +Layout of the scheduled report. +""" + showDescription: Boolean +""" +Layout of the scheduled report. +""" + showTitleFrontpage: Boolean +""" +Layout of the scheduled report. +""" + showParameters: Boolean +""" +Layout of the scheduled report. +""" + maxNumberOfRows: Int +""" +Layout of the scheduled report. +""" + showTitleHeader: Boolean +""" +Layout of the scheduled report. +""" + showExportDate: Boolean +""" +Layout of the scheduled report. +""" + footerShowPageNumbers: Boolean +} + +""" +List of parameter value configurations. +""" +input UpdateScheduledReportParameterValueInput { +""" +List of parameter value configurations. +""" + id: String! +""" +List of parameter value configurations. +""" + value: String! +} + +""" +The schedule to run the report by. +""" +input UpdateScheduledReportScheduleInput { +""" +The schedule to run the report by. +""" + cronExpression: String! +""" +The schedule to run the report by. +""" + timeZone: String! +""" +The schedule to run the report by. +""" + startDate: Long! +""" +The schedule to run the report by. +""" + endDate: Long +} + +""" +Data for updating a scheduled search +""" +input UpdateScheduledSearch { +""" +Data for updating a scheduled search +""" + viewName: String! +""" +Data for updating a scheduled search +""" + id: String! +""" +Data for updating a scheduled search +""" + name: String! +""" +Data for updating a scheduled search +""" + description: String +""" +Data for updating a scheduled search +""" + queryString: String! +""" +Data for updating a scheduled search +""" + queryStart: String! +""" +Data for updating a scheduled search +""" + queryEnd: String! +""" +Data for updating a scheduled search +""" + schedule: String! +""" +Data for updating a scheduled search +""" + timeZone: String! +""" +Data for updating a scheduled search +""" + backfillLimit: Int! +""" +Data for updating a scheduled search +""" + enabled: Boolean! +""" +Data for updating a scheduled search +""" + actions: [String!]! +""" +Data for updating a scheduled search +""" + labels: [String!]! +""" +Data for updating a scheduled search +""" + runAsUserId: String +""" +Data for updating a scheduled search +""" + queryOwnershipType: QueryOwnershipType +} + +input UpdateSearchLinkInteractionInput { + path: String! + interactionId: String! + searchLinkInteractionInput: SearchLinkInteractionInput! +} + +""" +Data for updating a Slack action +""" +input UpdateSlackAction { +""" +Data for updating a Slack action +""" + viewName: String! +""" +Data for updating a Slack action +""" + id: String! +""" +Data for updating a Slack action +""" + name: String! +""" +Data for updating a Slack action +""" + url: String! +""" +Data for updating a Slack action +""" + fields: [SlackFieldEntryInput!]! +""" +Data for updating a Slack action +""" + useProxy: Boolean! +} + +input UpdateSubscriptionInputObject { + subscription: Organizations__Subscription! + trialDays: Int +} + +input UpdateSystemPermissionsTokenPermissionsInput { + id: String! + permissions: [SystemPermission!]! +} + +""" +Data for updating an upload file action. +""" +input UpdateUploadFileAction { +""" +Data for updating an upload file action. +""" + viewName: String! +""" +Data for updating an upload file action. +""" + id: String! +""" +Data for updating an upload file action. +""" + name: String! +""" +Data for updating an upload file action. +""" + fileName: String! +} + +input UpdateUserByIdInput { + userId: String! + company: String + isRoot: Boolean + username: String + firstName: String + lastName: String + fullName: String + picture: String + email: String + countryCode: String + stateCode: String +} + +type UpdateUserByIdMutation { + user: User! +} + +type UpdateUserMutation { + user: User! +} + +""" +Data for updating a VictorOps action. +""" +input UpdateVictorOpsAction { +""" +Data for updating a VictorOps action. +""" + viewName: String! +""" +Data for updating a VictorOps action. +""" + id: String! +""" +Data for updating a VictorOps action. +""" + name: String! +""" +Data for updating a VictorOps action. +""" + messageType: String! +""" +Data for updating a VictorOps action. +""" + notifyUrl: String! +""" +Data for updating a VictorOps action. +""" + useProxy: Boolean! +} + +input UpdateViewPermissionsTokenPermissionsInput { + id: String! + permissions: [Permission!]! +} + +""" +Data for updating a webhook action +""" +input UpdateWebhookAction { +""" +Data for updating a webhook action +""" + viewName: String! +""" +Data for updating a webhook action +""" + id: String! +""" +Data for updating a webhook action +""" + name: String! +""" +Data for updating a webhook action +""" + url: String! +""" +Data for updating a webhook action +""" + method: String! +""" +Data for updating a webhook action +""" + headers: [HttpHeaderEntryInput!]! +""" +Data for updating a webhook action +""" + bodyTemplate: String! +""" +Data for updating a webhook action +""" + ignoreSSL: Boolean! +""" +Data for updating a webhook action +""" + useProxy: Boolean! +} + +input UpgradeAccountData { + lastName: String! + company: String! + email: String! + firstName: String + purpose: Purposes + phoneNumber: String + countryCode: String + stateCode: String + comment: String +} + +""" +An upload file action. +""" +type UploadFileAction implements Action{ +""" +File name for the uploaded file. +""" + fileName: String! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +input UserDefaultSettingsInput { + defaultTimeZone: String +} + +""" +Query running with user based ownership +""" +type UserOwnership implements QueryOwnership{ +""" +User owning and running the query. If null, then the user doesn't exist anymore. +""" + user: User +""" +Id of user owning and running the query +""" + id: String! +} + +input UserRoleAssignment { + userId: String! + roleId: String! +} + +input UserRoleAssignmentInput { + userId: String! + roleIds: [String!]! +} + +""" +Username and password authentication. The underlying authentication mechanism is configured by the server, e.g. LDAP. +""" +type UsernameAndPasswordAuthentication implements AuthenticationMethod{ + name: String! +} + +input UtmParams { + campaign: String! + content: String! + medium: String! + source: String! + term: String! +} + +""" +A VictorOps action. +""" +type VictorOpsAction implements Action{ +""" +Type of the VictorOps message to make. +""" + messageType: String! +""" +VictorOps webhook url to send the request to. +""" + notifyUrl: String! +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +The repositories this view will read from. +""" +input ViewConnectionInput { +""" +The repositories this view will read from. +""" + repositoryName: String! +""" +The repositories this view will read from. +""" + filter: String! +""" +The repositories this view will read from. +""" + languageVersion: LanguageVersionEnum +} + +""" +View permissions token. The token allows the caller to work with the same set of view-level permissions across multiple views. +""" +type ViewPermissionsToken implements Token{ +""" +The set of permissions on the token +""" + permissions: [String!]! +""" +The set of views on the token. Will only list the views the user has access to. +""" + views: [SearchDomain!]! +""" +The id of the token. +""" + id: String! +""" +The name of the token. +""" + name: String! +""" +The time at which the token expires. +""" + expireAt: Long +""" +The ip filter on the token. +""" + ipFilter: String +""" +The ip filter on the token. +""" + ipFilterV2: IPFilter +""" +The date the token was created. +""" + createdAt: Long! +} + +""" +A webhook action +""" +type WebhookAction implements Action{ +""" +Method to use for the request. +""" + method: String! +""" +Url to send the http(s) request to. +""" + url: String! +""" +Headers of the http(s) request. +""" + headers: [HttpHeaderEntry!]! +""" +Body of the http(s) request. Can be templated with values from the result. +""" + bodyTemplate: String! +""" +Flag indicating whether SSL should be ignored for the request. +""" + ignoreSSL: Boolean! +""" +Defines whether the action should use the configured proxy to make web requests. +""" + useProxy: Boolean! +""" +The name of the action. +""" + name: String! +""" +The display name of the action. +""" + displayName: String! +""" +The id of the action. +""" + id: String! +""" +A template that can be used to recreate the action. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier +""" +The package if any which the action is part of. +""" + package: PackageInstallation +""" +False if this type of action is disabled because of a security policy, true otherwise +""" + isAllowedToRun: Boolean! +""" +True if this action is used by triggers, where the query is run by the organization. If true, then the OrganizationOwnedQueries permission is required to edit the action. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +input WidgetInput { + id: String! + title: String! + description: String + x: Int! + y: Int! + width: Int! + height: Int! + queryOptions: WidgetQueryPropertiesInput + noteOptions: WidgetNotePropertiesInput + linkOptions: WidgetLinkPropertiesInput + parameterPanelOptions: WidgetParameterPanelPropertiesInput +} + +input WidgetLinkPropertiesInput { + labels: [String!]! +} + +input WidgetNotePropertiesInput { + text: String! + backgroundColor: String + textColor: String +} + +input WidgetParameterPanelPropertiesInput { + parameterIds: [String!]! +} + +input WidgetQueryPropertiesInput { + queryString: String! + start: String! + end: String! + widgetType: String! + options: String + dashboardLinkInteractions: [DashboardLinkInteractionInput!] + customLinkInteractions: [CustomLinkInteractionInput!] + searchLinkInteractions: [SearchLinkInteractionInput!] + updateParametersInteractions: [UpdateParametersInteractionInput!] +} + +""" +The input required to delete an external function specification. +""" +input deleteExternalFunctionInput { +""" +The input required to delete an external function specification. +""" + name: String! +} + +""" +FDR test errors +""" +union error =TestFdrValidationError | TestFdrRequestError + +type setAutomaticSearching { + automaticSearch: Boolean! +} + +type updateDefaultRoleMutation { + group: Group! +} + +""" +A user or pending user, depending on whether an invitation was sent +""" +union userOrPendingUser =User | PendingUser + +type AccessTokenValidatorResultType { + sessionId: String + showTermsAndConditions: ShowTermsAndConditions +} + +""" +A user account. +""" +type Account { + id: String! + enabledFeaturesForAccount: [FeatureFlag!]! + username: String! + isRoot: Boolean! + isOrganizationRoot: Boolean! + fullName: String + firstName: String + lastName: String + phoneNumber: String + email: String + picture: String + settings: UserSettings! + createdAt: DateTime! + countryCode: String + stateCode: String + company: String + canCreateCloudTrialRepo: Boolean! + isCloudProAccount: Boolean! + canCreateRepo: Boolean! + externalPermissions: Boolean! + externalGroupSynchronization: Boolean! + currentOrganization: Organization! + announcement: Notification +""" +[PREVIEW: New sorting and filtering options might be added.] +""" + notificationsV2( + typeFilter: [NotificationTypes!] +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): NotificationsResultSet! + token: PersonalUserToken + fieldConfigurations( + viewName: String! + ): [FieldConfiguration!]! +} + +""" +An action that can be invoked from a trigger. +""" +interface Action { +""" +An action that can be invoked from a trigger. +""" + name: String! +""" +An action that can be invoked from a trigger. +""" + displayName: String! +""" +An action that can be invoked from a trigger. +""" + id: String! +""" +An action that can be invoked from a trigger. +""" + yamlTemplate: YAML! +""" +An action that can be invoked from a trigger. +""" + packageId: VersionedPackageSpecifier +""" +An action that can be invoked from a trigger. +""" + package: PackageInstallation +""" +An action that can be invoked from a trigger. +""" + isAllowedToRun: Boolean! +""" +An action that can be invoked from a trigger. +""" + requiresOrganizationOwnedQueriesPermissionToEdit: Boolean! +""" +An action that can be invoked from a trigger. +""" + allowedActions: [AssetAction!]! +} + +""" +Security policies for actions in the organization +""" +type ActionSecurityPolicies { +""" +Indicates if email actions can be configured and triggered +""" + emailActionEnabled: Boolean! +""" +Allow list of glob patterns for acceptable email action recipients. Empty means no recipients allowed whereas null means all. +""" + emailActionRecipientAllowList: [String!] +""" +Indicates if repository actions can be configured and triggered +""" + repoActionEnabled: Boolean! +""" +Indicates if OpsGenie actions can be configured and triggered +""" + opsGenieActionEnabled: Boolean! +""" +Indicates if PagerDuty actions can be configured and triggered +""" + pagerDutyActionEnabled: Boolean! +""" +Indicates if single channel Slack actions can be configured and triggered +""" + slackSingleChannelActionEnabled: Boolean! +""" +Indicates if multi channel Slack actions can be configured and triggered +""" + slackMultiChannelActionEnabled: Boolean! +""" +Indicates if upload file actions can be configured and triggered +""" + uploadFileActionEnabled: Boolean! +""" +Indicates if VictorOps actions can be configured and triggered +""" + victorOpsActionEnabled: Boolean! +""" +Indicates if Webhook actions can be configured and triggered +""" + webhookActionEnabled: Boolean! +""" +Allow list of glob patterns for acceptable webhook URLs. Empty means no recipients allowed whereas null means all. +""" + webhookActionUrlAllowList: [String!] +} + +type ActionTemplate { + name: String! + displayName: String! + yamlTemplate: String! +""" +The type of action +""" + type: ActionType! +} + +""" +The type of action this template is for +""" +enum ActionType { + Email + LogScaleRepository + OpsGenie + PagerDuty + SlackMulti + SlackSingle + UploadFile + VictorOps + Webhook +} + +type ActiveSchemaOnView { + viewName: RepoOrViewName! + schemaId: String! + is1to1Linked: Boolean! +} + +""" +An aggregate alert. +""" +type AggregateAlert { +""" +Id of the aggregate alert. +""" + id: String! +""" +Name of the aggregate alert. +""" + name: String! +""" +Description of the aggregate alert. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +List of actions to fire on query result. +""" + actions: [Action!]! +""" +Labels attached to the aggregate alert. +""" + labels: [String!]! +""" +Flag indicating whether the aggregate alert is enabled. +""" + enabled: Boolean! +""" +Throttle time in seconds. +""" + throttleTimeSeconds: Long! +""" +A field to throttle on. Can only be set if throttleTimeSeconds is set. +""" + throttleField: String +""" +Search interval in seconds. +""" + searchIntervalSeconds: Long! +""" +Timestamp type to use for a query. +""" + queryTimestampType: QueryTimestampType! +""" +Trigger mode used for triggering the alert. +""" + triggerMode: TriggerMode! +""" +Unix timestamp for last execution of trigger. +""" + lastTriggered: Long +""" +Unix timestamp for last successful poll (including action invocation if applicable) of the aggregate alert query. If this is not quite recent, then the alert might be having problems. +""" + lastSuccessfulPoll: Long +""" +Last error encountered while running the aggregate alert. +""" + lastError: String +""" +Last warnings encountered while running the aggregate alert. +""" + lastWarnings: [String!]! +""" +YAML specification of the aggregate alert. +""" + yamlTemplate: YAML! +""" +The id of the package of the aggregate alert template. +""" + packageId: VersionedPackageSpecifier +""" +The package that the aggregate alert was installed as part of. +""" + package: PackageInstallation +""" +Ownership of the query run by this alert +""" + queryOwnership: QueryOwnership! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +type AggregateAlertTemplate { + name: String! + displayName: String! + yamlTemplate: YAML! + labels: [String!]! +} + +""" +An alert. +""" +type Alert { +""" +Id of the alert. +""" + id: String! +""" +Name of the alert. +""" + name: String! + assetType: AssetType! +""" +Id of user which the alert is running as. +""" + runAsUser: User +""" +Name of the alert. +""" + displayName: String! +""" +Name of the alert. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +Start of the relative time interval for the query. +""" + queryStart: String! +""" +Throttle time in milliseconds. +""" + throttleTimeMillis: Long! +""" +Field to throttle on. +""" + throttleField: String +""" +Unix timestamp for when the alert was last triggered. +""" + timeOfLastTrigger: Long +""" +Flag indicating whether the alert is enabled. +""" + enabled: Boolean! +""" +List of ids for actions to fire on query result. +""" + actions: [String!]! +""" +List of ids for actions to fire on query result. +""" + actionsV2: [Action!]! +""" +Last error encountered while running the alert. +""" + lastError: String +""" +Last warnings encountered while running the alert. +""" + lastWarnings: [String!]! +""" +Labels attached to the alert. +""" + labels: [String!]! +""" +Flag indicating whether the calling user has 'starred' the alert. +""" + isStarred: Boolean! +""" +A YAML formatted string that describes the alert. +""" + yamlTemplate: String! +""" +The id of the package that the alert was installed as part of. +""" + packageId: VersionedPackageSpecifier +""" +The package that the alert was installed as part of. +""" + package: PackageInstallation +""" +Ownership of the query run by this alert +""" + queryOwnership: QueryOwnership! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +All actions, labels and packages used in alerts. +""" +type AlertFieldValues { +""" +List of names of actions attached to alerts. Sorted by action names lexicographically.. +""" + actionNames: [String!]! +""" +List of labels attached to alerts. Sorted by label names lexicographically. +""" + labels: [String!]! +""" +List of packages for installed alerts as unversioned qualified package specifiers `scope/packageName`. Sorted lexicographically. +""" + unversionedPackageSpecifiers: [String!]! +} + +""" +Arguments for alert field values query. +""" +input AlertFieldValuesInput { +""" +Arguments for alert field values query. +""" + viewName: RepoOrViewName! +} + +type AlertTemplate { + name: String! + displayName: String! + yamlTemplate: String! + labels: [String!]! +} + +""" +The different types of alerts known to the system. +""" +enum AlertType { + LegacyAlert + FilterAlert + AggregateAlert +} + +type AliasInfo { + source: String! + alias: String! +} + +type AliasMapping { + id: String! + name: String! + tags: [TagInfo!]! + aliases: [AliasInfo!]! + originalFieldsToKeep: [String!]! +} + +""" +Arguments for analyzeQuery +""" +input AnalyzeQueryArguments { +""" +Arguments for analyzeQuery +""" + queryString: String! +""" +Arguments for analyzeQuery +""" + version: LanguageVersionInputType! +""" +Arguments for analyzeQuery +""" + isLive: Boolean +""" +Arguments for analyzeQuery +""" + arguments: [QueryArgumentInputType!] +""" +Arguments for analyzeQuery +""" + viewName: RepoOrViewName +} + +""" +Result of analyzing a query. +""" +type AnalyzeQueryInfo { +""" +Check if the given query contains any errors or warnings when used in a standard search context. +""" + validateQuery: QueryValidationInfo! +""" +Suggested type of alert to use for the given query. +Returns null if no suitable alert type could be suggested. +The given query is not guaranteed to be valid for the suggested alert type. + +""" + suggestedAlertType: SuggestedAlertTypeInfo +} + +""" +Allowed asset action on asset +""" +enum AssetAction { + Read + Update + Delete +} + +""" +Asset permissions +""" +enum AssetPermissionInputEnum { + UpdateAsset + DeleteAsset +} + +""" +Asset permission +""" +enum AssetPermissionOutputEnum { + ReadAsset + UpdateAsset + DeleteAsset +} + +""" +An asset permission search result set +""" +type AssetPermissionSearchResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [SearchAssetPermissionsResultEntry!]! +} + +""" +The different types of assets. +""" +enum AssetPermissionsAssetType { + LegacyAlert + FilterAlert + AggregateAlert + ScheduledSearch + ScheduledReport + Action + Dashboard + File + SavedQuery +} + +""" +Asset permissions assigned to the group +""" +type AssetPermissionsForGroup { +""" +The unique id for the Asset +""" + assetId: String! +""" +The type of the Asset +""" + assetType: AssetPermissionsAssetType! +""" +The search domain that the asset belongs to +""" + searchDomain: SearchDomain +""" +The group role assignments +""" + roles: [GroupRole!]! +""" +The directly assigned asset permissions +""" + directlyAssigned: [AssetPermissionOutputEnum!]! +} + +""" +Asset permissions assigned to the user +""" +type AssetPermissionsForUser { +""" +The unique id for the Asset +""" + assetId: String! +""" +The type of the Asset +""" + assetType: AssetPermissionsAssetType! +""" +The search domain that the asset belongs to +""" + searchDomain: SearchDomain +""" +The group role assignments +""" + groupRoles: [GroupRole!]! +""" +The directly assigned asset permissions per group +""" + groupDirectlyAssigned: [GroupAssetPermissionAssignment!]! + userRoles: [Role!]! +""" +The directly assigned asset permissions +""" + directlyAssigned: [AssetPermissionOutputEnum!]! +} + +enum AssetType { + Interaction + ScheduledSearch + Action + File + AggregateAlert + FilterAlert + Alert + Parser + SavedQuery + Dashboard +} + +""" +Represents information about how users authenticate with LogScale. +""" +interface AuthenticationMethod { +""" +Represents information about how users authenticate with LogScale. +""" + name: String! +} + +interface AuthenticationMethodAuth { + authType: String! +} + +""" +A regex pattern used to filter queries before they are executed. +""" +type BlockedQuery { + id: String! + expiresAt: DateTime + expiresInMilliseconds: Int + pattern: String! + type: BlockedQueryMatcherType! + view: View +""" +The organization owning the pattern or view, if any. +""" + organization: Organization + limitedToOrganization: Boolean! +""" +True if the current actor is allowed the remove this pattern +""" + unblockAllowed: Boolean! +} + +enum BlockedQueryMatcherType { + EXACT + REGEX +} + +""" +Bucket storage configuration for the organization +""" +type BucketStorageConfig { +""" +The primary bucket storage of the organization +""" + targetBucketId1: String! +""" +The secondary bucket storage of the organization +""" + targetBucketId2: String +} + +""" +A policy for choosing which segments to cache on local disk when overcommiting +local storage with bucket storage. + +This can be used to protect certain repositories for local storage, such that +searching other repositories does not evict them. + +A cache policy in LogScale divides segments into prioritized and non-prioritized +segments. When segments needs to be evicted from local storage, we always try +evicting non-prioritized segments before prioritized segments. + +A cache policy can be set either on one of three levels (in order of precedence): + - Repo + - Org + - Globally + + When determining the cache policy for a repo we first check if there is a cache + policy set on the repo. If none is set on the repo, we check the the org. If none + is set there either we check the global setting. + +""" +type CachePolicy { +""" +Prioritize caching segments younger than this +""" + prioritizeMillis: Long +} + +enum Changes { + Removed + Added + NoChange +} + +""" +Data for checking a local cluster connection +""" +input CheckLocalClusterConnectionInput { +""" +Data for checking a local cluster connection +""" + connectionId: String +""" +Data for checking a local cluster connection +""" + targetViewName: String! +""" +Data for checking a local cluster connection +""" + tags: [ClusterConnectionInputTag!] +""" +Data for checking a local cluster connection +""" + queryPrefix: String +} + +""" +Data for checking a remote cluster connection +""" +input CheckRemoteClusterConnectionInput { +""" +Data for checking a remote cluster connection +""" + connectionId: String +""" +Data for checking a remote cluster connection +""" + multiClusterViewName: String +""" +Data for checking a remote cluster connection +""" + publicUrl: String! +""" +Data for checking a remote cluster connection +""" + token: String +""" +Data for checking a remote cluster connection +""" + tags: [ClusterConnectionInputTag!] +""" +Data for checking a remote cluster connection +""" + queryPrefix: String +} + +""" +An organization search result set +""" +type ChildOrganizationsResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [Organization!]! +} + +""" +Identifies a client of the query. +""" +type Client { + externalId: String! + ip: String + user: String +} + +""" +Information about the LogScale cluster. +""" +type Cluster { + nodes: [ClusterNode!]! + clusterManagementSettings: ClusterManagementSettings! + clusterInfoAgeSeconds: Float! + underReplicatedSegmentSize: Float! + overReplicatedSegmentSize: Float! + missingSegmentSize: Float! + properlyReplicatedSegmentSize: Float! + inBucketStorageSegmentSize: Float! + pendingBucketStorageSegmentSize: Float! + pendingBucketStorageRiskySegmentSize: Float! + targetUnderReplicatedSegmentSize: Float! + targetOverReplicatedSegmentSize: Float! + targetMissingSegmentSize: Float! + targetProperlyReplicatedSegmentSize: Float! + ingestPartitions: [IngestPartition!]! + ingestPartitionsWarnings: [String!]! + suggestedIngestPartitions: [IngestPartition!]! + storagePartitions: [StoragePartition!]! + storagePartitionsWarnings: [String!]! + suggestedStoragePartitions: [StoragePartition!]! + storageReplicationFactor: Int + digestReplicationFactor: Int + stats: ClusterStats! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] The default cache policy of this cluster. +""" + defaultCachePolicy: CachePolicy +} + +""" +A cluster connection. +""" +interface ClusterConnection { +""" +A cluster connection. +""" + id: String! +""" +A cluster connection. +""" + clusterId: String! +""" +A cluster connection. +""" + tags: [ClusterConnectionTag!]! +""" +A cluster connection. +""" + queryPrefix: String! +} + +input ClusterConnectionInputTag { + key: String! + value: String! +} + +""" +The status of a cluster connection. +""" +interface ClusterConnectionStatus { +""" +The status of a cluster connection. +""" + id: String +""" +The status of a cluster connection. +""" + isValid: Boolean! +""" +The status of a cluster connection. +""" + errorMessages: [ConnectionAspectErrorType!]! +} + +type ClusterConnectionTag { + key: String! + value: String! +} + +""" +Settings for the LogScale cluster. +""" +type ClusterManagementSettings { +""" +Replication factor for segments +""" + segmentReplicationFactor: Int! +""" +Replication factor for the digesters +""" + digestReplicationFactor: Int! +""" +Percentage of all hosts relevant to a particular cluster rebalance operation that need to be alive before we allow the system to automatically execute the operation. Cluster rebalance operations currently include reassigning digest work, and moving existing segments to balance disk usage. Value is between 0 and 100, both inclusive +""" + minHostAlivePercentageToEnableClusterRebalancing: Int! +""" +Whether or not desired digesters are allowed to be updated automatically +""" + allowUpdateDesiredDigesters: Boolean! +""" +true if the cluster should allow moving existing segments between nodes to achieve a better data distribution +""" + allowRebalanceExistingSegments: Boolean! +} + +""" +A node in the a LogScale Cluster. +""" +type ClusterNode { + id: Int! + name: String! + zone: String + uri: String! + uuid: String! + humioVersion: String! + supportedTasks: [NodeTaskEnum!]! + assignedTasks: [NodeTaskEnum!] + unassignedTasks: [NodeTaskEnum!] + consideredAliveUntil: DateTime + clusterInfoAgeSeconds: Float! +""" +The size in GB of data this node needs to receive. +""" + inboundSegmentSize: Float! +""" +The size in GB of data this node has that others need. +""" + outboundSegmentSize: Float! + canBeSafelyUnregistered: Boolean! + reasonsNodeCannotBeSafelyUnregistered: ReasonsNodeCannotBeSafelyUnregistered! +""" +The size in GB of data currently on this node. +""" + currentSize: Float! +""" +The size in GB of the data currently on this node that are in the primary storage location. +""" + primarySize: Float! +""" +The size in GB of the data currently on this node that are in the secondary storage location. Zero if no secondary is configured. +""" + secondarySize: Float! +""" +The total size in GB of the primary storage location on this node. +""" + totalSizeOfPrimary: Float! +""" +The total size in GB of the secondary storage location on this node. Zero if no secondary is configured. +""" + totalSizeOfSecondary: Float! +""" +The size in GB of the free space on this node of the primary storage location. +""" + freeOnPrimary: Float! +""" +The size in GB of the free space on this node of the secondary storage location. Zero if no secondary is configured. +""" + freeOnSecondary: Float! +""" +The size in GB of work-in-progress data files. +""" + wipSize: Float! +""" +The size in GB of data once the node has received the data allocated to it. +""" + targetSize: Float! +""" +The size in GB of data that only exists on this node - i.e. only one replica exists in the cluster. +""" + solitarySegmentSize: Float! +""" +A flag indicating whether the node is considered up or down by the cluster coordinated. This is based on the `lastHeartbeat` field. +""" + isAvailable: Boolean! +""" +The last time a heartbeat was received from the node. +""" + lastHeartbeat: DateTime! +""" +The time since a heartbeat was received from the node. +""" + timeSinceLastHeartbeat: Long! +""" +A flag indicating whether the node is marked for eviction. The Falcon LogScale cluster will start to move segments, digesters and queries away from any node marked for eviction +""" + isBeingEvicted: Boolean +""" +Contains data describing the status of eviction +""" + evictionStatus: EvictionStatus! +""" +True if the machine the node runs on has local segment storage +""" + hasStorageRole: Boolean! +""" +True if the machine the node runs on has the possibility to process kafka partitions +""" + hasDigestRole: Boolean! +""" +The time at which the host booted +""" + bootedAt: DateTime! +""" +The time since last boot +""" + timeSinceBooted: Long! +} + +""" +Global stats for the cluster +""" +type ClusterStats { + compressedByteSize: Long! + uncompressedByteSize: Long! + compressedByteSizeOfMerged: Long! + uncompressedByteSizeOfMerged: Long! +} + +""" +Arguments for concatenateQueries +""" +input ConcatenateQueriesArguments { +""" +Arguments for concatenateQueries +""" + queryStrings: [String!]! +""" +Arguments for concatenateQueries +""" + version: LanguageVersionInputType! +} + +""" +A value denoting some aspect of a cluster connection +""" +enum ConnectionAspect { + Tag + QueryPrefix + Other + TargetView + PublicUrl + Token +} + +""" +A key-value pair from a connection aspect to an error message pertaining to that aspect +""" +type ConnectionAspectErrorType { +""" +A connection aspect +""" + aspect: ConnectionAspect! +""" +An error message for the connection, tagged by the relevant aspect +""" + error: String! +} + +""" +Represents the connection between a view and an underlying repository in another organization. +""" +type CrossOrgViewConnection { +""" +ID of the underlying repository +""" + id: String! +""" +Name of the underlying repository +""" + name: String! +""" +The filter applied to all results from the repository. +""" + filter: String! + languageVersion: LanguageVersion! +""" +ID of the organization containing the underlying repository +""" + orgId: String! +} + +""" +The status the local database of CrowdStrike IOCs +""" +type CrowdStrikeIocStatus { + databaseTables: [IocTableInfo!]! +} + +type CurrentStats { + ingest: Ingest! + storedData: StoredData! + scannedData: ScannedData! + users: UsersLimit! +} + +""" +Query result for current usage +""" +union CurrentUsageQueryResult =QueryInProgress | CurrentStats + +type CustomLinkInteraction { + urlTemplate: String! + openInNewTab: Boolean! + urlEncodeArgs: Boolean! +} + +""" +Represents information about a dashboard. +""" +type Dashboard { + id: String! + name: String! + description: String + assetType: AssetType! +""" +A YAML formatted string that describes the dashboard. It does not contain links or permissions, and is safe to share and use for making copies of a dashboard. +""" + templateYaml: String! + displayName: String! + labels: [String!]! + widgets: [Widget!]! + sections: [Section!]! + readOnlyTokens: [DashboardLink!]! + filters: [DashboardFilter!]! + parameters: [DashboardParameter!]! + updateFrequency: DashboardUpdateFrequencyType! + isStarred: Boolean! + defaultFilter: DashboardFilter + defaultSharedTimeStart: String! + defaultSharedTimeEnd: String! + timeJumpSizeInMs: Int + defaultSharedTimeEnabled: Boolean! + searchDomain: SearchDomain! + packageId: VersionedPackageSpecifier + package: PackageInstallation +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +A dashboard +""" +type DashboardEntry { + dashboard: Dashboard! +} + +""" +A saved configuration for filtering dashboard widgets. +""" +type DashboardFilter { + id: String! + name: String! + prefixFilter: String! +} + +""" +A token that can be used to access the dashboard without logging in. Useful for e.g. wall mounted dashboards or public dashboards. +""" +type DashboardLink { + name: String! + token: String! + createdBy: String! +""" +The ip filter for the dashboard link. +""" + ipFilter: IPFilter +""" +Ownership of the queries run by this shared dashboard +""" + queryOwnership: QueryOwnership! +} + +type DashboardLinkInteraction { + arguments: [DictionaryEntryType!]! + dashboardReference: DashboardLinkInteractionDashboardReference! + openInNewTab: Boolean! + useWidgetTimeWindow: Boolean! +} + +""" +A reference to a dashboard either by id or name +""" +type DashboardLinkInteractionDashboardReference { + id: String + name: String + repoOrViewName: RepoOrViewName + packageSpecifier: UnversionedPackageSpecifier +} + +""" +A page of dashboards. +""" +type DashboardPage { + pageInfo: PageType! + page: [Dashboard!]! +} + +""" +Represents a dashboard parameter. +""" +interface DashboardParameter { +""" +Represents a dashboard parameter. +""" + id: String! +""" +Represents a dashboard parameter. +""" + label: String! +""" +Represents a dashboard parameter. +""" + defaultValueV2: String +""" +Represents a dashboard parameter. +""" + order: Int +""" +Represents a dashboard parameter. +""" + width: Int +""" +Represents a dashboard parameter. +""" + isMultiParam: Boolean +""" +Represents a dashboard parameter. +""" + defaultMultiValues: [String!] +} + +type DashboardTemplate { + name: String! + displayName: String! + yamlTemplate: String! + labels: [String!]! +} + +""" +The frequency at which a dashboard fetches new results for widgets. +""" +union DashboardUpdateFrequencyType =NeverDashboardUpdateFrequency | RealTimeDashboardUpdateFrequency + +""" +A datasource, e.g. file name or system sending data to LogScale. +""" +type Datasource { + name: String! + oldestTimestamp: DateTime! + newestTimestamp: DateTime! + tags: [Tag!]! +""" +The size in Gigabytes of the data from this data source before compression. +""" + sizeAtIngest: Float! +""" +This size in Gigabytes of the data from this data source currently on disk. +""" + sizeOnDisk: Float! +""" +The size in Gigabytes of the data from this data source before compression, but only for the parts that are now part of a merged segment file. +""" + sizeAtIngestOfMerged: Float! +""" +This size in Gigabytes of the data from this data source currently on disk, but only for the parts that are now part of a merged segment file. +""" + sizeOnDiskOfMerged: Float! +} + +""" +Date and time in the ISO-8601 instant format. Example: `2019-12-03T10:15:30.00Z` +""" +scalar DateTime + +""" +A deletion of a set of events. +""" +type DeleteEvents { + id: String! + created: DateTime! + start: DateTime! + end: DateTime! + query: String! + createdByUser: String + languageVersion: LanguageVersion! +} + +""" +Entry into a list of unordered key-value pairs with unique keys +""" +type DictionaryEntryType { + key: String! + value: String! +} + +""" +A dynamic configuration. +""" +enum DynamicConfig { + BlockSignup + DisableUserTracking + DisableAnalyticsJob + MaxAccessTokenTTL + RejectIngestOnParserExceedingFraction + QueryPartitionAutoBalance + QueryCoordinatorMaxHeapFraction + PruneCommunityLockedOrganizationsAfterHours + PruneMissingTOSAcceptanceOrganizationsAfterHours + DisableViewWithSameNameCleanup + MaxIngestRequestSize + JoinRowLimit + JoinDefaultLimit + SelfJoinLimit + StateRowLimit + AstDepthLimit + AdHocTablesLimit + QueryMemoryLimit + LiveQueryMemoryLimit + QueryCoordinatorMemoryLimit + GroupDefaultLimit + GroupMaxLimit + RdnsDefaultLimit + RdnsMaxLimit + QueryResultRowCountLimit + ParserThrottlingAllocationFactor + UndersizedMergingRetentionPercentage + StaticQueryFractionOfCores + TargetMaxRateForDatasource + DelayIngestResponseDueToIngestLagMaxFactor + DelayIngestResponseDueToIngestLagThreshold + DelayIngestResponseDueToIngestLagScale + SampleIntervalForDatasourceRates + FdrMaxNodesPerFeed + BucketStorageWriteVersion + BucketStorageKeySchemeVersion + BucketStorageUploadInfrequentThresholdDays + MinimumHumioVersion + DebugAuditRequestTrace + FlushSegmentsAndGlobalOnShutdown + GracePeriodBeforeDeletingDeadEphemeralHostsMs + FdrS3FileSizeMax + S3ArchivingClusterWideStartFrom + S3ArchivingClusterWideEndAt + S3ArchivingClusterWideDisabled + S3ArchivingClusterWideRegexForRepoName + EnableDemoData + MaxNumberOfOrganizations + NumberOfDaysToRemoveStaleOrganizationsAfter + IsAutomaticUpdateCheckingAllowed + ExternalFunctionRequestResponseSizeLimitBytes + ExternalFunctionRequestResponseEventCountLimit + ReplaceANSIEscapeCodes + DisableInconsistencyDetectionJob + DeleteDuplicatedNameViewsAfterMerging + MaxQueryPenaltyCreditForBlockedQueriesFactor + MaxConcurrentQueriesOnWorker + MaxQueryPollsForWorker + MaxOpenSegmentsOnWorker + IngestFeedAwsProcessingDownloadBufferSize + IngestFeedAwsProcessingEventBufferSize + IngestFeedAwsProcessingEventsPerBatch + IngestFeedAwsDownloadMaxObjectSize + IngestFeedGovernorGainPerCore + IngestFeedGovernorCycleDuration + IngestFeedGovernorIngestDelayLow + IngestFeedGovernorIngestDelayHigh + IngestFeedGovernorRateOverride + IngestFeedMaxConcurrentPolls + MaxCsvFileUploadSizeBytes + MaxJsonFileUploadSizeBytes + MatchFilesMaxHeapFraction + LookupTableSyncAwaitSeconds + GraphQLSelectionSizeLimit + UnauthenticatedGraphQLSelectionSizeLimit + QueryBlockMillisOnHighIngestDelay + FileReplicationFactor + QueryBacktrackingLimit + GraphQlDirectivesAmountLimit + TableCacheMemoryAllowanceFraction + TableCacheMaxStorageFraction + TableCacheMaxStorageFractionForIngestAndHttpOnly +} + +""" +A key value pair of a dynamic config and the accompanying value. +""" +type DynamicConfigKeyValueType { +""" +The dynamic config key. +""" + dynamicConfigKey: DynamicConfig! +""" +The dynamic config value. +""" + dynamicConfigValue: String! +} + +scalar Email + +""" +Scope of feature flag enablement +""" +enum EnabledInScope { + GlobalScope + OrganizationScope + UserScope + Disabled +} + +enum EntitiesPageDirection { + Previous + Next +} + +input EntitiesPageInputType { + cursor: String! + direction: EntitiesPageDirection! +} + +enum EntitySearchEntityType { + Dashboard + File + Interaction +} + +input EntitySearchInputType { + searchTerm: String + pageSize: Int + paths: [String!] + sortBy: [EntitySearchSortInfoType!] + entityTypes: [EntitySearchEntityType!]! +} + +union EntitySearchResultEntity =ViewInteractionEntry | FileEntry | DashboardEntry + +input EntitySearchSortInfoType { + name: String! + order: EntitySearchSortOrderType! +} + +enum EntitySearchSortOrderType { + Descending + Ascending +} + +enum EnvironmentType { + ON_PREM + ON_CLOUD + ON_COMMUNITY +} + +""" +Usage information +""" +type EnvironmentVariableUsage { +""" +The source for this environment variable. "Environment": the value is from the environment, "Default": variable not found in the environment, but a default value is used, "Missing": no variable or default found +""" + source: String! +""" +Value for this variable +""" + value: String! +""" +Environment variable name +""" + name: String! +} + +""" +An event forwarder +""" +interface EventForwarder { +""" +An event forwarder +""" + id: String! +""" +An event forwarder +""" + name: String! +""" +An event forwarder +""" + description: String! +""" +An event forwarder +""" + enabled: Boolean! +} + +""" +An event forwarder +""" +type EventForwarderForSelection { +""" +Id of the event forwarder +""" + id: String! +""" +Name of the event forwarder +""" + name: String! +""" +Description of the event forwarder +""" + description: String! + enabled: Boolean! +""" +The kind of event forwarder +""" + kind: EventForwarderKind! +} + +""" +The kind of an event forwarder +""" +enum EventForwarderKind { + Kafka +} + +""" +An event forwarding rule +""" +type EventForwardingRule { +""" +The unique id for the event forwarding rule +""" + id: String! +""" +The query string for filtering and mapping the events to forward +""" + queryString: String! +""" +The id of the event forwarder +""" + eventForwarderId: String! +""" +The unix timestamp the event forwarder was created +""" + createdAt: Long + languageVersion: LanguageVersion! +} + +""" +Fields that helps describe the status of eviction +""" +type EvictionStatus { + currentlyUnderReplicatedBytes: Long! + totalSegmentBytes: Long! + isDigester: Boolean! + bytesThatExistOnlyOnThisNode: Float! +} + +""" +The specification of an external function. +""" +type ExternalFunctionSpecificationOutput { +""" +The name of the external function. +""" + name: String! +""" +The URL for the external function. +""" + procedureURL: String! +""" +The parameter specifications for the external function. +""" + parameters: [ParameterSpecificationOutput!]! +""" +The description for the external function. +""" + description: String! +""" +The kind of external function. This defines how the external function is executed. +""" + kind: KindOutput! +} + +""" +Information about an FDR feed. +""" +type FdrFeed { +""" +Id of the FDR feed. +""" + id: String! +""" +Name of the FDR feed. +""" + name: String! +""" +Description of the FDR feed. +""" + description: String +""" +The id of the parser that is used to parse the FDR data. +""" + parserId: String! +""" +AWS client id of the FDR feed. +""" + clientId: String! +""" +AWS SQS queue url of the FDR feed. +""" + sqsUrl: String! +""" +AWS S3 Identifier of the FDR feed. +""" + s3Identifier: String! +""" +Is ingest from the FDR feed enabled? +""" + enabled: Boolean! +} + +""" +Administrator control for an FDR feed +""" +type FdrFeedControl { +""" +Id of the FDR feed. +""" + id: String! +""" +Maximum number of nodes to poll FDR feed with +""" + maxNodes: Int +""" +Maximum amount of files downloaded from s3 in parallel for a single node. +""" + fileDownloadParallelism: Int +} + +enum FeatureAnnouncement { + AggregateAlertSearchPage + AggregateAlertOverview + FleetRemoteUpdatesAndGroups + FilterMatchHighlighting + OrganizationOwnedQueries + Interactions + FieldInteractions + PuffinRebranding + FetchMoreOnFieldsPanel + ToolPanel +} + +""" +Represents a feature flag. +""" +enum FeatureFlag { +""" +[PREVIEW: This functionality is still under development and can change without warning.] Export data to bucket storage. +""" + ExportToBucket +""" +[PREVIEW: This functionality is still under development and can change without warning.] Enable repeating queries. Can be used instead of live queries for functions having limitations around live queries. +""" + RepeatingQueries +""" +[PREVIEW: This functionality is still under development and can change without warning.] Enable custom ingest tokens not generated by LogScale. +""" + CustomIngestTokens +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable permission tokens. +""" + PermissionTokens +""" +[PREVIEW: This functionality is still under development and can change without warning.] Assign default roles for groups. +""" + DefaultRolesForGroups +""" +[PREVIEW: This functionality is still under development and can change without warning.] Use new organization limits. +""" + NewOrganizationLimits +""" +[PREVIEW: This functionality is still under development and can change without warning.] Authenticate cookies server-side. +""" + CookieAuthServerSide +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable ArrayFunctions in query language. +""" + ArrayFunctions +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable geography functions in query language. +""" + GeographyFunctions +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Prioritize newer over older segments. +""" + CachePolicies +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable searching across LogScale clusters. +""" + MultiClusterSearch +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable subdomains for current cluster. +""" + SubdomainForOrganizations +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable Humio Managed repositories. The customer is not permitted to change certain configurations in a LogScale Managed repository. +""" + ManagedRepositories +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Allow users to configure FDR feeds for managed repositories +""" + ManagedRepositoriesAllowFDRConfig +""" +[PREVIEW: This functionality is still under development and can change without warning.] The UsagePage shows data from ingestAfterFieldRemovalSize instead of segmentWriteBytes +""" + UsagePageUsingIngestAfterFieldRemovalSize +""" +[PREVIEW: This functionality is still under development and can change without warning.] Enable falcon data connector +""" + FalconDataConnector +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Flag for testing, does nothing +""" + SleepFunction +""" +[PREVIEW: This functionality is still under development and can change without warning.] Enable login bridge +""" + LoginBridge +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables download of macos installer for logcollector through fleet management +""" + MacosInstallerForLogCollector +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables UsageJob to log average usage as part of usage log +""" + LogAverageUsage +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables ephemeral hosts support for fleet management +""" + FleetEphemeralHosts +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables fleet management collector metrics +""" + FleetCollectorMetrics +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] No currentHosts writes for segments in buckets +""" + NoCurrentsForBucketSegments +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Pre-merge mini-segments +""" + PreMergeMiniSegments +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Use a new segment file format on write - not readable by older versions +""" + WriteNewSegmentFileFormat +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables fleet management collector debug logging +""" + FleetCollectorDebugLogging +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables LogScale Collector remote updates +""" + FleetRemoteUpdates +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables alternate query merge target handling +""" + AlternateQueryMergeTargetHandling +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables query optimizations for fleet management +""" + FleetUseStaticQueries +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables labels for fleet management +""" + FleetLabels +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables Field Aliasing +""" + FieldAliasing +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] External Functions +""" + ExternalFunctions +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable the LogScale Query Assistant +""" + QueryAssistant +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable Flight Control support in cluster +""" + FlightControl +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enable organization level security policies. For instance the ability to only enable certain action types. +""" + OrganizationSecurityPolicies +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables a limit on query backtracking +""" + QueryBacktrackingLimit +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Adds a derived #repo.cid tag when searching in views or dataspaces within an organization with an associated CID +""" + DerivedCidTag +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Live tables +""" + LiveTables +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables the MITRE Detection Annotation function +""" + MitreDetectionAnnotation +""" +[PREVIEW: This functionality is still under development and can change without warning. THIS FUNCTIONALITY IS EXPERIMENTAL: Enabling experimental functionality is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] Enables having multiple role bindings for a single view in the same group. This feature flag does nothing until min version is at least 1.150.0 +""" + MultipleViewRoleBindings +} + +""" +Feature flags with details +""" +type FeatureFlagV2 { + flag: FeatureFlag! + description: String! + experimental: Boolean! +} + +type FieldAliasSchema { + id: String! + name: String! + fields: [SchemaField!]! + instances: [AliasMapping!]! + version: String! +} + +type FieldAliasSchemasInfo { + schemas: [FieldAliasSchema!]! + activeSchemaOnOrg: String + activeSchemasOnViews: [ActiveSchemaOnView!]! +} + +""" +Field condition comparison operator type +""" +enum FieldConditionOperatorType { + Equal + NotEqual + Contains + NotContains + StartsWith + EndsWith + Present + NotPresent + Unknown +} + +""" +Presentation preferences used when a field is added to table and event list widgets in the UI. +""" +type FieldConfiguration { +""" +The field the configuration is associated with. +""" + fieldName: String! +""" +A JSON object containing the column properties applied to the column when it is added to a widget. +""" + config: JSON! +} + +""" +An assertion that an event output from a parser test case has an expected value for a given field. +""" +type FieldHasValue { +""" +Field to assert on. +""" + fieldName: String! +""" +Value expected to be contained in the field. +""" + expectedValue: String! +} + +""" +A file upload to LogScale for use with the `match` query function. You can see them under the Files page in the UI. +""" +type File { + contentHash: String! + nameAndPath: FileNameAndPath! + createdAt: DateTime! + createdBy: String! + modifiedAt: DateTime! + fileSizeBytes: Long + modifiedBy: String! + packageId: VersionedPackageSpecifier + package: PackageInstallation +""" +The view or repository for the file +""" + view: PartialSearchDomain +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +A file asset +""" +type FileEntry { + view: SearchDomain + file: File! +} + +""" +A field in a file and what value the field should have for a given entry to pass the filter. +""" +input FileFieldFilterType { +""" +A field in a file and what value the field should have for a given entry to pass the filter. +""" + field: String! +""" +A field in a file and what value the field should have for a given entry to pass the filter. +""" + values: [String!]! +} + +type FileNameAndPath { + name: String! +""" +Paths for files can be one of two types: absolute or relative. +Absolute paths start with a slash, and relative paths start without a slash, like Unix paths. + +Every repository or view in the system is considered a "folder" in its own right, +meaning that every relative path is relative to the current view. +An absolute path points to something that can be addressed from any view, +and a relative path points to a file located inside the view. +If there is no path, it means the file is located at your current location. + +""" + path: String +} + +""" +The config for lookup files. +""" +type FilesConfig { + maxFileUploadSize: Int! +} + +""" +A filter alert. +""" +type FilterAlert { +""" +Id of the filter alert. +""" + id: String! +""" +Name of the filter alert. +""" + name: String! +""" +Description of the filter alert. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +List of ids for actions to fire on query result. +""" + actions: [Action!]! +""" +Labels attached to the filter alert. +""" + labels: [String!]! +""" +Flag indicating whether the filter alert is enabled. +""" + enabled: Boolean! +""" +Throttle time in seconds. +""" + throttleTimeSeconds: Long +""" +A field to throttle on. Can only be set if throttleTimeSeconds is set. +""" + throttleField: String +""" +Unix timestamp for last successful poll of the filter alert query. If this is not quite recent, then the alert might be having problems. +""" + lastSuccessfulPoll: Long +""" +Unix timestamp for last execution of trigger. +""" + lastTriggered: Long +""" +Unix timestamp for last error. +""" + lastErrorTime: Long +""" +Last error encountered while running the filter alert. +""" + lastError: String +""" +Last warnings encountered while running the filter alert. +""" + lastWarnings: [String!]! +""" +YAML specification of the filter alert. +""" + yamlTemplate: YAML! +""" +The id of the package that the alert was installed as part of. +""" + packageId: VersionedPackageSpecifier +""" +The package that the alert was installed as part of. +""" + package: PackageInstallation +""" +Ownership of the query run by this alert +""" + queryOwnership: QueryOwnership! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +The default config for filter alerts. +""" +type FilterAlertConfig { +""" +Maximum trigger limit for filter alerts with one or more email actions. +""" + filterAlertEmailTriggerLimit: Int! +""" +Maximum trigger limit for filter alerts with no email actions. +""" + filterAlertNonEmailTriggerLimit: Int! +} + +type FilterAlertTemplate { + name: String! + displayName: String! + yamlTemplate: YAML! + labels: [String!]! +} + +enum FleetConfiguration__SortBy { + Name + ModifiedBy + Instances + Size + LastModified +} + +enum FleetGroups__SortBy { + Filter + WantedVersion + Collectors + Name +} + +type FleetInstallationToken { + token: String! + name: String! + assignedConfiguration: LogCollectorConfiguration + installationCommands: LogCollectorInstallCommand! +} + +enum FleetInstallationTokens__SortBy { + Name + ConfigName +} + +enum Fleet__SortBy { + Hostname + System + Version + Ingest + LastActivity + ConfigName + CpuAverage5Min + MemoryMax5Min + DiskMax5Min + Change +} + +""" +Settings for the Java Flight Recorder. +""" +type FlightRecorderSettings { +""" +True if OldObjectSample is enabled +""" + oldObjectSampleEnabled: Boolean! +""" +The duration old object sampling will run for before dumping results and restarting +""" + oldObjectSampleDurationMinutes: Long! +} + +""" +Data for generating an unsaved aggregate alert object from a library package template +""" +input GenerateAggregateAlertFromPackageTemplateInput { +""" +Data for generating an unsaved aggregate alert object from a library package template +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved aggregate alert object from a library package template +""" + packageId: VersionedPackageSpecifier! +""" +Data for generating an unsaved aggregate alert object from a library package template +""" + templateName: String! +} + +""" +Data for generating an unsaved aggregate alert object from a yaml template +""" +input GenerateAggregateAlertFromTemplateInput { +""" +Data for generating an unsaved aggregate alert object from a yaml template +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved aggregate alert object from a yaml template +""" + yamlTemplate: YAML! +} + +""" +Data for generating an unsaved alert object from a library package template +""" +input GenerateAlertFromPackageTemplateInput { +""" +Data for generating an unsaved alert object from a library package template +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved alert object from a library package template +""" + packageId: VersionedPackageSpecifier! +""" +Data for generating an unsaved alert object from a library package template +""" + templateName: String! +} + +""" +Data for generating an unsaved alert object from a yaml template +""" +input GenerateAlertFromTemplateInput { +""" +Data for generating an unsaved alert object from a yaml template +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved alert object from a yaml template +""" + yamlTemplate: YAML! +} + +""" +Data for generating an unsaved filter alert object from a library package template +""" +input GenerateFilterAlertFromPackageTemplateInput { +""" +Data for generating an unsaved filter alert object from a library package template +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved filter alert object from a library package template +""" + packageId: VersionedPackageSpecifier! +""" +Data for generating an unsaved filter alert object from a library package template +""" + templateName: String! +} + +""" +Data for generating an unsaved filter alert object from a yaml template +""" +input GenerateFilterAlertFromTemplateInput { +""" +Data for generating an unsaved filter alert object from a yaml template +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved filter alert object from a yaml template +""" + yamlTemplate: YAML! +} + +""" +Data for generating an unsaved parser object from a YAML template +""" +input GenerateParserFromTemplateInput { +""" +Data for generating an unsaved parser object from a YAML template +""" + yamlTemplate: YAML! +} + +""" +Data for generating an unsaved scheduled search object from a library package template. +""" +input GenerateScheduledSearchFromPackageTemplateInput { +""" +Data for generating an unsaved scheduled search object from a library package template. +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved scheduled search object from a library package template. +""" + packageId: VersionedPackageSpecifier! +""" +Data for generating an unsaved scheduled search object from a library package template. +""" + templateName: String! +} + +""" +Data for generating an unsaved scheduled search object from a yaml templat. +""" +input GenerateScheduledSearchFromTemplateInput { +""" +Data for generating an unsaved scheduled search object from a yaml templat. +""" + viewName: RepoOrViewName! +""" +Data for generating an unsaved scheduled search object from a yaml templat. +""" + yamlTemplate: YAML! +} + +""" +The input required to get an external function specification. +""" +input GetExternalFunctionInput { +""" +The input required to get an external function specification. +""" + name: String! +""" +The input required to get an external function specification. +""" + view: String! +} + +""" +A group. +""" +type Group { + id: String! + displayName: String! + defaultQueryPrefix: String + defaultRole: Role + defaultSearchDomainCount: Int! + lookupName: String + searchDomainCount: Int! + roles: [SearchDomainRole!]! + searchDomainRoles( + searchDomainId: String + ): [SearchDomainRole!]! + searchDomainRolesByName( + searchDomainName: String! + ): SearchDomainRole + searchDomainRolesBySearchDomainName( + searchDomainName: String! + ): [SearchDomainRole!]! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Get asset permissions assigned to the group for the specific asset +""" + assetPermissions( +""" +Id of the asset +""" + assetId: String! +""" +Asset type +""" + assetType: AssetPermissionsAssetType! + searchDomainId: String + ): AssetPermissionsForGroup! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Search for asset permissions for the group +""" + searchAssetPermissions( +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The sort by options for asset permissions. +""" + sortBy: SortBy +""" +Asset type +""" + assetType: AssetPermissionsAssetType! +""" +List of search domain id's to search within +""" + searchDomainIds: [String!] +""" +Include UpdateAsset and/or DeleteAsset permission assignments +""" + permissions: AssetPermissionInputEnum +""" +If this is set to true, the search will also return all assets, that the group has not been assigned any permissions for +""" + includeUnassignedAssets: Boolean + ): AssetPermissionSearchResultSet! + systemRoles: [GroupSystemRole!]! + organizationRoles: [GroupOrganizationRole!]! + queryPrefixes( + onlyIncludeRestrictiveQueryPrefixes: Boolean + onlyForRoleWithId: String + ): [QueryPrefixes!]! + userCount: Int! + users: [User!]! + searchUsers( +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +The value to sort the result set by. +""" + sortBy: OrderByUserField +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + ): UserResultSetType! +} + +""" +Group to asset permissions assignments +""" +type GroupAssetPermissionAssignment { + group: Group! + assetPermissions: [AssetPermissionOutputEnum!]! +} + +input GroupFilter { + oldQuery: String + newQuery: String! +} + +type GroupFilterInfo { + total: Int! + added: Int! + removed: Int! + noChange: Int! +} + +""" +The organization roles of the group. +""" +type GroupOrganizationRole { + role: Role! +} + +""" +A page of groups in an organization. +""" +type GroupPage { + pageInfo: PageType! + page: [Group!]! +} + +""" +The groups query result set. +""" +type GroupResultSetType { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [Group!]! +} + +""" +A group to role assignment +""" +type GroupRole { + group: Group! + role: Role! +} + +""" +The role assigned to a group in a SearchDomain +""" +type GroupSearchDomainRole { + role: Role! + searchDomain: SearchDomain! + group: Group! +} + +""" +The system roles of the group. +""" +type GroupSystemRole { + role: Role! +} + +""" +Health status of the service +""" +type HealthStatus { +""" +The latest status from the service +""" + status: String! +""" +The latest health status message from the service +""" + message: String! +} + +""" +Represents information about the LogScale instance. +""" +type HumioMetadata { +""" +Returns enabled features that are likely in beta. +""" + isFeatureFlagEnabled( + feature: FeatureFlag! + ): Boolean! + externalPermissions: Boolean! + version: String! +""" +[PREVIEW: Experimental field used to improve the user experience during cluster upgrades.] An indication whether or not the cluster is being updated. This is based off of differences in the cluster node versions. +""" + isClusterBeingUpdated: Boolean! +""" +[PREVIEW: Experimental field used to improve the user experience during cluster upgrades.] The lowest detected node version in the cluster. +""" + minimumNodeVersion: String! + environment: EnvironmentType! + clusterId: String! + falconDataConnectorUrl: String + regions: [RegionSelectData!]! +""" +[PREVIEW: Experimental feature, not ready for production.] List of supported AWS regions +""" + awsRegions: [String!]! +""" +[PREVIEW: Experimental feature, not ready for production.] Cluster AWS IAM role arn (Amazon Resource Name) used to assume role for ingest feeds +""" + ingestFeedAwsRoleArn: String +""" +[PREVIEW: Experimental feature, not ready for production.] Configuration status for AWS ingest feeds. +""" + awsIngestFeedsConfigurationStatus: IngestFeedConfigurationStatus! + sharedDashboardsEnabled: Boolean! + personalUserTokensEnabled: Boolean! + globalAllowListEmailActionsEnabled: Boolean! + isAutomaticUpdateCheckingEnabled: Boolean! +""" +The authentication method used for the cluster node +""" + authenticationMethod: AuthenticationMethod! + organizationMultiMode: Boolean! + organizationMode: OrganizationMode! + sandboxesEnabled: Boolean! + externalGroupSynchronization: Boolean! + allowActionsNotUseProxy: Boolean! + isUsingSmtp: Boolean! + isPendingUsersEnabled: Boolean! + scheduledSearchMaxBackfillLimit: Int + isExternalManaged: Boolean! + isApiExplorerEnabled: Boolean! + isScheduledReportEnabled: Boolean! + eulaUrl: String! +""" +The time in ms after which a repository has been marked for deletion it will no longer be restorable. +""" + deleteBackupAfter: Long! + maxCsvFileUploadSizeBytes: Long! + maxJsonFileUploadSizeBytes: Long! +""" +The filter alert config. +""" + filterAlertConfig: FilterAlertConfig! +""" +The lookup files config. +""" + filesConfig: FilesConfig! +} + +""" +A LogScale query +""" +type HumioQuery { + languageVersion: LanguageVersion! + queryString: String! + arguments: [DictionaryEntryType!]! + start: String! + end: String! + isLive: Boolean! +} + +""" +An IP Filter +""" +type IPFilter { +""" +The unique id for the ip filter +""" + id: String! +""" +The name for the ip filter +""" + name: String! +""" +The ip filter +""" + ipFilter: String! +} + +type IdentityProviderAuth { + id: String! + name: String! + authenticationMethod: AuthenticationMethodAuth! +} + +""" +An Identity Provider +""" +interface IdentityProviderAuthentication { +""" +An Identity Provider +""" + id: String! +""" +An Identity Provider +""" + name: String! +""" +An Identity Provider +""" + defaultIdp: Boolean! +""" +An Identity Provider +""" + humioManaged: Boolean! +""" +An Identity Provider +""" + lazyCreateUsers: Boolean! +""" +An Identity Provider +""" + domains: [String!]! +""" +An Identity Provider +""" + debug: Boolean! +} + +type Ingest { + currentBytes: Long! + limit: UsageLimit! +} + +""" +An ingest feed. +""" +type IngestFeed { +""" +Id of the ingest feed. +""" + id: String! +""" +Name of the ingest feed. +""" + name: String! +""" +Description of the ingest feed. +""" + description: String +""" +Parser used to parse the ingest feed. +""" + parser: Parser +""" +Is ingest from the ingest feed enabled? +""" + enabled: Boolean! +""" +The source which this ingest feed will ingest from +""" + source: IngestFeedSource! +""" +Unix timestamp for when this feed was created +""" + createdAt: Long! +""" +Details about how the ingest feed is running +""" + executionInfo: IngestFeedExecutionInfo +} + +""" +How to authenticate to AWS. +""" +union IngestFeedAwsAuthentication =IngestFeedAwsAuthenticationIamRole + +""" +IAM role authentication +""" +type IngestFeedAwsAuthenticationIamRole { +""" +Arn of the role to be assumed +""" + roleArn: String! +""" +External Id to the role to be assumed +""" + externalId: String! +} + +""" +Compression scheme of the file. +""" +enum IngestFeedCompression { + Auto + Gzip + None +} + +""" +Represents the configuration status of the ingest feed feature on the cluster +""" +type IngestFeedConfigurationStatus { + isConfigured: Boolean! +} + +""" +Details about how the ingest feed is running +""" +type IngestFeedExecutionInfo { +""" +Unix timestamp of the latest activity for the feed +""" + latestActivity: Long +""" +Details about the status of the ingest feed +""" + statusMessage: IngestFeedStatus +} + +""" +The preprocessing to apply to an ingest feed before parsing. +""" +union IngestFeedPreprocessing =IngestFeedPreprocessingSplitNewline | IngestFeedPreprocessingSplitAwsRecords + +""" +The kind of preprocessing to do. +""" +enum IngestFeedPreprocessingKind { +""" +Interpret the input as AWS JSON record format and emit each record as an event +""" + SplitAwsRecords +""" +Interpret the input as newline-delimited and emit each line as an event +""" + SplitNewline +} + +""" +Interpret the input as AWS JSON record format and emit each record as an event +""" +type IngestFeedPreprocessingSplitAwsRecords { +""" +The kind of preprocessing to do. +""" + kind: IngestFeedPreprocessingKind! +} + +""" +Interpret the input as newline-delimited and emit each line as an event +""" +type IngestFeedPreprocessingSplitNewline { +""" +The kind of preprocessing to do. +""" + kind: IngestFeedPreprocessingKind! +} + +""" +The ingest feed query result set +""" +type IngestFeedQueryResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [IngestFeed!]! +} + +""" +An ingest feed that polls data from S3 and is notified via SQS +""" +type IngestFeedS3SqsSource { +""" +AWS SQS queue url. +""" + sqsUrl: String! +""" +The preprocessing to apply to an ingest feed before parsing. +""" + preprocessing: IngestFeedPreprocessing! +""" +How to authenticate to AWS. +""" + awsAuthentication: IngestFeedAwsAuthentication! +""" +Compression scheme of the file. +""" + compression: IngestFeedCompression! +""" +The AWS region to connect to. +""" + region: String! +} + +""" +The source from which to download from an ingest feed. +""" +union IngestFeedSource =IngestFeedS3SqsSource + +""" +Details about the status of the ingest feed +""" +type IngestFeedStatus { +""" +Description of the problem with the ingest feed +""" + problem: String! +""" +Terse description of the problem with the ingest feed +""" + terseProblem: String +""" +Timestamp, in milliseconds, of when the status message was set +""" + statusTimestamp: Long! +""" +Cause of the problem with the ingest feed +""" + cause: IngestFeedStatusCause +} + +""" +Details about the cause of the problem +""" +type IngestFeedStatusCause { +""" +Description of the cause of the problem +""" + cause: String! +""" +Terse description of the cause of the problem +""" + terseCause: String +} + +enum IngestFeeds__SortBy { + CreatedTimeStamp + Name +} + +enum IngestFeeds__Type { + AwsS3Sqs +} + +""" +Ingest Listeners listen on a port for UDP or TCP traffic, used with SysLog. +""" +type IngestListener { + id: String! + repository: Repository! +""" +The TCP/UDP port to listen to. +""" + port: Int! +""" +The network protocol data is sent through. +""" + protocol: IngestListenerProtocol! +""" +The charset used to decode the event stream. Available charsets depend on the JVM running the LogScale instance. Names and aliases can be found at http://www.iana.org/assignments/character-sets/character-sets.xhtml +""" + charset: String! +""" +Specify which host should open the socket. By default this field is empty and all hosts will open a socket. This field can be used to select only one host to open the socket. +""" + vHost: Int + name: String! +""" +The ip address this listener will bind to. By default (leaving this field empty) it will bind to 0.0.0.0 - all interfaces. Using this field it is also possible to specify the address to bind to. In a cluster setup it is also possible to specify if only one machine should open a socket - The vhost field is used for that. +""" + bindInterface: String! +""" +The parser configured to parse data for the listener. This returns null if the parser has been removed since the listener was created. +""" + parser: Parser +} + +""" +The network protocol a ingest listener uses. +""" +enum IngestListenerProtocol { +""" +UDP Protocol +""" + UDP +""" +TCP Protocol +""" + TCP +""" +Gelf over UDP Protocol +""" + GELF_UDP +""" +Gelf over TCP Protocol +""" + GELF_TCP +""" +Netflow over UDP +""" + NETFLOW_UDP +} + +""" +A cluster ingest partition. It assigns cluster nodes with the responsibility of ingesting data. +""" +type IngestPartition { + id: Int! +""" +The ids of the node responsible executing real-time queries for the partition and writing events to time series. The list is ordered so that the first node is the primary node and the rest are followers ready to take over if the primary fails. +""" + nodeIds: [Int!]! +} + +""" +An API ingest token used for sending data to LogScale. +""" +type IngestToken { + name: String! + token: String! + parser: Parser +} + +""" +The status of an IOC database table +""" +type IocTableInfo { +""" +The name of the indicator type in this table +""" + name: String! + status: IocTableStatus! +""" +The number of milliseconds since epoch that the IOC database was last updated +""" + lastUpdated: Long +""" +The number of indicators in the database +""" + count: Int! +} + +enum IocTableStatus { + Unauthorized + Unavailable + Ok +} + +""" +Represents information about the IP database used by LogScale +""" +type IpDatabaseInfo { +""" +The absolute file path of the file containing the database +""" + dbFilePath: String! +""" +The update strategy used for the IP Database +""" + updateStrategy: String! +""" +Metadata about the IP Database used by LogScale +""" + metadata: IpDatabaseMetadata +} + +""" +Represents metadata about the IP database used by LogScale +""" +type IpDatabaseMetadata { +""" +The type of database +""" + type: String! +""" +The date on which the database was build +""" + buildDate: DateTime! +""" +The description of the database +""" + description: String! +""" +The md5 hash of the file containing the database +""" + dbFileMd5: String! +} + +scalar JSON + +type KafkaClusterDescription { + clusterID: String! + nodes: [KafkaNode!]! + controller: KafkaNode! + logDirDescriptions: [KafkaLogDir!]! + globalEventsTopic: KafkaTopicDescription! + ingestTopic: KafkaTopicDescription! + chatterTopic: KafkaTopicDescription! +} + +type KafkaLogDir { + nodeID: Int! + path: String! + error: String + topicPartitions: [KafkaNodeTopicPartitionLogDescription!]! +} + +type KafkaNode { + id: Int! + host: String + port: Int! + rack: String +} + +type KafkaNodeTopicPartitionLogDescription { + topicPartition: KafkaTopicPartition! + offset: Long! + size: Long! + isFuture: Boolean! +} + +type KafkaTopicConfig { + key: String! + value: String! +} + +type KafkaTopicConfigs { + configs: [KafkaTopicConfig!]! + defaultConfigs: [KafkaTopicConfig!]! +} + +type KafkaTopicDescription { + name: String! + config: KafkaTopicConfigs! + partitions: [KafkaTopicPartitionDescription!]! +} + +type KafkaTopicPartition { + topic: String! + partition: Int! +} + +type KafkaTopicPartitionDescription { + partition: Int! + leader: Int! + replicas: [Int!]! + inSyncReplicas: [Int!]! +} + +""" +The kind of the external function +""" +enum KindEnum { + Source + General + Enrichment +} + +""" +Defines how the external function is executed. +""" +type KindOutput { +""" +The name of the kind of external function. +""" + name: KindEnum! +""" +The parameters that specify the key fields. Use for the 'Enrichment' functions. +""" + parametersDefiningKeyFields: [String!] +""" +The names of the keys when they're returned from the external function. Use for the 'Enrichment' functions. +""" + fixedKeyFields: [String!] +} + +type LanguageVersion { +""" +If non-null, this is a version known by the current version of LogScale. +""" + name: LanguageVersionEnum +""" +If non-null, this is a version stored by a future LogScale version. +""" + futureName: String +""" +The language version. +""" + version: LanguageVersionOutputType! +""" +If false, this version isn't recognized by the current version of LogScale. +It must have been stored by a future LogScale version. +This can happen if LogScale was upgraded, and subsequently downgraded (rolled back). +""" + isKnown: Boolean! +} + +""" +The version of the LogScale query language to use. +""" +enum LanguageVersionEnum { + legacy + xdr1 + xdrdetects1 + filteralert + federated1 +} + +""" +A specific language version. +""" +input LanguageVersionInputType { +""" +A specific language version. +""" + name: String! +} + +""" +A specific language version. +""" +type LanguageVersionOutputType { +""" +The name of the language version. The name is case insensitive. +""" + name: String! +} + +""" +Represents information about the LogScale instance. +""" +interface License { +""" +Represents information about the LogScale instance. +""" + expiresAt: DateTime! +""" +Represents information about the LogScale instance. +""" + issuedAt: DateTime! +} + +""" +A Limit added to the organization. +""" +type Limit { +""" +The limit name +""" + limitName: String! +""" +If the limit allows logging in +""" + allowLogin: Boolean! +""" +The daily ingest allowed for the limit +""" + dailyIngest: Long! +""" +The retention in days allowed for the limit +""" + retention: Int! +""" +If the limit allows self service +""" + allowSelfService: Boolean! +""" +The deleted date for the limit +""" + deletedDate: Long +} + +""" +A Limit added to the organization. +""" +type LimitV2 { +""" +The id +""" + id: String! +""" +The limit name +""" + limitName: String! +""" +The display name of the limit +""" + displayName: String! +""" +If the limit allows logging in +""" + allowLogin: Boolean! +""" +The daily ingest allowed for the limit +""" + dailyIngest: contractual! +""" +The amount of storage allowed for the limit +""" + storageLimit: contractual! +""" +The data scanned measurement allowed for the limit +""" + dataScannedLimit: contractual! +""" +The usage measurement type used for the limit +""" + measurementPoint: Organizations__MeasurementType! +""" +The user seats allowed for the limit +""" + userLimit: contractual! +""" +The number of repositories allowed for the limit +""" + repoLimit: Int +""" +The retention in days for the limit, that's the contracted value +""" + retention: Int! +""" +The max retention in days allowed for the limit, this can be greater than or equal to retention +""" + maxRetention: Int! +""" +If the limit allows self service +""" + allowSelfService: Boolean! +""" +The deleted date for the limit +""" + deletedDate: Long +""" +The expiration date for the limit +""" + expirationDate: Long +""" +If the limit is a trial +""" + trial: Boolean! +""" +If the customer is allowed flight control +""" + allowFlightControl: Boolean! +""" +Data type for the limit, all repositories linked to the limit will get this datatype logged in usage +""" + dataType: String! +""" +Repositories attached to the limit +""" + repositories: [Repository!]! +} + +""" +All data related to a scheduled report accessible with a readonly scheduled report access token +""" +type LimitedScheduledReport { +""" +Id of the scheduled report. +""" + id: String! +""" +Name of the scheduled report. +""" + name: String! +""" +Description of the scheduled report. +""" + description: String! +""" +Name of the dashboard referenced by the report. +""" + dashboardName: String! +""" +Display name of the dashboard referenced by the report. +""" + dashboardDisplayName: String! +""" +Shared time interval of the dashboard referenced by the report. +""" + dashboardSharedTimeInterval: SharedDashboardTimeInterval +""" +Widgets of the dashboard referenced by the report. +""" + dashboardWidgets: [Widget!]! +""" +Sections of the dashboard referenced by the report. +""" + dashboardSections: [Section!]! +""" +The name of the repository or view queries are executed against. +""" + repoOrViewName: RepoOrViewName! +""" +Layout of the scheduled report. +""" + layout: ScheduledReportLayout! +""" +Timezone of the schedule. Examples include UTC, Europe/Copenhagen. +""" + timeZone: String! +""" +List of parameter value configurations. +""" + parameters: [ParameterValue!]! +} + +""" +The status of a local cluster connection. +""" +type LocalClusterConnectionStatus implements ClusterConnectionStatus{ +""" +Name of the local view +""" + viewName: String +""" +Id of the connection +""" + id: String +""" +Whether the connection is valid +""" + isValid: Boolean! +""" +Errors if the connection is invalid +""" + errorMessages: [ConnectionAspectErrorType!]! +} + +""" +A fleet search result entry +""" +type LogCollector { +""" +If the collector is enrolled this is its id +""" + id: String +""" +The hostname +""" + hostname: String! +""" +The host system +""" + system: String! +""" +Version +""" + version: String! +""" +Last activity recorded +""" + lastActivity: String! +""" +Ingest last 24h. +""" + ingestLast24H: Long! +""" +Ip address +""" + ipAddress: String + logSources: [LogCollectorLogSource!]! +""" +Log collector machineId +""" + machineId: String! +""" +contains the name of any manually assigned config +""" + configName: String +""" +contains the id of any manually assigned config +""" + configId: String + configurations: [LogCollectorConfigInfo!]! + errors: [String!]! + cfgTestId: String + cpuAverage5Min: Float + memoryMax5Min: Long + diskMax5Min: Float + change: Changes + groups: [LogCollectorGroup!]! + wantedVersion: String + debugLogging: LogCollectorDebugLogging + timeOfUpdate: DateTime + usesRemoteUpdate: Boolean! + ephemeralTimeout: Int + status: LogCollectorStatusType + labels: [LogCollectorLabel!]! +} + +type LogCollectorConfigInfo { + id: String! + name: String! + group: LogCollectorGroup + assignment: LogCollectorConfigurationAssignmentType! +} + +""" +A configuration file for a log collector +""" +type LogCollectorConfiguration { + id: String! + name: String! + yaml: String + draft: String + version: Int! + yamlCharactersCount: Int! + modifiedAt: DateTime! + draftModifiedAt: DateTime + modifiedBy: String! + instances: Int! + description: String + isTestRunning: Boolean! +} + +enum LogCollectorConfigurationAssignmentType { + Group + Manual + Test +} + +type LogCollectorConfigurationProblemAtPath { + summary: String! + details: String + path: String! + number: Int! +} + +union LogCollectorDebugLogging =LogCollectorDebugLoggingStatic + +type LogCollectorDebugLoggingStatic { + url: String + token: String! + level: String! + repository: String +} + +""" +Details about a Log Collector +""" +type LogCollectorDetails { +""" +If the collector is enrolled this is its id +""" + id: String +""" +The hostname +""" + hostname: String! +""" +The host system +""" + system: String! +""" +Version +""" + version: String! +""" +Last activity recorded +""" + lastActivity: String! +""" +Ip address +""" + ipAddress: String + logSources: [LogCollectorLogSource!]! +""" +Log collector machineId +""" + machineId: String! + configurations: [LogCollectorConfigInfo!]! + errors: [String!]! + cpuAverage5Min: Float + memoryMax5Min: Long + diskMax5Min: Float + ephemeralTimeout: Int + status: LogCollectorStatusType +} + +type LogCollectorGroup { + id: String! + name: String! + filter: String + configurations: [LogCollectorConfiguration!]! + collectorCount: Int + wantedVersion: String + onlyUsesRemoteUpdates: Boolean! +} + +type LogCollectorInstallCommand { + windowsCommand: String! + linuxCommand: String! + macosCommand: String! +} + +""" +Provides information about an installer of the LogScale Collector. +""" +type LogCollectorInstaller { +""" +Installer file name +""" + name: String! +""" +URL to fetch installer from +""" + url: String! +""" +LogScale Collector version +""" + version: String! +""" +Installer CPU architecture +""" + architecture: String! +""" +Installer type (deb, rpm or msi) +""" + type: String! +""" +Installer file size +""" + size: Int! +""" +Config file example +""" + configExample: String +""" +Icon file name +""" + icon: String +} + +type LogCollectorLabel { + name: String! + value: String! +} + +type LogCollectorLogSource { + sourceName: String! + sourceType: String! + sinkType: String! + parser: String + repository: String +} + +type LogCollectorMergedConfiguration { + problems: [LogCollectorConfigurationProblemAtPath!]! + content: String! +} + +enum LogCollectorStatusType { + Error + OK +} + +type LoginBridge { + name: String! + issuer: String! + description: String! + remoteId: String! + loginUrl: String! + relayStateUUrl: String! + samlEntityId: String! + publicSamlCertificate: String! + groupAttribute: String! + organizationIdAttributeName: String! + organizationNameAttributeName: String + additionalAttributes: String + groups: [String!]! + allowedUsers: [User!]! + generateUserName: Boolean! + termsDescription: String! + termsLink: String! + showTermsAndConditions: Boolean! +""" +True if any user in this organization has logged in to CrowdStream via LogScale. Requires manage organizations permissions +""" + anyUserAlreadyLoggedInViaLoginBridge: Boolean! +} + +type LoginBridgeRequest { + samlResponse: String! + loginUrl: String! + relayState: String! +} + +type LookupFileTemplate { + name: String! + displayName: String! + content: String! +} + +scalar Markdown + +""" +A place for LogScale to find packages. +""" +type Marketplace { +""" +Gets all categories in the marketplace. +""" + categoryGroups: [MarketplaceCategoryGroup!]! +} + +""" +A category that can be used to filter search results in the marketplace. +""" +type MarketplaceCategory { +""" +A display string for the category. +""" + title: String! +""" +The id is used to filter the searches. +""" + id: String! +} + +""" +A grouping of categories that can be used to filter search results in the marketplace. +""" +type MarketplaceCategoryGroup { +""" +A display string for the category group. +""" + title: String! +""" +The categories that are members of the group. +""" + categories: [MarketplaceCategory!]! +} + +type MonthlyIngest { + monthly: [UsageOnDay!]! +} + +""" +Query result for monthly ingest +""" +union MonthlyIngestQueryResult =QueryInProgress | MonthlyIngest + +type MonthlyStorage { + monthly: [StorageOnDay!]! +} + +""" +Query result for monthly storage +""" +union MonthlyStorageQueryResult =QueryInProgress | MonthlyStorage + +type NeverDashboardUpdateFrequency { + name: String! +} + +""" +Assignable node task. +""" +enum NodeTaskEnum { + storage + digest + query +} + +""" +A notification +""" +type Notification { +""" +The unique id for the notification +""" + id: String! +""" +The title of the notification +""" + title: String! +""" +The message for the notification +""" + message: String! +""" +Whether the notification is dismissable +""" + dismissable: Boolean! +""" +The severity of the notification +""" + severity: NotificationSeverity! +""" +The type of the notification +""" + type: NotificationTypes! +""" +Link accompanying the notification +""" + link: String +""" +Description for the link +""" + linkDescription: String +} + +enum NotificationSeverity { + Success + Info + Warning + Error +} + +enum NotificationTypes { + Banner + Announcement + Bell +} + +""" +Paginated response for notifications. +""" +type NotificationsResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [Notification!]! +} + +type OidcIdentityProvider implements IdentityProviderAuthentication{ + id: String! + name: String! + clientId: String! + clientSecret: String! + domains: [String!]! + issuer: String! + tokenEndpointAuthMethod: String! + userClaim: String! + scopes: [String!]! + userInfoEndpoint: String + registrationEndpoint: String + tokenEndpoint: String + groupsClaim: String + jwksEndpoint: String + authenticationMethod: AuthenticationMethodAuth! + authorizationEndpoint: String + debug: Boolean! + federatedIdp: String + scopeClaim: String + defaultIdp: Boolean! + humioManaged: Boolean! + lazyCreateUsers: Boolean! +} + +type OnlyTotal { + total: Int! +} + +enum OrderBy { + DESC + ASC +} + +""" +OrderByDirection +""" +enum OrderByDirection { + DESC + ASC +} + +""" +OrderByUserField +""" +enum OrderByUserField { + FULLNAME + USERNAME + DISPLAYNAME +} + +input OrderByUserFieldInput { + userField: OrderByUserField! + order: OrderByDirection! +} + +""" +An Organization +""" +type Organization { +""" +The unique id for the Organization +""" + id: String! +""" +The CID corresponding to the organization +""" + cid: String +""" +The name for the Organization +""" + name: String! +""" +The description for the Organization, can be null +""" + description: String +""" +Details about the organization +""" + details: OrganizationDetails! +""" +Stats of the organization +""" + stats: OrganizationStats! +""" +Organization configurations and settings +""" + configs: OrganizationConfigs! +""" +Search domains in the organization +""" + searchDomains: [SearchDomain!]! +""" +IP filter for readonly dashboard links +""" + readonlyDashboardIPFilter: String +""" +Created date +""" + createdAt: Long +""" +If the organization has been marked for deletion, this indicates the day it was deleted. +""" + deletedAt: Long +""" +Trial started at +""" + trialStartedAt: Long +""" +Public url for the Organization +""" + publicUrl: String +""" +Ingest url for the Organization +""" + ingestUrl: String +""" +Check if the current user has a given permission in the organization. +""" + isActionAllowed( +""" +The action to check if a user is allowed to perform on an organization. +""" + action: OrganizationAction! + ): Boolean! +""" +Limits assigned to the organization +""" + limits: [Limit!]! +""" +Limits assigned to the organizations +""" + limitsV2: [LimitV2!]! + externalPermissions: Boolean! + externalGroupSynchronization: Boolean! +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] The default cache policy of this organization. +""" + defaultCachePolicy: CachePolicy +} + +""" +Actions a user may perform on an organization. +""" +enum OrganizationAction { + AdministerPermissions + CreateRepository + CreateView + ChangeReadOnlyDashboardFilter + CreateUser + ConfigureIdp + ChangeSessions + ChangeOrganizationSettings + CreateTrialRepository + UseCustomEmailTemplate + ViewLoginBridge + ViewUsage + ConfigureIPFilters + DeleteRepositoryOrView + ChangeFleetManagement + ViewFleetManagement + UseRemoteUpdates + UseFleetRemoteDebug + UseFleetEphemeralHosts + UseFleetStaticQueries + UseFleetLabels + ChangeTriggersToRunAsOtherUsers + ChangeEventForwarders + ViewRunningQueries + BlockQueries + AdministerTokens + ManageUsers + ViewIpFilters + DownloadMacOsInstaller + SecurityPoliciesEnabled + ChangeSecurityPolicies + QueryAssistant + OrganizationQueryOwnershipEnabled + UsePersonalToken + ChangeExternalFunctions + AddFederatedView + ViewFalconDataConnectorUrl + ManageSchemas +""" +[PREVIEW: This is a temporary value that will be removed again] +""" + ExternalFunctionsEnabled + ViewOrganizationSettings + ViewSecurityPolicies + ViewSessionSettings + ViewUsers + ViewPermissions + ViewIdp + ViewOrganizationTokens + ViewDeletedRepositoriesOrViews + ViewEventForwarders + ViewSchemas +} + +""" +Configurations for the organization +""" +type OrganizationConfigs { +""" +Session settings +""" + session: OrganizationSession! +""" +Social login settings +""" + socialLogin: [SocialLoginSettings!]! +""" +Subdomain configuration for the organization +""" + subdomains: SubdomainConfig +""" +Bucket storage configuration for the organization +""" + bucketStorage: BucketStorageConfig +""" +Security policies for actions in the organization +""" + actions: ActionSecurityPolicies +""" +Security policies for tokens in the organization +""" + tokens: TokenSecurityPolicies +""" +Security policies for shared dashboard tokens in the organization +""" + sharedDashboards: SharedDashboardsSecurityPolicies +""" +Login bridge +""" + loginBridge: LoginBridge +""" +Whether the organization is currently blocking ingest +""" + blockingIngest: Boolean! +""" +Default timezone to use for users without a default timezone set. +""" + defaultTimeZone: String +} + +""" +Details about the organization +""" +type OrganizationDetails { +""" +Notes of the organization (root only) +""" + notes: String! +""" +Industry of the organization +""" + industry: String! +""" +Industry of the organization +""" + useCases: [Organizations__UseCases!]! +""" +Subscription of the organization +""" + subscription: Organizations__Subscription! +""" +Trial end date of the organization if any +""" + trialEndDate: Long +""" +Limits of the organization +""" + limits: OrganizationLimits! +""" +The country of the organization +""" + country: String! +""" +Determines whether an organization has access to IOCs (indicators of compromise) +""" + iocAccess: Boolean +} + +""" +Limits of the organization +""" +type OrganizationLimits { +""" +Daily ingest allowed +""" + dailyIngest: Long! +""" +Days of retention allowed +""" + retention: Int! +""" +Max amount of users allowed +""" + users: Int! +""" +License expiration date +""" + licenseExpirationDate: Long +""" +Whether self service is enabled for the Organization, allowing features like creating repositories and setting retention. +""" + allowSelfService: Boolean! +""" +Last contract synchronization date +""" + lastSyncDate: Long +""" +Whether the contract is missing for the organization. None for non accounts, true if account and has no contract and false if contract was found and used. +""" + missingContract: Boolean +""" +Contract version +""" + contractVersion: Organizations__ContractVersion! +} + +""" +Organization management permissions +""" +enum OrganizationManagementPermission { + ManageSpecificOrganizations +} + +enum OrganizationMode { + Single + Multi + MultiV2 +} + +""" +Organization permissions +""" +enum OrganizationPermission { + ExportOrganization + ChangeOrganizationPermissions + ChangeIdentityProviders + CreateRepository + ManageUsers + ViewUsage + ChangeOrganizationSettings + ChangeIPFilters + ChangeSessions + ChangeAllViewOrRepositoryPermissions + IngestAcrossAllReposWithinOrganization + DeleteAllRepositories + DeleteAllViews + ViewAllInternalNotifications + ChangeFleetManagement + ViewFleetManagement + ChangeTriggersToRunAsOtherUsers + MonitorQueries + BlockQueries + ChangeSecurityPolicies + ChangeExternalFunctions + ChangeFieldAliases + ManageViewConnections +} + +""" +An organization search result entry +""" +type OrganizationSearchResultEntry { +""" +The unique id for the Organization +""" + organizationId: String! +""" +The name of the Organization +""" + organizationName: String! +""" +The string matching the search +""" + searchMatch: String! +""" +The id of the entity matched +""" + entityId: String! +""" +The subscription type of the organization +""" + subscription: Organizations__Subscription! +""" +The type of the search result match +""" + type: Organizations__SearchEntryType! +""" +The amount of users in the organization +""" + userCount: Int! +""" +The amount of repositories and views in the organization +""" + viewCount: Int! +""" +The total data volume in bytes that the organization is currently using +""" + byteVolume: Long! +""" +The end date of the trial if applicable +""" + trialEndDate: Long +""" +The time when the organization was created +""" + createdAt: Long! +""" +If the organization has been marked for deletion, this indicates the time when the organization was marked. +""" + deletedAt: Long +""" +The relevant organization for the result +""" + organization: Organization! +} + +""" +An organization search result set +""" +type OrganizationSearchResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [OrganizationSearchResultEntry!]! +} + +""" +Session configuration for the organization +""" +type OrganizationSession { +""" +The maximum time in ms the user is allowed to be inactive +""" + maxInactivityPeriod: Long! +""" +The time in ms after which the user is forced to reauthenticate +""" + forceReauthenticationAfter: Long! +} + +""" +Stats of the organization +""" +type OrganizationStats { +""" +Total compressed data volume used by the organization +""" + dataVolumeCompressed: Long! +""" +Total data volume used by the organization +""" + dataVolume: Long! +""" +The total daily ingest of the organization +""" + dailyIngest: Long! +""" +The number of users in the organization +""" + userCount: Int! +} + +enum OrganizationsLinks__SortBy { + Cid + OrgId + Name +} + +enum Organizations__ContractVersion { + Unknown + Version1 + Version2 +} + +enum Organizations__MeasurementType { + SegmentWriteSize + ProcessedEventsSize +} + +enum Organizations__SearchEntryType { + Organization + Repository + View + User +} + +enum Organizations__SortBy { + UserCount + Name + Volume + ViewCount + Subscription + CreatedAt +} + +enum Organizations__Subscription { + Paying + Trial + PreTrial + PostTrial + UnlimitedPoC + ClusterOwner + Complementary + OnPremMonitor + MissingTOSAcceptance + CommunityLocked + CommunityUnlocked + Partner + Internal + Churned + Unknown +} + +enum Organizations__UseCases { + Unknown + IoT + Security + Operations + ApplicationDevelopment +} + +""" +A Humio package +""" +type Package2 { + id: VersionedPackageSpecifier! + scope: PackageScope! + name: PackageName! + version: PackageVersion! + description: String + iconUrl: UrlOrData + author: PackageAuthor! + contributors: [PackageAuthor!]! + licenseUrl: URL! + minHumioVersion: SemanticVersion! + readme: Markdown + dashboardTemplates: [DashboardTemplate!]! + savedQueryTemplates: [SavedQueryTemplate!]! + parserTemplates: [ParserTemplate!]! + alertTemplates: [AlertTemplate!]! + filterAlertTemplates: [FilterAlertTemplate!]! + aggregateAlertTemplates: [AggregateAlertTemplate!]! + lookupFileTemplates: [LookupFileTemplate!]! + actionTemplates: [ActionTemplate!]! + scheduledSearchTemplates: [ScheduledSearchTemplate!]! + viewInteractionTemplates: [ViewInteractionTemplate!]! + type: PackageType! +""" +The available versions of the package on the marketplace. +""" + versionsOnMarketplace: [RegistryPackageVersionInfo!]! +} + +""" +The author of a package. +""" +type PackageAuthor { + name: String! + email: Email +} + +""" +A package installation. +""" +type PackageInstallation { + id: VersionedPackageSpecifier! + installedBy: UserAndTimestamp! + updatedBy: UserAndTimestamp! + source: PackageInstallationSourceType! +""" +Finds updates on a package. It also looks for updates on packages that were installed manually, in case e.g. test versions of a package have been distributed prior to the full release. +""" + availableUpdate: PackageVersion + package: Package2! +} + +enum PackageInstallationSourceType { + HumioHub + ZipFile +} + +scalar PackageName + +""" +Information about a package that matches a search in a package registry. +""" +type PackageRegistrySearchResultItem { + id: VersionedPackageSpecifier! + description: String + iconUrl: UrlOrData + type: PackageType! + installedVersion: VersionedPackageSpecifier +""" +True if the current version of LogScale supports the latest version of this package. +""" + isLatestVersionSupported: Boolean! +""" +The version of LogScale required to run the latest version of this package. +""" + minHumioVersionOfLatest: SemanticVersion! +} + +scalar PackageScope + +scalar PackageTag + +enum PackageType { + application + library +} + +scalar PackageVersion + +type PageType { + number: Int! + totalNumberOfRows: Int! + total: Int! +} + +""" +The specification of a parameter +""" +type ParameterSpecificationOutput { +""" +The name of the parameter +""" + name: String! +""" +The type of the parameter" +""" + parameterType: ParameterTypeEnum! +""" +Restricts the smallest allowed value for parameters of type Long +""" + minLong: Long +""" +Restricts the largest allowed value for parameters of type Long +""" + maxLong: Long +""" + Restricts the smallest allowed value for parameters of type Double +""" + minDouble: Float +""" +Restricts the largest allowed value for parameters of type Double +""" + maxDouble: Float +""" +Restricts the minimum number of allowed elements for parameters of type Array +""" + minLength: Int +""" +Defines a default value of the parameter +""" + defaultValue: [String!] +} + +""" +The parameter types +""" +enum ParameterTypeEnum { + Field + String + Long + Double + ArrayField + ArrayString + ArrayLong + ArrayDouble +} + +""" +Parameter value configuration. +""" +type ParameterValue { +""" +Id of the parameter. +""" + id: String! +""" +Value of the parameter. +""" + value: String! +} + +""" +A configured parser for incoming data. +""" +type Parser { +""" +The id of the parser. +""" + id: String! +""" +Name of the parser. +""" + name: String! +""" +The full name of the parser including package information if part of an application. +""" + displayName: String! +""" +The description of the parser. +""" + description: String + assetType: AssetType! +""" +True if the parser is one of LogScale's built-in parsers. +""" + isBuiltIn: Boolean! +""" +The parser script that is executed for every incoming event. +""" + script: String! +""" +The source code of the parser. +""" + sourceCode: String! + languageVersion: LanguageVersion! +""" +Fields that are used as tags. +""" + fieldsToTag: [String!]! +""" +The fields to use as tags. +""" + tagFields: [String!]! +""" +A list of fields that will be removed from the event before it's parsed. These fields will not be included when calculating usage. +""" + fieldsToBeRemovedBeforeParsing: [String!]! +""" +A template that can be used to recreate the parser. +""" + yamlTemplate: YAML! +""" +Saved test data (e.g. log lines) that you can use to test the parser. +""" + testData: [String!]! +""" +Test cases that can be used to help verify that the parser works as expected. +""" + testCases: [ParserTestCase!]! + packageId: VersionedPackageSpecifier + package: PackageInstallation +} + +type ParserTemplate { + name: String! + displayName: String! + yamlTemplate: String! +} + +""" +A test case for a parser. +""" +type ParserTestCase { +""" +The event to parse and test on. +""" + event: ParserTestEvent! +""" +Assertions on the shape of the test case output events. The list consists of key-value pairs to be treated as a map-construct, where the index of the output event is the key, and the assertions are the value. +""" + outputAssertions: [ParserTestCaseAssertionsForOutput!]! +} + +""" +Assertions on the shape of the given output event. It is a key-value pair, where the index of the output event is the key, and the assertions are the value. +""" +type ParserTestCaseAssertionsForOutput { +""" +The index of the output event which the assertions should apply to. +""" + outputEventIndex: Int! +""" +Assertions on the shape of a given test case output event. +""" + assertions: ParserTestCaseOutputAssertions! +} + +""" +Assertions on the shape of a given test case output event. +""" +type ParserTestCaseOutputAssertions { +""" +Names of fields which should not be present on the output event. +""" + fieldsNotPresent: [String!]! +""" +Names of fields and their expected value on the output event. These are key-value pairs, and should be treated as a map-construct. +""" + fieldsHaveValues: [FieldHasValue!]! +} + +""" +An event for a parser to parse during testing. +""" +type ParserTestEvent { +""" +The contents of the `@rawstring` field when the event begins parsing. +""" + rawString: String! +} + +""" +A subset of a view +""" +type PartialSearchDomain { + id: String! + name: String! +""" +Check if the current user is allowed to perform the given action on the view. +""" + isActionAllowed( +""" +The action to check if a user is allowed to perform on a view. +""" + action: ViewAction! + ): Boolean! +} + +""" +A pending user. I.e. a user that was invited to join an organization. +""" +type PendingUser { +""" +The id or token for the pending user +""" + id: String! +""" +Whether IDP is enabled for the organization +""" + idp: Boolean! +""" +The time the pending user was created +""" + createdAt: Long! +""" +The email of the user that invited the pending user +""" + invitedByEmail: String! +""" +The name of the user that invited the pending user +""" + invitedByName: String! +""" +The name of the organization the the pending user is about to join +""" + orgName: String! +""" +The email of the pending user +""" + newUserEmail: String! +""" +The current organization state for the user, if any. +""" + pendingUserState: PendingUserState! +} + +""" +The current organization state for the user. +""" +enum PendingUserState { + NoOrganization + SingleUserOrganization + MultiUserOrganizationOnlyOwnerConflict + MultiUserOrganizationNoConflict + UserExistsNoOrganization + UserExistsDeletedOrganization +} + +""" +Permissions on a view +""" +enum Permission { + ChangeUserAccess +""" +Permission to administer alerts, scheduled searches and actions +""" + ChangeTriggersAndActions +""" +Permission to administer alerts and scheduled searches +""" + ChangeTriggers +""" +Permission to administer actions +""" + ChangeActions + ChangeDashboards + ChangeDashboardReadonlyToken + ChangeFiles + ChangeInteractions + ChangeParsers + ChangeSavedQueries + ConnectView + ChangeDataDeletionPermissions + ChangeRetention + ChangeDefaultSearchSettings + ChangeS3ArchivingSettings + DeleteDataSources + DeleteRepositoryOrView + DeleteEvents + ReadAccess + ChangeIngestTokens + ChangePackages + ChangeViewOrRepositoryDescription + ChangeConnections +""" +Permission to administer event forwarding rules +""" + EventForwarding + QueryDashboard + ChangeViewOrRepositoryPermissions + ChangeFdrFeeds + OrganizationOwnedQueries + ReadExternalFunctions + ChangeIngestFeeds + ChangeScheduledReports +} + +""" +The type of permission +""" +enum PermissionType { + AssetPermission + ViewPermission + OrganizationPermission + OrganizationManagementPermission + SystemPermission +} + +""" +Personal token for a user. The token will inherit the same permissions as the user. +""" +type PersonalUserToken implements Token{ +""" +The id of the token. +""" + id: String! +""" +The name of the token. +""" + name: String! +""" +The time at which the token expires. +""" + expireAt: Long +""" +The ip filter on the token. +""" + ipFilter: String +""" +The ip filter on the token. +""" + ipFilterV2: IPFilter +""" +The date the token was created. +""" + createdAt: Long! +} + +type Query { +""" +[PREVIEW: Experimental feature, not ready for production.] All actions, labels and packages used in alerts. +""" + alertFieldValues( +""" +Arguments for alert field values query. +""" + input: AlertFieldValuesInput! + ): AlertFieldValues! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Get allowed asset actions for the logged in user on a specific asset +""" + allowedAssetActions( +""" +Id of the asset +""" + assetId: String! +""" +Asset type +""" + assetType: AssetPermissionsAssetType! +""" +The name of the search domain that the asset belongs to +""" + searchDomainName: String + ): [AssetAction!]! +""" +Analyze a query for certain properties +""" + analyzeQuery( + input: AnalyzeQueryArguments! + ): AnalyzeQueryInfo! +""" +Returns information about the IP ASN database used by the LogScale instance. +""" + asnDatabaseInfo: IpDatabaseInfo! +""" +This fetches the list of blocked query patterns. +""" + blockedQueries( +""" +Whether to return all blocked queries within the cluster. Requires the ManageCluster permission. +""" + clusterWide: Boolean + ): [BlockedQuery!]! +""" +This is used to check if a given domain is valid. +""" + checkDomain( + domain: String! + ): Boolean! +""" +Validate a local cluster connection. +""" + checkLocalClusterConnection( +""" +Data for checking a local cluster connection +""" + input: CheckLocalClusterConnectionInput! + ): LocalClusterConnectionStatus! +""" +Validate a remote cluster connection. +""" + checkRemoteClusterConnection( +""" +Data for checking a remote cluster connection +""" + input: CheckRemoteClusterConnectionInput! + ): RemoteClusterConnectionStatus! +""" +[PREVIEW: Feature still in development] Get linked child organizations +""" + childOrganizations( + search: String + skip: Int! + limit: Int! +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + sortBy: OrganizationsLinks__SortBy + ): ChildOrganizationsResultSet! +""" +This is used to retrieve information about a cluster. +""" + cluster: Cluster! +""" +Return the cluster management settings for this LogScale cluster. +""" + clusterManagementSettings: ClusterManagementSettings +""" +Concatenate multiple valid queries into a combined query. +""" + concatenateQueries( + input: ConcatenateQueriesArguments! + ): QueryConcatenationInfo! +""" +This returns the current authenticated user. +""" + currentUser: User! +""" +This is used to retrieve a dashboard. +""" + dashboardsPage( + search: String + pageNumber: Int! + pageSize: Int! + ): DashboardPage! +""" +[PREVIEW: Internal debugging] For internal debugging +""" + debugCache( + searchKeys: [String!]! + ): String! +""" +This returns the current value for the dynamic configuration. +""" + dynamicConfig( + dynamicConfig: DynamicConfig! + ): String! +""" +Returns all dynamic configurations. Requires root access. +""" + dynamicConfigs: [DynamicConfigKeyValueType!]! +""" +[PREVIEW: Under development] Get next and previous pages when querying assets across LogScale views and repositories. Requires the cursor from the entitiesSearch or entitiesPage response as well as a direction +""" + entitiesPage( +""" +input parameters for the page +""" + input: EntitiesPageInputType! + ): SearchResult! +""" +[PREVIEW: Under development] Query assets across LogScale views and repositories. Will only return the first page. The response includes a cursor that can be sent to entitiesPage to get next pages with the same parameters +""" + entitiesSearch( +""" +input parameters for the search +""" + input: EntitySearchInputType! + ): SearchResult! +""" +Get usage information around non-secret environment variables +""" + environmentVariableUsage: [EnvironmentVariableUsage!]! +""" +This will list all of the event forwarders associated with an organization. +""" + eventForwarders: [EventForwarder!]! +""" +This is used to determine if a given user has exceeded their query quota. +""" + exceededQueryQuotas( +""" +Username of the user for which to retrieve exceeded Query Quotas +""" + username: String! + ): [QueryQuotaExceeded!]! +""" +[PREVIEW: All flags should be considered as beta features. Enabling features that are marked as experimental is strongly discouraged and can lead to LogScale ending up in a bad state beyond repair.] List feature flags depending on filters and context +""" + featureFlags( +""" +Include experimental features. Enabling experimental features are strongly discouraged and can lead to LogScale ending up in a bad state beyond repair. +""" + includeExperimentalFeatures: Boolean +""" +Filter defining for which scope feature flags should be returned +""" + enabledInScopeFilter: EnabledInScope + ): [FeatureFlagV2!]! +""" +This can fetch the OIDC metadata from the discovery (.well-known/openid-configuration) endpoint provided. +""" + fetchOIDCMetadataFromDiscoveryEndpoint( +""" +The .well-known OIDC endpoint. +""" + discoveryEndpoint: String! + ): WellKnownEndpointDetails! +""" +This will fetch the SAML metadata from the discovery endpoint provided. +""" + fetchSamlMetadataFromDiscoveryEndpoint( +""" +The SAML metadata endpoint. +""" + discoveryEndpoint: String! + ): SamlMetadata! +""" +[PREVIEW: This functionality is still under development and can change without warning.] Retrieve the active schema and its field aliases on the given view. +""" + fieldAliasSchemaOnView( + repoOrViewName: String! + ): FieldAliasSchema +""" +[PREVIEW: This functionality is still under development and can change without warning.] Retrieve all schemas for field aliases +""" + fieldAliasSchemas: FieldAliasSchemasInfo! +""" +This will find information on the identity provider. +""" + findIdentityProvider( + email: String! + ): IdentityProviderAuth! +""" +[PREVIEW: Under development.] +""" + fleetInstallationToken( + id: String! + ): FleetInstallationToken +""" +[PREVIEW: Under development.] +""" + fleetInstallationTokens: [FleetInstallationToken!]! +""" +Return the Java Flight Recorder settings for the specified vhost. +""" + flightRecorderSettings( +""" +The vhost to fetch settings for. +""" + vhost: Int! + ): FlightRecorderSettings +""" +Generate an unsaved aggregate alert from a package alert template. +""" + generateAggregateAlertFromPackageTemplate( +""" +Data for generating an unsaved aggregate alert object from a library package template +""" + input: GenerateAggregateAlertFromPackageTemplateInput! + ): UnsavedAggregateAlert! +""" +Generate an unsaved aggregate alert from a yaml template. +""" + generateAggregateAlertFromTemplate( +""" +Data for generating an unsaved aggregate alert object from a yaml template +""" + input: GenerateAggregateAlertFromTemplateInput! + ): UnsavedAggregateAlert! +""" +Generate an unsaved alert from a package alert template. +""" + generateAlertFromPackageTemplate( +""" +Data for generating an unsaved alert object from a library package template +""" + input: GenerateAlertFromPackageTemplateInput! + ): UnsavedAlert! +""" +Generate an unsaved alert from a yaml template. +""" + generateAlertFromTemplate( +""" +Data for generating an unsaved alert object from a yaml template +""" + input: GenerateAlertFromTemplateInput! + ): UnsavedAlert! +""" +Generate an unsaved filter alert from a package alert template. +""" + generateFilterAlertFromPackageTemplate( +""" +Data for generating an unsaved filter alert object from a library package template +""" + input: GenerateFilterAlertFromPackageTemplateInput! + ): UnsavedFilterAlert! +""" +Generate an unsaved filter alert from a yaml template. +""" + generateFilterAlertFromTemplate( +""" +Data for generating an unsaved filter alert object from a yaml template +""" + input: GenerateFilterAlertFromTemplateInput! + ): UnsavedFilterAlert! +""" +Generate an unsaved parser from a YAML template. +""" + generateParserFromTemplate( +""" +Data for generating an unsaved parser object from a YAML template +""" + input: GenerateParserFromTemplateInput! + ): UnsavedParser! +""" +Generate an unsaved scheduled search from a package scheduled search template. +""" + generateScheduledSearchFromPackageTemplate( +""" +Data for generating an unsaved scheduled search object from a library package template. +""" + input: GenerateScheduledSearchFromPackageTemplateInput! + ): UnsavedScheduledSearch! +""" +Generate an unsaved scheduled search from a yaml template. +""" + generateScheduledSearchFromTemplate( +""" +Data for generating an unsaved scheduled search object from a yaml templat. +""" + input: GenerateScheduledSearchFromTemplateInput! + ): UnsavedScheduledSearch! +""" +[PREVIEW: Experimental prototype not ready for production use] Look up an external function specification. +""" + getExternalFunction( + input: GetExternalFunctionInput! + ): ExternalFunctionSpecificationOutput +""" +This is used to get content of a file. +""" + getFileContent( + name: String! + fileName: String! + offset: Int + limit: Int + filterString: String + ): UploadedFileSnapshot! +""" +[PREVIEW: Under development.] +""" + getLogCollectorDebugLogging: LogCollectorDebugLogging +""" +[PREVIEW: Under development.] +""" + getLogCollectorDetails( + machineId: String! + ): LogCollectorDetails! +""" +[PREVIEW: Under development.] +""" + getLogCollectorInstanceDebugLogging( + id: String! + ): LogCollectorDebugLogging +""" +[PREVIEW: Under development.] +""" + getLostCollectorDays: Int! +""" +Used to get information on a specified group. +""" + group( + groupId: String! + ): Group! +""" +Used to get information on groups by a given display name. +""" + groupByDisplayName( + displayName: String! + ): Group! +""" +All defined groups in an organization. +""" + groupsPage( + search: String + pageNumber: Int! + pageSize: Int! + typeFilter: [PermissionType!] + ): GroupPage! +""" +This will check whether an organization has an organization root. +""" + hasOrgRoot( + orgId: String! + ): Boolean! +""" +This is used to get information on a specific identity provider. +""" + identityProvider( + id: String! + ): IdentityProviderAuthentication! + identityProviders: [IdentityProviderAuthentication!]! +""" +This returns information about the license for the LogScale instance, if any license installed. +""" + installedLicense: License +""" +Provides details for a specific package installed on a specific view. +""" + installedPackage( +""" +The id of the package. +""" + packageId: VersionedPackageSpecifier! +""" +The name of the view the package is installed in. +""" + viewName: String! + ): PackageInstallation +""" +Used to get information on the IOC database used by the LogScale instance. +""" + iocDatabaseInfo: CrowdStrikeIocStatus! +""" +This returns information about the IP location database used by the LogScale instance. +""" + ipDatabaseInfo: IpDatabaseInfo! +""" +Returns a list of IP filters. +""" + ipFilters: [IPFilter!]! +""" +This will return information about the Kafka cluster. +""" + kafkaCluster: KafkaClusterDescription! +""" +[PREVIEW: Internal testing.] Used to get language restrictions for language version. +""" + languageRestrictions( + version: LanguageVersionEnum! + ): QueryLanguageRestriction! +""" +Used to list all notifications currently set in the system. This requires root access. +""" + listNotifications: [Notification!]! +""" +[PREVIEW: Under development.] +""" + logCollectorConfiguration( + id: String! + ): LogCollectorConfiguration! +""" +List available Log Collector installers. +""" + logCollectorInstallers: [LogCollectorInstaller!] +""" +[PREVIEW: Under development.] +""" + logCollectorMergedConfiguration( + configIds: [String!]! + ): LogCollectorMergedConfiguration! +""" +List versions available through Remote Update for the LogScale Collector +""" + logCollectorVersionsAvailable: [String!]! + loginBridgeRequest: LoginBridgeRequest! + marketplace: Marketplace! +""" +This will return information about the LogScale instance +""" + meta( + url: String + ): HumioMetadata! + oidcIdentityProvider( + id: String! + ): OidcIdentityProvider! +""" +Get the current organization +""" + organization: Organization! +""" +Get a pending user. +""" + pendingUser( + token: String! + ): PendingUser! +""" +Get a pending user. +""" + pendingUsers( + search: String + ): [PendingUser!]! +""" +Proxy query through a specific organization. Root operation. +""" + proxyOrganization( + organizationId: String! + ): Query! +""" +[PREVIEW: Internal testing.] +""" + queryAnalysis( + queryString: String! + languageVersion: LanguageVersionEnum! + isLive: Boolean! + viewName: String + ): queryAnalysis! +""" +[PREVIEW: in development.] Return the query assistance for the given search, as well as the assistant version. +""" + queryAssistance( +""" +The search to assist with +""" + search: String! +""" +Enable to remap often used fields to their LogScale equivalents +""" + remapFields: Boolean! + ): QueryAssistantResult! + queryQuotaDefaultSettings: [QueryQuotaIntervalSetting!]! + queryQuotaUsage( +""" +Username of the user for which to retrieve status of Query Quotas +""" + username: String! + ): [QueryQuotaUsage!]! + queryQuotaUserSettings( +""" +If omitted, returns the Query Quota Settings for all users. If provided, returns the Query Quota Settings for that particular user. +""" + username: String + ): [QueryQuotaUserSettings!]! +""" +Query search domains with organization filter +""" + querySearchDomains( +""" +Filter results based on this string +""" + searchFilter: String +""" +Choose to filter based on type of search domain +""" + typeFilter: SearchDomainTypes! + sortBy: Searchdomain__SortBy! +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +Filter for deleted search domains. True will return deleted search domains and exclude regular search domains and requires that you have some permission that grants you access to delete search domains. False or nothing will return search domains that has not yet been deleted. +""" + deleted: Boolean + includeHidden: Boolean +""" +Filter results by name of connected limit. Search domains without a limit will be excluded +""" + limitName: String + ): SearchDomainSearchResultSet! +""" +Fetch the list of active event redaction jobs. +""" + redactEvents( +""" +The name of the repository to fetch pending event redactions for. +""" + repositoryName: String! + ): [DeleteEvents!]! + repositories( +""" +Include sandboxes for other users in the results set +""" + includeSandboxes: Boolean + includeHidden: Boolean + ): [Repository!]! +""" +Lookup a given repository by name. +""" + repository( +""" +The name of the repository +""" + name: String! + includeHidden: Boolean + ): Repository! +""" +A given role. +""" + role( + roleId: String! + ): Role! +""" +All defined roles. +""" + roles: [Role!]! +""" +All defined roles in org. +""" + rolesInOrgForChangingUserAccess( + searchDomainId: String! + ): [Role!]! +""" +Searchable paginated roles +""" + rolesPage( + search: String + pageNumber: Int! + pageSize: Int! + typeFilter: [PermissionType!] + includeHidden: Boolean + ): RolePage! +""" +Returns running queries. +""" + runningQueries( +""" +Search term that is used to filter running queries based on query input +""" + searchTerm: String +""" +Which field to use when sorting +""" + sortField: SortField + sortOrder: SortOrder +""" +Whether to return global results. Default=false. True requires system level access. +""" + global: Boolean + ): RunningQueries! + samlIdentityProvider( + id: String! + ): SamlIdentityProvider! + savedQuery( + id: String! + ): SavedQuery! +""" +Get scheduled report information using a scheduled report access token. +""" + scheduledReport: LimitedScheduledReport! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Search asset permissions assigned to groups and/or users +""" + searchAssetPermissions( +""" +Id of the asset +""" + assetId: String! +""" +Asset type +""" + assetType: AssetPermissionsAssetType! +""" +The name of the search domain to search within +""" + searchDomainName: String +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +List of user ids to limit the search to +""" + userIds: [String!] +""" +List of group ids to limit the search to +""" + groupIds: [String!] + ): AssetPermissionSearchResultSet! + searchDomain( + name: String! + ): SearchDomain! + searchDomains( + includeHidden: Boolean + ): [SearchDomain!]! +""" +Paged searchDomains. +""" + searchDomainsPage( + search: String + includeHidden: Boolean + pageNumber: Int! + pageSize: Int! + ): SearchDomainPage! +""" +[PREVIEW: Under development.] Get paginated search results. +""" + searchFleet( + isLiveFilter: Boolean + groupIdsFilter: [String!] + changeFilter: Changes + groupFilter: GroupFilter + queryState: String + inactiveFilter: Boolean + statusFilter: SearchFleetStatusFilter + testConfigIdFilter: String + configIdFilter: String +""" +Filter results based on this string +""" + searchFilter: String + sortBy: Fleet__SortBy +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): SearchFleetUnion! +""" +[PREVIEW: Under development.] +""" + searchFleetInstallationTokens( +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + sortBy: FleetInstallationTokens__SortBy +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + ): SearchFleetInstallationTokenResultSet! +""" +[PREVIEW: Under development.] Search log collector configurations. +""" + searchLogCollectorConfigurations( +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + sortBy: FleetConfiguration__SortBy +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + ): SearchLogCollectorConfigurationResultSet! +""" +[PREVIEW: Under development.] Search log collector configurations. +""" + searchLogCollectorGroups( +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + sortBy: FleetGroups__SortBy +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + ): SearchLogCollectorGroupsResultSet! +""" +Get paginated search results. (Root operation) +""" + searchOrganizations( +""" +Filter results based on this string +""" + searchFilter: String + sortBy: Organizations__SortBy! + typeFilter: [Organizations__SearchEntryType!] + subscriptionFilter: [Organizations__Subscription!] + includeDeletedFilter: Boolean +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): OrganizationSearchResultSet! +""" +[PREVIEW: Part of the ScheduledReports feature under development] Check the status for a specific typed service. +""" + serviceStatus( +""" +The service type name of the service to get status for. +""" + serviceType: String! + ): HealthStatus! +""" +[PREVIEW: Part of the ScheduledReports feature under development] Metadata from all registered services +""" + servicesMetadata: [ServiceMetadata!]! +""" +Paginated search results for tokens +""" + sessions( +""" +Filter results based on this string +""" + searchFilter: String + level: Sessions__Filter_Level + sortBy: Sessions__SortBy +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + onlyActiveSessions: Boolean + ): SessionQueryResultSet! +""" +Gets a shared dashboard by it's shared link token. +""" + sharedDashboards( + token: String! + ): SharedDashboard! + starredDashboards: [Dashboard!]! +""" +[PREVIEW: Under development.] Token for fleet management. +""" + tokenForFleetManagement: String! +""" +Paginated search results for tokens +""" + tokens( +""" +Filter results based on this string +""" + searchFilter: String + typeFilter: [Tokens__Type!] + parentEntityIdFilter: [String!] + sortBy: Tokens__SortBy! +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): TokenQueryResultSet! +""" +[PREVIEW: BETA feature.] +""" + usage: UsageStats! +""" +A user in the system. +""" + user( + id: String! + ): User +""" +Requires manage cluster permission; Returns all users in the system. +""" + users( + orderBy: OrderByUserFieldInput + search: String + ): [User!]! + usersAndGroupsForChangingUserAccess( + search: String + searchDomainId: String! +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): UsersAndGroupsSearchResultSet! +""" +Requires either root access, org owner access or permission to manage users in at least one repository or view. Returns a page of all users in an organization. +""" + usersPage( + orderBy: OrderByUserFieldInput + search: String + pageNumber: Int! + pageSize: Int! + ): UsersPage! +""" +Return users without organizations +""" + usersWithoutOrganizations: [User!]! +""" +Validate the Access Token +""" + validateAccessToken( + accessToken: String! + ): String! +""" +Validate the Access Token +""" + validateAccessTokenV2( + accessToken: String! + ): AccessTokenValidatorResultType! +""" +[PREVIEW: Internal testing.] Check that a query compiles. +""" + validateQuery( + queryString: String! + version: LanguageVersionEnum! + isLive: Boolean + arguments: [QueryArgument!] + ): QueryValidationResult! +""" +Validate the JWT Token +""" + validateToken( + jwtToken: String! + ): Boolean! +""" +The currently authenticated user's account. +""" + viewer: Account! +""" +The currently authenticated user's account if any. +""" + viewerOpt: Account +""" +[PREVIEW: Internal debugging tool, do not use without explicit instruction from support] Get the list of keys being used to select queries for tracing on workers. +""" + workerQueryTracingState: WorkerQueryTracingState! +} + +""" +An argument to a query +""" +input QueryArgument { +""" +An argument to a query +""" + name: String! +""" +An argument to a query +""" + value: String! +} + +""" +An argument for a query. +""" +input QueryArgumentInputType { +""" +An argument for a query. +""" + name: String! +""" +An argument for a query. +""" + value: String! +} + +""" +Either a successful assistance result, or an error +""" +union QueryAssistantAssistance =QueryAssistantSuccess | QueryAssistantError + +type QueryAssistantDiagnostic { + message: QueryAssistantDiagnosticMessage! + position: QueryAssistantDiagnosticPosition + severity: QueryAssistantDiagnosticSeverity! +} + +type QueryAssistantDiagnosticMessage { + what: String! + terse: String! + code: String! +} + +type QueryAssistantDiagnosticPosition { + column: Int! + line: Int! + beginOffset: Int! + endOffset: Int! + longString: String! +} + +enum QueryAssistantDiagnosticSeverity { + Hint + Information + Warning + Error +} + +type QueryAssistantError { + error: String! +} + +""" +An assistance result and a version of the query assistant +""" +type QueryAssistantResult { +""" +The assistant version. +""" + version: String! +""" +The query assistance for the given search. +""" + assistance: QueryAssistantAssistance! +} + +type QueryAssistantSuccess { + result: String! + diagnostics: [QueryAssistantDiagnostic!]! +} + +""" +An interaction for a query based widget +""" +type QueryBasedWidgetInteraction { + name: String! + titleTemplate: String + conditions: [WidgetInteractionCondition!]! + typeInfo: QueryBasedWidgetInteractionTypeInfo! +} + +union QueryBasedWidgetInteractionTypeInfo =DashboardLinkInteraction | CustomLinkInteraction | SearchLinkInteraction | UpdateParametersInteraction + +""" +Result of concatenating queries. +""" +type QueryConcatenationInfo { + concatenatedQuery: String! + validationResult: QueryValidationInfo! +} + +""" +A diagnostic message from query validation. +""" +type QueryDiagnostic { +""" +[PREVIEW: Internal testing.] +""" + message: String! +""" +[PREVIEW: Internal testing.] +""" + code: String! +""" +[PREVIEW: Internal testing.] +""" + severity: Severity! +} + +""" +Diagnostic information for a query. +""" +type QueryDiagnosticInfoOutputType { +""" +The diagnostic message. +""" + message: String! +""" +The code for the diagnostic. +""" + code: String! +""" +The severity of the diagnostic. +""" + severity: String! +} + +type QueryInProgress { + queryId: String! +} + +""" +Language restrictions for language version. +""" +type QueryLanguageRestriction { + version: LanguageVersion! + allowedFunctions: [String!]! + enabled: Boolean! +} + +""" +Query ownership +""" +interface QueryOwnership { +""" +Query ownership +""" + id: String! +} + +type QueryPrefixes { + viewId: String! + queryPrefix: String! +} + +type QueryQuotaExceeded { + kind: QueryQuotaMeasurementKind! + resetsAt: Long! +} + +enum QueryQuotaInterval { + PerDay + PerHour + PerTenMinutes + PerMinute +} + +type QueryQuotaIntervalSetting { + interval: QueryQuotaInterval! + measurementKind: QueryQuotaMeasurementKind! + value: Long + valueKind: QueryQuotaIntervalSettingKind! + source: QueryQuotaIntervalSettingSource! +} + +enum QueryQuotaIntervalSettingKind { + Limitless + Limited +} + +enum QueryQuotaIntervalSettingSource { + Default + UserSpecified +} + +enum QueryQuotaMeasurementKind { + StaticCost + LiveCost + QueryCount +} + +type QueryQuotaUsage { + interval: QueryQuotaInterval! + queryCount: Int! + staticCost: Long! + liveCost: Long! +} + +""" +Query Quota Settings for a particular user +""" +type QueryQuotaUserSettings { +""" +Username of the user for which these Query Quota Settings apply +""" + username: String! +""" +List of the settings that apply +""" + settings: [QueryQuotaIntervalSetting!]! +} + +""" +Timestamp type to use for a query. +""" +enum QueryTimestampType { +""" +Use @timestamp for the query. +""" + EventTimestamp +""" +Use @ingesttimestamp for the query. +""" + IngestTimestamp +} + +""" +Result of query validation. +""" +type QueryValidationInfo { + isValid: Boolean! + diagnostics: [QueryDiagnosticInfoOutputType!]! +} + +""" +Result of validating a query. +""" +type QueryValidationResult { +""" +[PREVIEW: Internal testing.] +""" + isValid: Boolean! +""" +[PREVIEW: Internal testing.] +""" + diagnostics: [QueryDiagnostic!]! +} + +type RealTimeDashboardUpdateFrequency { + name: String! +} + +""" +A map from reasons why a node might not be able to be unregistered safely, to the boolean value indicating whether a given reason applies to this node. For a node to be unregistered without any undue disruption, none of the reasons must apply. +""" +type ReasonsNodeCannotBeSafelyUnregistered { + isAlive: Boolean! + leadsDigest: Boolean! + hasUnderReplicatedData: Boolean! + hasDataThatExistsOnlyOnThisNode: Boolean! +} + +type RecentQuery { + languageVersion: LanguageVersion! + query: HumioQuery! + runAt: DateTime! + widgetType: String + widgetOptions: JSON +} + +""" +Information about regions +""" +type RegionSelectData { + name: String! + url: String! + iconUrl: String! +} + +""" +Info about a version of a LogScale Package. +""" +type RegistryPackageVersionInfo { +""" +The package version +""" + version: SemanticVersion! +""" +The minimum version of LogScale required to run the package. +""" + minHumioVersion: SemanticVersion! +} + +""" +The status of a remote cluster connection. +""" +type RemoteClusterConnectionStatus implements ClusterConnectionStatus{ +""" +Name of the remote view +""" + remoteViewName: String +""" +Software version of the remote view +""" + remoteServerVersion: String +""" +Oldest server version that is protocol compatible with the remote server +""" + remoteServerCompatVersion: String +""" +Id of the connection +""" + id: String +""" +Whether the connection is valid +""" + isValid: Boolean! +""" +Errors if the connection is invalid +""" + errorMessages: [ConnectionAspectErrorType!]! +} + +scalar RepoOrViewName + +type RepositoriesUsageQueryResult { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [RepositoryUsageValue!]! +} + +""" +Query result for repositories usage data +""" +union RepositoriesUsageQueryResultTypes =QueryInProgress | RepositoriesUsageQueryResult + +enum RepositoriesUsageQuerySortBy { + Name + UsageValue +} + +""" +A repository stores ingested data, configures parsers and data retention policies. +""" +type Repository implements SearchDomain{ +""" +Repo Types are used for tracking trial status in LogScale Cloud setups. +""" + type: RepositoryType! +""" +Repo data types are used for controlling the types of data are allowed in the repository. +""" + dataType: RepositoryDataType! +""" +The limit attached to the repository. +""" + limit: LimitV2 +""" +The date and time in the future after which ingest for this repository will be re-enabled. +""" + ingestBlock: DateTime +""" +Usage tag, used to group usage summary on repositories +""" + usageTag: String +""" +Data sources where data is ingested from. E.g. This can be specific log files or services sending data to LogScale. +""" + datasources: [Datasource!]! +""" +Total size the data. Size is measured as the size stored before compression and is thus the size of the internal format, not the data that was ingested. +""" + uncompressedByteSize: Long! +""" +Total size of data. Size is measured as the size after compression. +""" + compressedByteSize: Long! +""" +Total size the data, merged parts. Size is measured as the size stored before compression and is thus the size of the internal format, not the data that was ingested. +""" + uncompressedByteSizeOfMerged: Long! +""" +Total size of data, merged parts. Size is measured as the size after compression. +""" + compressedByteSizeOfMerged: Long! +""" +The timestamp of the latest ingested data, or null if the repository is empty. +""" + timeOfLatestIngest: DateTime +""" +The maximum time (in days) to keep data. Data old than this will be deleted. +""" + timeBasedRetention: Float +""" +Retention (in Gigabytes) based on the size of data when it arrives to LogScale, that is before parsing and compression. LogScale will keep `at most` this amount of data. +""" + ingestSizeBasedRetention: Float + ingestTokens: [IngestToken!]! +""" +Retention (in Gigabytes) based on the size of data when in storage, that is, after parsing and compression. LogScale will keep `at least` this amount of data, but as close to this number as possible. +""" + storageSizeBasedRetention: Float +""" +Sets time (in days) to keep backups before they are deleted. +""" + timeBasedBackupRetention: Float +""" +The ingest listeners configured for this repository. +""" + ingestListeners: [IngestListener!]! +""" +Maximum number of auto shards created. +""" + maxAutoShardCount: Int +""" +Configuration for S3 archiving. E.g. bucket name and region. +""" + s3ArchivingConfiguration: S3Configuration +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] The cache policy set on this repo. +""" + cachePolicy: CachePolicy +""" +[PREVIEW: Cache policies are a limited feature and is subject to change] The cache policy of this repo that as will be applied. + +This will apply the cache policy of the repo, org-wide default, or global +default. This will be (in order of precedence): + 1. The repo cache policy, if set. + 2. The organization-wide cache policy, if set. + 3. The global cache policy, if set. + 4. The default cache policy in which no segments are prioritized. + +""" + effectiveCachePolicy: CachePolicy! +""" +Tag grouping rules applied on the repository currently. Rules only apply to the tags they denote, and tags without rules do not have any grouping. +""" + currentTagGroupings: [TagGroupingRule!]! +""" +The AWS External ID used when assuming roles in AWS on behalf of this repository. +""" + awsExternalId: String! +""" +The event forwarding rules configured for the repository +""" + eventForwardingRules: [EventForwardingRule!]! +""" +List event forwarders in the organization with only basic information +""" + eventForwardersForSelection: [EventForwarderForSelection!]! +""" +A saved FDR feed. +""" + fdrFeed( +""" +The id of the FDR feed to get. +""" + id: String! + ): FdrFeed! +""" +Saved FDR Feeds +""" + fdrFeeds: [FdrFeed!]! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Administrator control for an FDR feed. +""" + fdrFeedControl( +""" +The id of the FDR feed to get administrator control for. +""" + id: String! + ): FdrFeedControl! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Administrator controls for FDR feeds +""" + fdrFeedControls: [FdrFeedControl!]! +""" +[PREVIEW: Experimental feature, not ready for production.] A saved Ingest feed. +""" + ingestFeed( +""" +The id of the IngestFeed to get. +""" + id: String! + ): IngestFeed! +""" +[PREVIEW: Experimental feature, not ready for production.] Saved ingest feeds +""" + ingestFeeds( +""" +Filter results based on this string +""" + searchFilter: String +""" +Type of ingest feed to filter +""" + typeFilter: [IngestFeeds__Type!] +""" +Field which to sort the ingest feeds by +""" + sortBy: IngestFeeds__SortBy! +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): IngestFeedQueryResultSet! +""" +A parser on the repository. +""" + parser( + id: String +""" +[DEPRECATED: Please use `id` instead. Will be removed in version 1.136] +""" + name: String + ): Parser +""" +Saved parsers. +""" + parsers: [Parser!]! + id: String! + name: RepoOrViewName! + description: String +""" +The point in time the search domain was marked for deletion. +""" + deletedDate: Long +""" +The point in time the search domain will not be restorable anymore. +""" + permanentlyDeletedAt: Long + isStarred: Boolean! +""" +Search limit in milliseconds, which searches should are limited to. +""" + searchLimitedMs: Long +""" +Repositories not part of the search limitation. +""" + reposExcludedInSearchLimit: [String!]! +""" +Returns a specific version of a package given a package version. +""" + packageV2( +""" +The package id of the package to get. +""" + packageId: VersionedPackageSpecifier! + ): Package2! +""" +[PREVIEW: This may be moved to the Package2 object.] The available versions of a package. +""" + packageVersions( + packageId: UnversionedPackageSpecifier! + ): [RegistryPackageVersionInfo!]! +""" +Returns a list of available packages that can be installed. +""" + availablePackages( +""" +Filter input to limit the returned packages +""" + filter: String +""" +Packages with any of these tags will be included. No filtering on tags. +""" + tags: [PackageTag!] +""" +Packages with any of these categories will be included. +""" + categories: [String!] + ): [PackageRegistrySearchResultItem!]! +""" +List packages installed on a specific view or repo. +""" + installedPackages: [PackageInstallation!]! + hasPackageInstalled( + packageId: VersionedPackageSpecifier! + ): Boolean! +""" +Users who has access. +""" + users: [User!]! +""" +Users or groups who has access. +""" + usersAndGroups( + search: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): UsersAndGroupsSearchResultSet! +""" +[PREVIEW] Search users with a given permission +""" + usersV2( +""" +Search for a user whose email or name matches this search string +""" + search: String +""" +Permission that the users must have on the search domain. Leave out to get users with any permission on the view +""" + permissionFilter: Permission +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): Users! +""" +Groups with assigned roles. +""" + groups: [Group!]! + starredFields: [String!]! + recentQueriesV2: [RecentQuery!]! + automaticSearch: Boolean! +""" +Check if the current user is allowed to perform the given action on the view. +""" + isActionAllowed( +""" +The action to check if a user is allowed to perform on a view. +""" + action: ViewAction! + ): Boolean! +""" +Returns the all actions the user is allowed to perform on the view. +""" + allowedViewActions: [ViewAction!]! +""" +The query prefix prepended to each search in this domain. +""" + viewerQueryPrefix: String! +""" +All tags from all datasources. +""" + tags: [String!]! +""" +All interactions defined on the view. +""" + interactions: [ViewInteraction!]! +""" +A saved alert +""" + alert( + id: String! + ): Alert! +""" +Saved alerts. +""" + alerts: [Alert!]! +""" +A saved dashboard. +""" + dashboard( + id: String! + ): Dashboard! +""" +All dashboards available on the view. +""" + dashboards: [Dashboard!]! +""" +A saved filter alert +""" + filterAlert( + id: String! + ): FilterAlert! +""" +Saved filter alerts. +""" + filterAlerts: [FilterAlert!]! +""" +A saved aggregate alert +""" + aggregateAlert( + id: String! + ): AggregateAlert! +""" +Saved aggregate alerts. +""" + aggregateAlerts: [AggregateAlert!]! +""" +A saved scheduled search. +""" + scheduledSearch( +""" +The id of the scheduled search to get. +""" + id: String! + ): ScheduledSearch! +""" +Saved scheduled searches. +""" + scheduledSearches: [ScheduledSearch!]! +""" +A saved action. +""" + action( +""" +The id of the action to get. +""" + id: String! + ): Action! +""" +A list of saved actions. +""" + actions: [Action!]! +""" +A saved query. +""" + savedQuery( + id: String! + ): SavedQuery! +""" +Saved queries. +""" + savedQueries: [SavedQuery!]! + defaultQuery: SavedQuery + files: [File!]! + fileFieldSearch( +""" +Name of the csv or json file to retrieve the field entries from. +""" + fileName: String! +""" +Name of the field in the file to return entries from. +""" + fieldName: String! +""" +Text to filter values by prefix on. +""" + prefixFilter: String +""" +The exact values that given fields should have for an entry to be part of the result. +""" + valueFilters: [FileFieldFilterType!]! +""" +Names of the fields to include in the result. +""" + fieldsToInclude: [String!]! +""" +Maximum number of values to retrieve from the file. +""" + maxEntries: Int! + ): [[DictionaryEntryType!]!]! +""" +Saved scheduled reports. +""" + scheduledReports: [ScheduledReport!]! +""" +Saved scheduled report. +""" + scheduledReport( +""" +The id of the scheduled report to get. +""" + id: String! + ): ScheduledReport +} + +""" +The data type of a repository. Indicates which type of data the repository is restricted to - e.g. 'Falcon' for repository intended for Falcon data +""" +enum RepositoryDataType { + FALCON + ANYDATA +} + +""" +The repository type of a repository +""" +enum RepositoryType { + PERSONAL + TRIAL + DEFAULT + SYSTEM + MANAGED +} + +type RepositoryUsageValue { + name: String + valueBytes: Long! + percentage: Float! + id: String! +} + +type Role { + id: String! + displayName: String! + color: String + description: String + viewPermissions: [Permission!]! + systemPermissions: [SystemPermission!]! + organizationPermissions: [OrganizationPermission!]! + organizationManagementPermissions: [OrganizationManagementPermission!]! + groupsCount: Int! + usersCount: Int! + users: [User!]! + groupsV2( + search: String + userId: String + searchInRoles: Boolean + onlyIncludeGroupsWithRestrictiveQueryPrefix: Boolean +""" +The amount of results to return. +""" + limit: Int +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int + ): GroupResultSetType! + groups: [Group!]! +} + +""" +A page of roles. +""" +type RolePage { + pageInfo: PageType! + page: [Role!]! +} + +""" +The roles query result set. +""" +type RolesResultSetType { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [Role!]! +} + +""" +Queries that are currently being executed +""" +type RunningQueries { +""" +Number of milliseconds until next update is available +""" + updateAvailableIn: Long! +""" +Total number of queries being executed +""" + totalNumberOfQueries: Int! +""" +Total number of live queries being executed +""" + totalNumberOfLiveQueries: Int! +""" +Total number of clients querying +""" + totalNumberOfClients: Int! +""" +Total size of skipped bytes for all queries being executed +""" + totalSkippedBytes: Long! +""" +Total size of included bytes for all queries being executed +""" + totalIncludedBytes: Long! +""" +Total size of remaining bytes to be processed for all queries being executed +""" + totalQueuedBytes: Long! +""" +Queries being executed, at most 1000 queries are returned. +""" + queries: [RunningQuery!]! +} + +""" +A query that is currently being executed. +""" +type RunningQuery { + id: String! + clients: [Client!]! + initiatedBy: String + isLive: Boolean! + isHistoricDone: Boolean! + queryInput: String! + queryPrefix: String! + coordinatorId: String! + totalWork: Int! + workDone: Int! + view: String! +""" +The organization owning the query, if any. +""" + organization: Organization + timeInMillis: Long! + timeQueuedInMillis: Long! + isDashboard: Boolean! + estimatedTotalBytes: Long! + skippedBytes: Long! + includedBytes: Long! + processedEvents: Long! +""" +Static CPU time spent since query started +""" + mapMillis: Float! +""" +Static CPU time spent the last 30 seconds +""" + deltaMapMillis: Float! +""" +Live CPU time spent since query started +""" + liveMillis: Float! +""" +Live CPU time spent the last 30 seconds +""" + deltaLiveMillis: Float! + mapAllocations: Long! + liveAllocations: Long! + reduceAllocations: Long! + totalAllocations: Long! + deltaTotalAllocations: Long! + timeInterval: String! + timeZoneOffSetMinutes: Int! + queryArgs: String! + status: String! +""" +Total cost calculation. +""" + totalCost: Float! +""" +Live cost calculation +""" + liveCost: Float! +""" +Static cost calculation +""" + staticCost: Float! +""" +Total cost calculation last 30 seconds. +""" + deltaTotalCost: Float! +""" +Live cost calculation last 30 seconds. +""" + deltaLiveCost: Float! +""" +Static cost calculation last 30 seconds. +""" + deltaStaticCost: Float! +} + +""" +The format to store archived segments in on AWS S3. +""" +enum S3ArchivingFormat { + RAW + NDJSON +} + +""" +Configuration for S3 archiving. E.g. bucket name and region. +""" +type S3Configuration { +""" +S3 bucket name for storing archived data. Example: acme-bucket. +""" + bucket: String! +""" +The region the S3 bucket belongs to. Example: eu-central-1. +""" + region: String! +""" +Do not archive logs older than this. +""" + startFrom: DateTime +""" +Whether the archiving has been disabled. +""" + disabled: Boolean +""" +The format to store the archived data in on S3. +""" + format: S3ArchivingFormat +""" +Array of names of tag fields to use in that order in the output file names. +""" + tagOrderInName: [String!]! +} + +""" +A SAML Identity Provider +""" +type SamlIdentityProvider implements IdentityProviderAuthentication{ + id: String! + name: String! + domains: [String!]! + groupMembershipAttribute: String + idpCertificateInBase64: String! + idpEntityId: String! + signOnUrl: String! + authenticationMethod: AuthenticationMethodAuth! + userAttribute: String + adminAttribute: String + adminAttributeMatch: String + defaultIdp: Boolean! + humioManaged: Boolean! + lazyCreateUsers: Boolean! + debug: Boolean! +} + +type SamlMetadata { + entityID: String! + signOnUrl: String! + certificate: String! +} + +""" +A query saved for later use. +""" +type SavedQuery { +""" +A YAML formatted string that describes the saved query. +""" + templateYaml: String! + id: String! + name: String! + displayName: String! + description: String + assetType: AssetType! + query: HumioQuery! + isStarred: Boolean! + widgetType: String! + options: JSON! + packageId: VersionedPackageSpecifier + package: PackageInstallation +""" +[PREVIEW: Saved query interactions feature is under preview] +""" + interactions: [QueryBasedWidgetInteraction!]! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +type SavedQueryTemplate { + name: String! + displayName: String! + yamlTemplate: String! +} + +type ScannedData { + currentBytes: Long! + limit: UsageLimit! +} + +""" +A scheduled report schedule properties +""" +type Schedule { +""" +Cron pattern describing the schedule to execute the report on. +""" + cronExpression: String! +""" +Timezone of the schedule. Examples include UTC, Europe/Copenhagen. +""" + timeZone: String! +""" +Start date of the active period of the schedule. +""" + startDate: Long! +""" +Optional end date of the active period of the schedule. +""" + endDate: Long +} + +""" +Information about a scheduled report +""" +type ScheduledReport { +""" +Id of the scheduled report. +""" + id: String! +""" +Name of the scheduled report. +""" + name: String! +""" +Flag indicating whether a password is defined for the report. +""" + isPasswordDefined: Boolean! +""" +Flag indicating whether the scheduled report is enabled. +""" + enabled: Boolean! +""" +Status of the latest report execution. +""" + status: String! +""" +Description of the scheduled report. +""" + description: String! +""" +The id of the dashboard the report was created for. +""" + dashboardId: String! +""" +The dashboard the report was created for. +""" + dashboard: Dashboard! +""" +Unix timestamp for the last report execution. The timestamp only indicates an attempt, not if it was successful. +""" + timeOfLastReportExecution: Long +""" +Unix timestamp for the next planned report execution. +""" + timeOfNextPlannedReportExecution: Long +""" +Last errors encountered while generating the scheduled report. +""" + lastExecutionErrors: [String!]! +""" +Last warnings encountered while generating the scheduled report. +""" + lastExecutionWarnings: [String!]! +""" +User who created the report. +""" + createdBy: User +""" +Date when the report was created. +""" + creationDate: String! +""" +Start of the relative time interval for the dashboard. +""" + timeIntervalStart: String +""" +The schedule to run the report by. +""" + schedule: Schedule! +""" +Labels attached to the scheduled report. +""" + labels: [String!]! +""" +List of parameter value configurations. +""" + parameters: [ParameterValue!]! +""" +List of recipients who should receive an email with the generated report. +""" + recipients: [String!]! +""" +Layout of the scheduled report. +""" + layout: ScheduledReportLayout! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +""" +Information about a scheduled report layout +""" +type ScheduledReportLayout { +""" +Paper size. Supported types are A4 and Letter. +""" + paperSize: String! +""" +Paper orientation. Supported types are Landscape and Portrait. +""" + paperOrientation: String! +""" +Paper layout. Supported types are List and Grid. +""" + paperLayout: String! +""" +Flag indicating whether to show report description. +""" + showDescription: Boolean +""" +Flag indicating whether to show title on frontpage. +""" + showTitleFrontpage: Boolean! +""" +Flag indicating whether to show parameters. +""" + showParameters: Boolean! +""" +Max number of rows to display in tables. +""" + maxNumberOfRows: Int! +""" +Flag indicating whether to show title header. +""" + showTitleHeader: Boolean! +""" +Flag indicating whether to show export date. +""" + showExportDate: Boolean! +""" +Flag indicating whether to show footer page numbers. +""" + footerShowPageNumbers: Boolean! +} + +""" +Information about a scheduled search +""" +type ScheduledSearch { +""" +Id of the scheduled search. +""" + id: String! +""" +Name of the scheduled search. +""" + name: String! +""" +Description of the scheduled search. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +Start of the relative time interval for the query. +""" + start: String! +""" +End of the relative time interval for the query. +""" + end: String! +""" +Time zone of the schedule. Currently this field only supports UTC offsets like 'UTC', 'UTC-01' or 'UTC+12:45'. +""" + timeZone: String! +""" +Cron pattern describing the schedule to execute the query on. +""" + schedule: String! +""" +User-defined limit, which caps the number of missed searches to backfill, e.g. in the event of a shutdown. +""" + backfillLimit: Int! +""" +Flag indicating whether the scheduled search is enabled. +""" + enabled: Boolean! +""" +List of Ids for actions to fire on query result. +""" + actions: [String!]! +""" +List of actions to fire on query result. +""" + actionsV2: [Action!]! +""" +Id of user which the scheduled search is running as. +""" + runAsUser: User +""" +Unix timestamp for when last query execution finished. +""" + lastScheduledSearch: Long +""" +Unix timestamp for end of search interval for last query execution. +""" + lastExecuted: Long +""" +Unix timestamp for end of search interval for last query execution that triggered. +""" + lastTriggered: Long +""" +Unix timestamp for next planned search. +""" + timeOfNextPlannedExecution: Long +""" +Last error encountered while running the search. +""" + lastError: String +""" +Last warnings encountered while running the scheduled search. +""" + lastWarnings: [String!]! +""" +Labels added to the scheduled search. +""" + labels: [String!]! +""" +Flag indicating whether the calling user has 'starred' the scheduled search. +""" + isStarred: Boolean! +""" +A template that can be used to recreate the scheduled search. +""" + yamlTemplate: YAML! + packageId: VersionedPackageSpecifier + package: PackageInstallation +""" +Ownership of the query run by this scheduled search +""" + queryOwnership: QueryOwnership! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Allowed asset actions +""" + allowedActions: [AssetAction!]! +} + +type ScheduledSearchTemplate { + name: String! + displayName: String! + yamlTemplate: String! + labels: [String!]! +} + +type SchemaField { + name: String! + description: String +} + +""" +An asset permissions search result entry +""" +type SearchAssetPermissionsResultEntry { +""" +The unique id for the Asset +""" + assetId: String! +""" +The name of the Asset +""" + assetName: String! +""" +The type of the Asset +""" + assetType: AssetPermissionsAssetType! +""" +The search domain that the asset belongs to +""" + searchDomain: SearchDomain +""" +The asset permissions assigned to this asset +""" + permissions: [AssetPermissionOutputEnum!]! +} + +""" +Common interface for Repositories and Views. +""" +interface SearchDomain { +""" +Common interface for Repositories and Views. +""" + id: String! +""" +Common interface for Repositories and Views. +""" + name: RepoOrViewName! +""" +Common interface for Repositories and Views. +""" + description: String +""" +Common interface for Repositories and Views. +""" + deletedDate: Long +""" +Common interface for Repositories and Views. +""" + permanentlyDeletedAt: Long +""" +Common interface for Repositories and Views. +""" + isStarred: Boolean! +""" +Common interface for Repositories and Views. +""" + searchLimitedMs: Long +""" +Common interface for Repositories and Views. +""" + reposExcludedInSearchLimit: [String!]! +""" +Common interface for Repositories and Views. +""" + packageV2( + packageId: VersionedPackageSpecifier! + ): Package2! +""" +Common interface for Repositories and Views. +""" + packageVersions( + packageId: UnversionedPackageSpecifier! + ): [RegistryPackageVersionInfo!]! +""" +Common interface for Repositories and Views. +""" + availablePackages( + filter: String + tags: [PackageTag!] + categories: [String!] + ): [PackageRegistrySearchResultItem!]! +""" +Common interface for Repositories and Views. +""" + installedPackages: [PackageInstallation!]! +""" +Common interface for Repositories and Views. +""" + hasPackageInstalled( + packageId: VersionedPackageSpecifier! + ): Boolean! +""" +Common interface for Repositories and Views. +""" + users: [User!]! +""" +Common interface for Repositories and Views. +""" + usersAndGroups( + search: String + skip: Int + limit: Int + ): UsersAndGroupsSearchResultSet! +""" +Common interface for Repositories and Views. +""" + usersV2( + search: String + permissionFilter: Permission + skip: Int + limit: Int + ): Users! +""" +Common interface for Repositories and Views. +""" + groups: [Group!]! +""" +Common interface for Repositories and Views. +""" + starredFields: [String!]! +""" +Common interface for Repositories and Views. +""" + recentQueriesV2: [RecentQuery!]! +""" +Common interface for Repositories and Views. +""" + automaticSearch: Boolean! +""" +Common interface for Repositories and Views. +""" + isActionAllowed( + action: ViewAction! + ): Boolean! +""" +Common interface for Repositories and Views. +""" + allowedViewActions: [ViewAction!]! +""" +Common interface for Repositories and Views. +""" + viewerQueryPrefix: String! +""" +Common interface for Repositories and Views. +""" + tags: [String!]! +""" +Common interface for Repositories and Views. +""" + interactions: [ViewInteraction!]! +""" +Common interface for Repositories and Views. +""" + alert( + id: String! + ): Alert! +""" +Common interface for Repositories and Views. +""" + alerts: [Alert!]! +""" +Common interface for Repositories and Views. +""" + dashboard( + id: String! + ): Dashboard! +""" +Common interface for Repositories and Views. +""" + dashboards: [Dashboard!]! +""" +Common interface for Repositories and Views. +""" + filterAlert( + id: String! + ): FilterAlert! +""" +Common interface for Repositories and Views. +""" + filterAlerts: [FilterAlert!]! +""" +Common interface for Repositories and Views. +""" + aggregateAlert( + id: String! + ): AggregateAlert! +""" +Common interface for Repositories and Views. +""" + aggregateAlerts: [AggregateAlert!]! +""" +Common interface for Repositories and Views. +""" + scheduledSearch( + id: String! + ): ScheduledSearch! +""" +Common interface for Repositories and Views. +""" + scheduledSearches: [ScheduledSearch!]! +""" +Common interface for Repositories and Views. +""" + action( + id: String! + ): Action! +""" +Common interface for Repositories and Views. +""" + actions: [Action!]! +""" +Common interface for Repositories and Views. +""" + savedQuery( + id: String! + ): SavedQuery! +""" +Common interface for Repositories and Views. +""" + savedQueries: [SavedQuery!]! +""" +Common interface for Repositories and Views. +""" + defaultQuery: SavedQuery +""" +Common interface for Repositories and Views. +""" + files: [File!]! +""" +Common interface for Repositories and Views. +""" + fileFieldSearch( + fileName: String! + fieldName: String! + prefixFilter: String + valueFilters: [FileFieldFilterType!]! + fieldsToInclude: [String!]! + maxEntries: Int! + ): [[DictionaryEntryType!]!]! +""" +Common interface for Repositories and Views. +""" + scheduledReports: [ScheduledReport!]! +""" +Common interface for Repositories and Views. +""" + scheduledReport( + id: String! + ): ScheduledReport +} + +""" +A page of searchDomains. +""" +type SearchDomainPage { + pageInfo: PageType! + page: [SearchDomain!]! +} + +""" +The role assigned in a searchDomain. +""" +type SearchDomainRole { + searchDomain: SearchDomain! + role: Role! +} + +""" +The search domain search result set +""" +type SearchDomainSearchResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [SearchDomain!]! +} + +enum SearchDomainTypes { + All + Views + Repository +} + +""" +The fleet search has not finished yet +""" +type SearchFleetInProgress { + queryState: String! + totalResultsInfo: SearchFleetTotalResultInfo! +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [LogCollector!]! +} + +""" +A fleet installation token search result set +""" +type SearchFleetInstallationTokenResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [FleetInstallationToken!]! +} + +""" +A fleet search result set +""" +type SearchFleetResultSet { + queryState: String! + totalResultsInfo: SearchFleetTotalResultInfo! +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [LogCollector!]! +} + +enum SearchFleetStatusFilter { + Error + OK +} + +""" +Information about the returned result set. +""" +union SearchFleetTotalResultInfo =OnlyTotal | GroupFilterInfo + +""" +Query result for search fleet +""" +union SearchFleetUnion =SearchFleetResultSet | SearchFleetInProgress + +type SearchLinkInteraction { + repoOrViewName: RepoOrViewName + queryString: String! + arguments: [DictionaryEntryType!]! + openInNewTab: Boolean! + useWidgetTimeWindow: Boolean! +} + +""" +A log collector configuration search result set +""" +type SearchLogCollectorConfigurationResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [LogCollectorConfiguration!]! +} + +""" +A log collector group search result set +""" +type SearchLogCollectorGroupsResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [LogCollectorGroup!]! +} + +type SearchResult { +""" +The total number of results that matched the search query. Only [pageSize] elements will be returned. +""" + totalResults: Int! + data: [EntitySearchResultEntity!]! + cursor: String + hasNextPage: Boolean! + hasPreviousPage: Boolean! +} + +enum Searchdomain__SortBy { + Name + Volume + DeletedAt + LimitName +} + +""" +A dashboard section. +""" +type Section { + id: String! + title: String + description: String + collapsed: Boolean! + timeSelector: TimeInterval + widgetIds: [String!]! + order: Int! +} + +scalar SemanticVersion + +""" +Metadata about a registered service +""" +type ServiceMetadata { +""" +The name of the service +""" + name: String! +""" +The type of the service +""" + serviceType: String! +""" +The endpoint of the service +""" + endpointUrl: String! +""" +The version of the service +""" + version: String! +""" +The health status of the service +""" + healthStatus: HealthStatus! +} + +""" +An active session. +""" +type Session { +""" +The id of the session +""" + id: String! +""" +Client info. +""" + clientInfo: String! +""" +Approximate city from IP +""" + city: String +""" +Country from IP +""" + country: String +""" +The IP of the client when the session was created. +""" + ip: String! +""" +The user that created the session. +""" + user: User! +""" +The time at which the session was created. +""" + createdAt: Long +""" +The time at which the session was last active. +""" + lastActivityAt: Long +""" +If the session is the current session for the user. +""" + isCurrentSession: Boolean! +} + +""" +The session query result set +""" +type SessionQueryResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [Session!]! +} + +enum Sessions__Filter_Level { + Organization + User +} + +enum Sessions__SortBy { + LastActivityTime + LoginTime + IPAddress + Location + ClientInfo + User +} + +""" +Output diagnostic from query validation. +""" +enum Severity { + Error + Warning + Information + Hint +} + +""" +Represents information about a dashboard shared through a link. +""" +type SharedDashboard { + id: String! + name: String! + displayName: String! +""" +The ip filter on the shared dashboard. +""" + ipFilter: IPFilter + sharedTimeInterval: SharedDashboardTimeInterval +""" +The name of the repository or view queries are executed against. +""" + repoOrViewName: RepoOrViewName! + widgets: [Widget!]! + sections: [Section!]! +} + +""" +Time Interval that is active on all dashboard widgets +""" +type SharedDashboardTimeInterval { + isLive: Boolean! + start: String! + end: String! +} + +""" +Security policies for shared dashboards in the organization +""" +type SharedDashboardsSecurityPolicies { +""" +Whether shared dashboard tokens are enabled +""" + sharedDashboardsEnabled: Boolean! +""" +The IP filter that is enforced on all shared dashboards +""" + enforceIpFilter: IPFilter +} + +enum ShowTermsAndConditions { + StandardMandatoryDoDNoticeAndConsent + LogScaleEula + None +} + +enum SocialLoginField { + AllowAll + DenyAll + AllowSelected +} + +""" +Social login configuration for the organization +""" +type SocialLoginSettings { +""" +Social provider +""" + provider: SocialProviderProfile! +""" +Filter +""" + filter: SocialLoginField! +""" +Allowed users +""" + allowList: [User!]! +} + +enum SocialProviderProfile { + Google + Github + Bitbucket +} + +""" +The sort by options for asset permissions. +""" +enum SortBy { + Name + SearchDomain + Permission +} + +""" +Field to sort queries by +""" +enum SortField { + InitiatedBy + View + Age + Status + DeltaTotalMemoryAllocation + TotalMemoryAllocation + DeltaLiveCPU + TotalLiveCPU + DeltaStaticCPU + TotalStaticCPU + DeltaStaticCost + DeltaLiveCost + DeltaTotalCost + StaticCost + LiveCost + TotalCost +} + +""" +Order to sort queries by +""" +enum SortOrder { + Ascending + Descending +} + +""" +Returns a query that gives the underlying events for some specified fields. queryArguments are names of free variables in the query, prefixed with a ?.For example, 'foo=?bar | count()' has the queryArgument bar. +""" +type SourceEventsQueryResultType { +""" +[PREVIEW: Internal testing.] +""" + query: String +""" +[PREVIEW: Internal testing.] +""" + queryArguments: [String!]! +""" +[PREVIEW: Internal testing.] +""" + diagnostics: [QueryDiagnostic!]! +} + +type StorageOnDay { + date: DateTime! + storageBytes: Long! + limit: UsageLimit! +} + +""" +A cluster storage partition. It assigns cluster nodes with the responsibility of storing a segment data. +""" +type StoragePartition { + id: Int! +""" +A list of ids for the nodes responsible for the partition. The list is ordered so that the first node is the primary node and the rest are followers. +""" + nodeIds: [Int!]! +} + +type StoredData { + currentBytes: Long! + limit: UsageLimit! +} + +""" +Subdomain configuration for the organization +""" +type SubdomainConfig { +""" +The primary subdomain of the organization +""" + primarySubdomain: String! +""" +The secondary subdomains of the organization +""" + secondarySubdomains: [String!]! +""" +EnforceSubdomain, if set to true the organization can only be accessed by the subdomain, otherwise it can also be accessed directly at the cluster domain url. +""" + enforceSubdomains: Boolean! +} + +type SuggestedAlertTypeInfo { +""" +The suggested alert type. +""" + alertType: AlertType! +} + +""" +Actions a user may perform on the system. +""" +enum SystemAction { + ViewOrganizations + AdministerSystemPermissions + ChangeSubdomain + ViewSubdomain + DeleteOrganizations + AdministerOrganizations + AdministerCloud + AdministerTokens + AdministerCluster + ChangeSharedFiles +} + +""" +System permissions +""" +enum SystemPermission { + ReadHealthCheck + ViewOrganizations + ManageOrganizations + ImportOrganization + DeleteOrganizations + ChangeSystemPermissions + ManageCluster + IngestAcrossAllReposWithinCluster + DeleteHumioOwnedRepositoryOrView + ChangeUsername + ChangeFeatureFlags + ChangeSubdomains + ListSubdomains + PatchGlobal + ChangeBucketStorage + ManageOrganizationLinks +} + +""" +A tag on a datasource. +""" +type Tag { + key: String! + value: String! +} + +""" +Describes the number of groups that tag values get distributed into for a given tag. +""" +type TagGroupingRule { + tagName: String! + groupCount: Int! +} + +type TagInfo { + name: String! + value: String! +} + +""" +A time interval that represents either a fixed or relative time range. +""" +type TimeInterval { + start: String! + end: String! +} + +""" +A token. +""" +interface Token { +""" +A token. +""" + id: String! +""" +A token. +""" + name: String! +""" +A token. +""" + expireAt: Long +""" +A token. +""" + ipFilter: String +""" +A token. +""" + ipFilterV2: IPFilter +""" +A token. +""" + createdAt: Long! +} + +""" +The token query result set +""" +type TokenQueryResultSet { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [Token!]! +} + +""" +Security policies for tokens in the organization +""" +type TokenSecurityPolicies { +""" +Whether personal user tokens are enabled +""" + personalUserTokensEnabled: Boolean! +""" +Maximum time in ms a personal user token can be used before expiring (TTL) +""" + personalUserTokensEnforceExpirationAfterMs: Long +""" +The IP filter that is enforced on all personal user tokens +""" + personalUserTokensEnforceIpFilter: IPFilter +""" +Whether view permission tokens are enabled +""" + viewPermissionTokensEnabled: Boolean! +""" +Maximum time in ms a view permission token can be used before expiring (TTL) +""" + viewPermissionTokensEnforceExpirationAfterMs: Long +""" +The IP filter that is enforced on all view permission tokens +""" + viewPermissionTokensEnforceIpFilter: IPFilter +""" +Whether it is allowed to change permissions on existing view permission tokens +""" + viewPermissionTokensAllowPermissionUpdates: Boolean +""" +Whether organization permission tokens are enabled +""" + organizationPermissionTokensEnabled: Boolean! +""" +Maximum time in ms a organization permission token can be used before expiring (TTL) +""" + organizationPermissionTokensEnforceExpirationAfterMs: Long +""" +The IP filter that is enforced on all organization permission tokens +""" + organizationPermissionTokensEnforceIpFilter: IPFilter +""" +Whether it is allowed to change permissions on existing organization permission tokens +""" + organizationPermissionTokensAllowPermissionUpdates: Boolean +""" +Whether system permission tokens are enabled +""" + systemPermissionTokensEnabled: Boolean! +""" +Maximum time in ms a system permission token can be used before expiring (TTL) +""" + systemPermissionTokensEnforceExpirationAfterMs: Long +""" +The IP filter that is enforced on all system permission tokens +""" + systemPermissionTokensEnforceIpFilter: IPFilter +""" +Whether it is allowed to change permissions on existing system permission tokens +""" + systemPermissionTokensAllowPermissionUpdates: Boolean +} + +enum Tokens__SortBy { + ExpirationDate + Name +} + +enum Tokens__Type { + ViewPermissionToken + OrganizationPermissionToken + OrganizationManagementPermissionToken + SystemPermissionToken +} + +""" +Trigger mode for an aggregate alert. +""" +enum TriggerMode { +""" +Wait for up to 20 minutes for a complete result before triggering. +""" + CompleteMode +""" +Trigger immediately, even on incomplete results. If nothing to trigger on, wait for up to 20 minutes for there to be a result to trigger on. +""" + ImmediateMode +} + +scalar URL + +enum UiTheme { + Auto + Dark + Light +} + +type UnlimitedUsage { + unlimited: Boolean! +} + +""" +An unsaved aggregate alert. +""" +type UnsavedAggregateAlert { +""" +Name of the aggregate alert. +""" + name: String! +""" +Description of the aggregate alert. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +List of actions to fire on query result. +""" + actions: [Action!]! +""" +Labels attached to the aggregate alert. +""" + labels: [String!]! +""" +Flag indicating whether the aggregate alert is enabled. +""" + enabled: Boolean! +""" +Throttle time in seconds. +""" + throttleTimeSeconds: Long! +""" +A field to throttle on. Can only be set if throttleTimeSeconds is set. +""" + throttleField: String +""" +Timestamp type to use for a query. +""" + queryTimestampType: QueryTimestampType! +""" +Trigger mode used for triggering the alert. +""" + triggerMode: TriggerMode! +""" +Search interval in seconds. +""" + searchIntervalSeconds: Long! +} + +""" +An unsaved alert. +""" +type UnsavedAlert { +""" +Name of the alert. +""" + name: String! +""" +Description of the alert. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +Start of the relative time interval for the query. +""" + queryStart: String! +""" +Throttle time in milliseconds. +""" + throttleTimeMillis: Long! +""" +Field to throttle on. +""" + throttleField: String +""" +List of ids for actions to fire on query result. +""" + actions: [Action!]! +""" +Labels attached to the alert. +""" + labels: [String!]! +""" +Flag indicating whether the alert is enabled. +""" + enabled: Boolean! +} + +""" +An unsaved filter alert. +""" +type UnsavedFilterAlert { +""" +Name of the filter alert. +""" + name: String! +""" +Description of the filter alert. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +List of ids for actions to fire on query result. +""" + actions: [Action!]! +""" +Labels attached to the filter alert. +""" + labels: [String!]! +""" +Flag indicating whether the filter alert is enabled. +""" + enabled: Boolean! +""" +Throttle time in seconds. +""" + throttleTimeSeconds: Long +""" +A field to throttle on. Can only be set if throttleTimeSeconds is set. +""" + throttleField: String +} + +""" +The contents of a parser YAML template in structured form. The parser needs to be persisted before it can be deployed. +""" +type UnsavedParser { +""" +Name of the parser. +""" + name: String! +""" +The parser script that is executed for every incoming event. +""" + script: String! +""" +Fields that are used as tags. +""" + fieldsToTag: [String!]! +""" +A list of fields that will be removed from the event before it's parsed. These fields will not be included when calculating usage. +""" + fieldsToBeRemovedBeforeParsing: [String!]! +""" +Test cases that can be used to help verify that the parser works as expected. +""" + testCases: [ParserTestCase!]! +} + +""" +An unsaved scheduled search. +""" +type UnsavedScheduledSearch { +""" +Name of the scheduled search. +""" + name: String! +""" +Description of the scheduled search. +""" + description: String +""" +LogScale query to execute. +""" + queryString: String! +""" +Start of the relative time interval for the query. +""" + start: String! +""" +End of the relative time interval for the query. +""" + end: String! +""" +Cron pattern describing the schedule to execute the query on. +""" + schedule: String! +""" +Time zone of the schedule. Currently this field only supports UTC offsets like 'UTC', 'UTC-01' or 'UTC+12:45'. +""" + timeZone: String! +""" +User-defined limit, which caps the number of missed searches to backfill, e.g. in the event of a shutdown. +""" + backfillLimit: Int! +""" +List of Ids for actions to fire on query result. +""" + actions: [Action!]! +""" +Labels attached to the scheduled search. +""" + labels: [String!]! +""" +Flag indicating whether the scheduled search is enabled. +""" + enabled: Boolean! +} + +scalar UnversionedPackageSpecifier + +type UpdateParametersInteraction { + arguments: [DictionaryEntryType!]! + useWidgetTimeWindow: Boolean! +} + +""" +An uploaded file snapshot. +""" +type UploadedFileSnapshot { + nameAndPath: FileNameAndPath! + headers: [String!]! + lines: [[String!]!]! + totalLinesCount: Long! + limit: Int! + offset: Int! + filterString: String +} + +scalar UrlOrData + +""" +Contractual usage limit. If you are above you should renegotiate your contract. +""" +union UsageLimit =UsageLimitDefined | UnlimitedUsage + +type UsageLimitDefined { + limit: Long! +} + +type UsageOnDay { + date: DateTime! + ingestBytes: Long! + averageIngestBytes: Long + limit: UsageLimit! +} + +type UsageStats { +""" +Current usage measurements and limits for ingest, storage, scanned data and users +""" + currentStats( + queryId: String + ): CurrentUsageQueryResult! + monthlyIngest( + month: Int! + year: Int! + queryId: String + ): MonthlyIngestQueryResult! + monthlyStoredData( + month: Int! + year: Int! + queryId: String + ): MonthlyStorageQueryResult! + firstUsageTimeStamp: Long! + repositoriesIngest( + month: Int! + year: Int! + day: Int +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + sortBy: RepositoriesUsageQuerySortBy! + queryId: String + ): RepositoriesUsageQueryResultTypes! + repositoriesStorage( + month: Int! + year: Int! + day: Int +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy + sortBy: RepositoriesUsageQuerySortBy! + queryId: String + ): RepositoriesUsageQueryResultTypes! +} + +""" +A user profile. +""" +type User { + id: String! +""" +fullName if present, otherwise username. +""" + displayName: String! + username: String! + isRoot: Boolean! + isOrgRoot: Boolean! + fullName: String + firstName: String + lastName: String + phoneNumber: String + email: String + picture: String + createdAt: DateTime! + countryCode: String + stateCode: String + company: String + userOrGroupSearchDomainRoles( + search: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): UserOrGroupSearchDomainRoleResultSet! + groupSearchDomainRoles: [GroupSearchDomainRole!]! + searchDomainRoles( + searchDomainId: String + ): [SearchDomainRole!]! + searchDomainRolesByName( + searchDomainName: String! + ): SearchDomainRole + searchDomainRolesBySearchDomainName( + searchDomainName: String! + ): [SearchDomainRole!]! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Get asset permissions assigned to the user for the specific asset +""" + assetPermissions( +""" +Id of the asset +""" + assetId: String! +""" +Asset type +""" + assetType: AssetPermissionsAssetType! +""" +Search domain id +""" + searchDomainId: String + ): AssetPermissionsForUser! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] Search for asset permissions for the user +""" + searchAssetPermissions( +""" +Filter results based on this string +""" + searchFilter: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int +""" +Choose the order in which the results are returned. +""" + orderBy: OrderBy +""" +The sort by options for asset permissions. +""" + sortBy: SortBy +""" +Asset type +""" + assetType: AssetPermissionsAssetType! +""" +List of search domain id's to search within +""" + searchDomainIds: [String!] +""" +Include UpdateAsset and/or DeleteAsset permission assignments +""" + permissions: AssetPermissionInputEnum +""" +If this is set to true, the search will also return all assets, that the user has not been assigned any permissions for +""" + includeUnassignedAssets: Boolean + ): AssetPermissionSearchResultSet! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] The roles assigned to the user through a group. +""" + rolesV2( + search: String + typeFilter: [PermissionType!] +""" +The amount of results to return. +""" + limit: Int +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int + searchInGroups: Boolean + ): RolesResultSetType! +""" +[PREVIEW: Feature currently being iterated on. Changes may occur.] The groups the user is a member of. +""" + groupsV2( + search: String + typeFilter: [PermissionType!] +""" +The amount of results to return. +""" + limit: Int +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int + searchInRoles: Boolean + ): GroupResultSetType! +""" +The groups the user is a member of. +""" + groups: [Group!]! +""" +Permissions of the user. +""" + permissions( +""" +Exact name of the repo to find permissions for. +""" + viewName: String + ): [UserPermissions!]! +""" +A page of user permissions. +""" + permissionsPage( + search: String + pageNumber: Int! + pageSize: Int! + ): UserPermissionsPage! +""" +Returns the actions the user is allowed to perform in the system. +""" + allowedSystemActions: [SystemAction!]! +""" +Returns the actions the user is allowed to perform in the organization. +""" + allowedOrganizationActions: [OrganizationAction!]! +} + +type UserAndTimestamp { + username: String! + user: User + timestamp: DateTime! +} + +""" +A user or a group +""" +union UserOrGroup =Group | User + +""" +A user or a group role +""" +union UserOrGroupSearchDomainRole =GroupSearchDomainRole | SearchDomainRole + +""" +A page of users or group roles. +""" +type UserOrGroupSearchDomainRoleResultSet { +""" +The total number of matching results +""" + totalResults: Int! + results: [UserOrGroupSearchDomainRole!]! +} + +""" +Permissions of the user. +""" +type UserPermissions { + searchDomain: SearchDomain! + queryPrefix: String! + viewPermissions: [Permission!]! +} + +""" +A page of user permissions. +""" +type UserPermissionsPage { + pageInfo: PageType! + page: [UserPermissions!]! +} + +""" +The users query result set. +""" +type UserResultSetType { +""" +The total number of matching results +""" + totalResults: Int! +""" +The paginated result set +""" + results: [User!]! +} + +type UserSettings { + isCommunityMessageDismissed: Boolean! + isGettingStartedMessageDismissed: Boolean! + isWelcomeMessageDismissed: Boolean! + isEventListOrderedWithNewestAtBottom: Boolean! + isPackageDocsMessageDismissed: Boolean! + isFieldPanelOpenByDefault: Boolean! + isAutomaticSearchEnabled: Boolean! + isDarkModeMessageDismissed: Boolean! + uiTheme: UiTheme! + starredDashboards: [String!]! + starredSearchDomains: [String!]! + starredAlerts: [String!]! +""" +[PREVIEW: We are iterating on our feature announcements, and may change this again] +""" + featureAnnouncementsToShow: [FeatureAnnouncement!]! + isQuickStartCompleted: Boolean! +""" +Default timezone preference +""" + defaultTimeZone: String +""" +[PREVIEW: Experimental user setting value for a feature which allow for automatic highlighting on the search page] +""" + isAutomaticHighlightingEnabled: Boolean! + isResizableQueryFieldMessageDismissed: Boolean! +} + +""" +A paginated set of users +""" +type Users { +""" +The total number of users +""" + totalUsers: Int! +""" +The paginated set of users +""" + users: [User!]! +} + +""" +A page of users and groups. +""" +type UsersAndGroupsSearchResultSet { +""" +The total number of matching results +""" + totalResults: Int! + results: [UserOrGroup!]! +} + +type UsersLimit { + currentBytes: Int! + limit: UsageLimit! +} + +""" +A page of users. +""" +type UsersPage { + pageInfo: PageType! + page: [User!]! +} + +scalar VersionedPackageSpecifier + +""" +Represents information about a view, pulling data from one or several repositories. +""" +type View implements SearchDomain{ + connections: [ViewConnection!]! + crossOrgConnections: [CrossOrgViewConnection!]! +""" +[PREVIEW: Experimental feature, not ready for production.] Cluster connections. +""" + clusterConnections: [ClusterConnection!]! +""" +A specific connection. +""" + clusterConnection( +""" +The id of the connection to get. +""" + id: String! + ): ClusterConnection! +""" +[PREVIEW: Experimental feature, not ready for production.] Check all this search domain's cluster connections. +""" + checkClusterConnections: [ClusterConnectionStatus!]! +""" +[PREVIEW: Experimental feature, not ready for production.] True if the view is federated, false otherwise. +""" + isFederated: Boolean! + id: String! + name: RepoOrViewName! + description: String +""" +The point in time the search domain was marked for deletion. +""" + deletedDate: Long +""" +The point in time the search domain will not be restorable anymore. +""" + permanentlyDeletedAt: Long + isStarred: Boolean! +""" +Search limit in milliseconds, which searches should are limited to. +""" + searchLimitedMs: Long +""" +Repositories not part of the search limitation. +""" + reposExcludedInSearchLimit: [String!]! +""" +Returns a specific version of a package given a package version. +""" + packageV2( +""" +The package id of the package to get. +""" + packageId: VersionedPackageSpecifier! + ): Package2! +""" +[PREVIEW: This may be moved to the Package2 object.] The available versions of a package. +""" + packageVersions( + packageId: UnversionedPackageSpecifier! + ): [RegistryPackageVersionInfo!]! +""" +Returns a list of available packages that can be installed. +""" + availablePackages( +""" +Filter input to limit the returned packages +""" + filter: String +""" +Packages with any of these tags will be included. No filtering on tags. +""" + tags: [PackageTag!] +""" +Packages with any of these categories will be included. +""" + categories: [String!] + ): [PackageRegistrySearchResultItem!]! +""" +List packages installed on a specific view or repo. +""" + installedPackages: [PackageInstallation!]! + hasPackageInstalled( + packageId: VersionedPackageSpecifier! + ): Boolean! +""" +Users who has access. +""" + users: [User!]! +""" +Users or groups who has access. +""" + usersAndGroups( + search: String +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): UsersAndGroupsSearchResultSet! +""" +[PREVIEW] Search users with a given permission +""" + usersV2( +""" +Search for a user whose email or name matches this search string +""" + search: String +""" +Permission that the users must have on the search domain. Leave out to get users with any permission on the view +""" + permissionFilter: Permission +""" +The number of results to skip or the offset to use. For instance if implementing pagination, set skip = limit * (page - 1) +""" + skip: Int +""" +The amount of results to return. +""" + limit: Int + ): Users! +""" +Groups with assigned roles. +""" + groups: [Group!]! + starredFields: [String!]! + recentQueriesV2: [RecentQuery!]! + automaticSearch: Boolean! +""" +Check if the current user is allowed to perform the given action on the view. +""" + isActionAllowed( +""" +The action to check if a user is allowed to perform on a view. +""" + action: ViewAction! + ): Boolean! +""" +Returns the all actions the user is allowed to perform on the view. +""" + allowedViewActions: [ViewAction!]! +""" +The query prefix prepended to each search in this domain. +""" + viewerQueryPrefix: String! +""" +All tags from all datasources. +""" + tags: [String!]! +""" +All interactions defined on the view. +""" + interactions: [ViewInteraction!]! +""" +A saved alert +""" + alert( + id: String! + ): Alert! +""" +Saved alerts. +""" + alerts: [Alert!]! +""" +A saved dashboard. +""" + dashboard( + id: String! + ): Dashboard! +""" +All dashboards available on the view. +""" + dashboards: [Dashboard!]! +""" +A saved filter alert +""" + filterAlert( + id: String! + ): FilterAlert! +""" +Saved filter alerts. +""" + filterAlerts: [FilterAlert!]! +""" +A saved aggregate alert +""" + aggregateAlert( + id: String! + ): AggregateAlert! +""" +Saved aggregate alerts. +""" + aggregateAlerts: [AggregateAlert!]! +""" +A saved scheduled search. +""" + scheduledSearch( +""" +The id of the scheduled search to get. +""" + id: String! + ): ScheduledSearch! +""" +Saved scheduled searches. +""" + scheduledSearches: [ScheduledSearch!]! +""" +A saved action. +""" + action( +""" +The id of the action to get. +""" + id: String! + ): Action! +""" +A list of saved actions. +""" + actions: [Action!]! +""" +A saved query. +""" + savedQuery( + id: String! + ): SavedQuery! +""" +Saved queries. +""" + savedQueries: [SavedQuery!]! + defaultQuery: SavedQuery + files: [File!]! + fileFieldSearch( +""" +Name of the csv or json file to retrieve the field entries from. +""" + fileName: String! +""" +Name of the field in the file to return entries from. +""" + fieldName: String! +""" +Text to filter values by prefix on. +""" + prefixFilter: String +""" +The exact values that given fields should have for an entry to be part of the result. +""" + valueFilters: [FileFieldFilterType!]! +""" +Names of the fields to include in the result. +""" + fieldsToInclude: [String!]! +""" +Maximum number of values to retrieve from the file. +""" + maxEntries: Int! + ): [[DictionaryEntryType!]!]! +""" +Saved scheduled reports. +""" + scheduledReports: [ScheduledReport!]! +""" +Saved scheduled report. +""" + scheduledReport( +""" +The id of the scheduled report to get. +""" + id: String! + ): ScheduledReport +} + +""" +Actions a user may perform on a view. +""" +enum ViewAction { + ChangeConnections + ChangeUserAccess +""" +Denotes if you can administer alerts, scheduled searches and actions +""" + ChangeTriggersAndActions +""" +Denotes if you can administer alerts and scheduled searches +""" + ChangeTriggers +""" +Denotes if you can administer actions +""" + ChangeActions + ChangeInteractions + ChangeViewOrRepositoryDescription + ChangeDashboards + ChangeDashboardReadonlyToken + ChangeFdrFeeds + ChangeDataspaceKind + ChangeFdrFeedControls + ReadFdrFeeds + ChangeIngestFeeds + ChangeFiles + ChangeParsers + DeleteParsers + ChangeSavedQueries + ConnectView + ConnectMultiClusterView + ChangeDataDeletionPermissions + ChangeRetention + ChangeTimeBasedRetention + ChangeSizeBasedRetention + ChangeDefaultSearchSettings + ChangeS3ArchivingSettings + DeleteDataSources + DeleteRepositoryOrView + DeleteEvents +""" +Denotes if you can see log events +""" + ReadEvents + ChangeIngestTokens + ChangePackages +""" +Denotes if you can administer event forwarding rules +""" + EventForwarding + ChangeIngestListeners + ChangePermissionTokens + ChangeIngestBlocking + ChangeFieldsToBeRemovedBeforeParsing + ExportQueryResults + ChangeOrganizationOwnedQueries + ReadExternalFunctions + ChangeScheduledReports +} + +""" +Represents the connection between a view and an underlying repository. +""" +type ViewConnection { +""" +The underlying repository +""" + repository: Repository! +""" +The filter applied to all results from the repository. +""" + filter: String! + languageVersion: LanguageVersion! +} + +""" +An interaction available across search and dashboards +""" +type ViewInteraction { + id: String! + name: String! + displayName: String! + description: String + assetType: AssetType! + packageId: VersionedPackageSpecifier + package: PackageInstallation +} + +""" +A defined view interaction +""" +type ViewInteractionEntry { + id: String! + view: SearchDomain! + interaction: QueryBasedWidgetInteraction! + packageId: VersionedPackageSpecifier + package: PackageInstallation +} + +type ViewInteractionTemplate { + name: String! + displayName: String! + yamlTemplate: String! +} + +type WellKnownEndpointDetails { + issuer: String! + authorizationEndpoint: String + jwksEndpoint: String + registrationEndpoint: String + tokenEndpoint: String + tokenEndpointAuthMethod: String! + userInfoEndpoint: String +} + +""" +A dashboard widget. +""" +interface Widget { +""" +A dashboard widget. +""" + id: String! +""" +A dashboard widget. +""" + title: String! +""" +A dashboard widget. +""" + description: String +""" +A dashboard widget. +""" + x: Int! +""" +A dashboard widget. +""" + y: Int! +""" +A dashboard widget. +""" + width: Int! +""" +A dashboard widget. +""" + height: Int! +} + +type WidgetInteractionCondition { + fieldName: String! + operator: FieldConditionOperatorType! + argument: String! +} + +""" +A key being traced by worker query tracing. +""" +type WorkerQueryTracingItem { + key: String! + expiry: Long! +} + +""" +The state of worker query tracing. +""" +type WorkerQueryTracingState { + items: [WorkerQueryTracingItem!]! +} + +scalar YAML + +""" +Common interface for contractual parts of the limit +""" +interface contractual { +""" +Common interface for contractual parts of the limit +""" + includeUsage: Boolean! +} + +type drilldowns { +""" +[PREVIEW: Internal testing.] Get the query that returns the underlying events for the given fields. +""" + sourceEventsForFieldsQuery( + fields: [String!]! + ): SourceEventsQueryResultType! +} + +""" +A namespace for various query analyses and transformations. +""" +type queryAnalysis { + drilldowns: drilldowns! +""" +Checks if a query is fit for use for a filter alert +""" + isValidFilterAlertQuery( + viewName: String! + ): Boolean! +""" +The query contains an aggregator +""" + isAggregate: Boolean! +""" +The query does not contain a join-like function +""" + isSinglePhase: Boolean! +""" +The query string up to the first aggregator +""" + filterPart: String! +} + +""" +The `BigDecimal` scalar type represents signed fractional values with arbitrary precision. +""" +scalar BigDecimal + +""" +The `BigInt` scalar type represents non-fractional signed whole numeric values. BigInt can represent arbitrary big values. +""" +scalar BigInt + +""" +The `Boolean` scalar type represents `true` or `false`. +""" +scalar Boolean + +""" +The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754). +""" +scalar Float + +""" +The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. +""" +scalar Int + +""" +The `Long` scalar type represents non-fractional signed whole numeric values. Long can represent values between -(2^63) and 2^63 - 1. +""" +scalar Long + +""" +The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text. +""" +scalar String + + +# Fetched from version 1.154.0--build-1810--sha-eebd9d5d384aeb5d20f7a012d51fa7c64a07417e \ No newline at end of file diff --git a/internal/api/humiographql/tools.go b/internal/api/humiographql/tools.go new file mode 100644 index 00000000..7f113e03 --- /dev/null +++ b/internal/api/humiographql/tools.go @@ -0,0 +1,4 @@ +package humiographql + +//go:generate go run github.com/Khan/genqlient genqlient.yaml +import _ "github.com/Khan/genqlient/generate" diff --git a/internal/api/status.go b/internal/api/status.go new file mode 100644 index 00000000..2313f6c8 --- /dev/null +++ b/internal/api/status.go @@ -0,0 +1,66 @@ +package api + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "strings" + + "github.com/Masterminds/semver/v3" +) + +type StatusResponse struct { + Version string +} + +func (s StatusResponse) AtLeast(ver string) (bool, error) { + assumeLatest := true + version := strings.Split(s.Version, "-") + constraint, err := semver.NewConstraint(fmt.Sprintf(">= %s", ver)) + if err != nil || len(version) == 0 { + return assumeLatest, fmt.Errorf("could not parse constraint of `%s`: %w", fmt.Sprintf(">= %s", ver), err) + } + semverVersion, err := semver.NewVersion(version[0]) + if err != nil { + return assumeLatest, fmt.Errorf("could not parse version of `%s`: %w", version[0], err) + } + + return constraint.Check(semverVersion), nil +} + +func (c *Client) Status(ctx context.Context) (*StatusResponse, error) { + resp, err := c.HTTPRequestContext(ctx, http.MethodGet, "api/v1/status", nil, JSONContentType) + + if err != nil { + return nil, err + } + + if resp == nil { + return nil, fmt.Errorf("failed to get response") + } + + defer func() { + _ = resp.Body.Close() + }() + + if resp.StatusCode >= 400 { + return nil, fmt.Errorf("error getting server status: %s", resp.Status) + } + + jsonData, err := io.ReadAll(resp.Body) + + if err != nil { + return nil, err + } + + var status StatusResponse + err = json.Unmarshal(jsonData, &status) + + if err != nil { + return nil, err + } + + return &status, nil +} diff --git a/pkg/helpers/clusterinterface.go b/internal/helpers/clusterinterface.go similarity index 96% rename from pkg/helpers/clusterinterface.go rename to internal/helpers/clusterinterface.go index fa02cdb9..9342f808 100644 --- a/pkg/helpers/clusterinterface.go +++ b/internal/helpers/clusterinterface.go @@ -22,11 +22,11 @@ import ( "net/url" "strings" - humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/kubernetes" corev1 "k8s.io/api/core/v1" - "github.com/humio/humio-operator/pkg/kubernetes" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -48,7 +48,7 @@ type Cluster struct { humioConfig *humioapi.Config } -func NewCluster(ctx context.Context, k8sClient client.Client, managedClusterName, externalClusterName, namespace string, certManagerEnabled bool, withAPIToken bool, withBootstrapToken bool) (ClusterInterface, error) { +func NewCluster(ctx context.Context, k8sClient client.Client, managedClusterName, externalClusterName, namespace string, certManagerEnabled bool, withPersonalAPIToken bool, withBootstrapToken bool) (ClusterInterface, error) { // Return error immediately if we do not have exactly one of the cluster names configured if managedClusterName != "" && externalClusterName != "" { return nil, fmt.Errorf("cannot have both ManagedClusterName and ExternalClusterName set at the same time") @@ -64,11 +64,11 @@ func NewCluster(ctx context.Context, k8sClient client.Client, managedClusterName managedClusterName: managedClusterName, namespace: namespace, certManagerEnabled: certManagerEnabled, - withAPIToken: withAPIToken, + withAPIToken: withPersonalAPIToken, withBootstrapToken: withBootstrapToken, } - humioConfig, err := cluster.constructHumioConfig(ctx, k8sClient, withAPIToken, withBootstrapToken) + humioConfig, err := cluster.constructHumioConfig(ctx, k8sClient, withPersonalAPIToken, withBootstrapToken) if err != nil { return nil, err } @@ -245,7 +245,7 @@ func (c Cluster) constructHumioConfig(ctx context.Context, k8sClient client.Clie return nil, fmt.Errorf("not possible to run secure cluster with plain http") } - // Get API token + // Search API token var apiToken corev1.Secret err = k8sClient.Get(ctx, types.NamespacedName{ Namespace: c.namespace, diff --git a/pkg/helpers/clusterinterface_test.go b/internal/helpers/clusterinterface_test.go similarity index 100% rename from pkg/helpers/clusterinterface_test.go rename to internal/helpers/clusterinterface_test.go diff --git a/pkg/helpers/helpers.go b/internal/helpers/helpers.go similarity index 93% rename from pkg/helpers/helpers.go rename to internal/helpers/helpers.go index e9f37624..3ade7ae9 100644 --- a/pkg/helpers/helpers.go +++ b/internal/helpers/helpers.go @@ -88,11 +88,24 @@ func Int64Ptr(val int64) *int64 { return &val } -// IntPtr returns a int pointer to the specified int value -func IntPtr(val int) *int { +// Int32Ptr returns a int pointer to the specified int32 value +func Int32Ptr(val int32) *int32 { return &val } +// StringPtr returns a string pointer to the specified string value +func StringPtr(val string) *string { + return &val +} + +func Int32PtrToFloat64Ptr(val *int32) *float64 { + if val != nil { + f := float64(*val) + return &f + } + return nil +} + // BoolTrue returns true if the pointer is nil or true func BoolTrue(val *bool) bool { return val == nil || *val diff --git a/pkg/humio/action_transform.go b/internal/humio/action_transform.go similarity index 63% rename from pkg/humio/action_transform.go rename to internal/humio/action_transform.go index e8e43e13..6ec340ef 100644 --- a/pkg/humio/action_transform.go +++ b/internal/humio/action_transform.go @@ -18,14 +18,13 @@ package humio import ( "fmt" - "github.com/humio/humio-operator/pkg/kubernetes" "net/http" "net/url" "strings" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - - humioapi "github.com/humio/cli/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/kubernetes" ) const ( @@ -41,8 +40,8 @@ const ( // ActionFromActionCR converts a HumioAction Kubernetes custom resource to an Action that is valid for the LogScale API. // It assumes any referenced secret values have been resolved by method resolveSecrets on HumioActionReconciler. -func ActionFromActionCR(ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - at, err := actionType(ha) +func ActionFromActionCR(ha *humiov1alpha1.HumioAction) (humiographql.ActionDetails, error) { + at, err := getActionType(ha) if err != nil { return nil, fmt.Errorf("could not find action type: %w", err) } @@ -67,62 +66,45 @@ func ActionFromActionCR(ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) return nil, fmt.Errorf("invalid action type: %s", at) } -func emailAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func emailAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsEmailAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return nil, err - } - if len(hn.Spec.EmailProperties.Recipients) == 0 { errorList = append(errorList, "property emailProperties.recipients is required") } if len(errorList) > 0 { - return ifErrors(action, ActionTypeEmail, errorList) - } - action.Type = humioapi.ActionTypeEmail - action.EmailAction.Recipients = hn.Spec.EmailProperties.Recipients - action.EmailAction.BodyTemplate = hn.Spec.EmailProperties.BodyTemplate - action.EmailAction.BodyTemplate = hn.Spec.EmailProperties.BodyTemplate - action.EmailAction.SubjectTemplate = hn.Spec.EmailProperties.SubjectTemplate - action.EmailAction.UseProxy = hn.Spec.EmailProperties.UseProxy - - return action, nil + return nil, ifErrors(ActionTypeEmail, errorList) + } + return &humiographql.ActionDetailsEmailAction{ + Name: hn.Spec.Name, + Recipients: hn.Spec.EmailProperties.Recipients, + EmailBodyTemplate: &hn.Spec.EmailProperties.BodyTemplate, + SubjectTemplate: &hn.Spec.EmailProperties.SubjectTemplate, + UseProxy: hn.Spec.EmailProperties.UseProxy, + }, nil } -func humioRepoAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func humioRepoAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsHumioRepoAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - apiToken, found := kubernetes.GetSecretForHa(hn) - if hn.Spec.HumioRepositoryProperties.IngestToken == "" && !found { errorList = append(errorList, "property humioRepositoryProperties.ingestToken is required") } if len(errorList) > 0 { - return ifErrors(action, ActionTypeHumioRepo, errorList) + return nil, ifErrors(ActionTypeHumioRepo, errorList) + } + action := &humiographql.ActionDetailsHumioRepoAction{ + Name: hn.Spec.Name, } if hn.Spec.HumioRepositoryProperties.IngestToken != "" { - action.HumioRepoAction.IngestToken = hn.Spec.HumioRepositoryProperties.IngestToken + action.IngestToken = hn.Spec.HumioRepositoryProperties.IngestToken } else { - action.HumioRepoAction.IngestToken = apiToken + action.IngestToken = apiToken } - - action.Type = humioapi.ActionTypeHumioRepo - return action, nil } -func opsGenieAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func opsGenieAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsOpsGenieAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - apiToken, found := kubernetes.GetSecretForHa(hn) if hn.Spec.OpsGenieProperties.GenieKey == "" && !found { @@ -132,37 +114,31 @@ func opsGenieAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { errorList = append(errorList, "property opsGenieProperties.apiUrl is required") } if len(errorList) > 0 { - return ifErrors(action, ActionTypeOpsGenie, errorList) + return nil, ifErrors(ActionTypeOpsGenie, errorList) + } + action := &humiographql.ActionDetailsOpsGenieAction{ + Name: hn.Spec.Name, + ApiUrl: hn.Spec.OpsGenieProperties.ApiUrl, + UseProxy: hn.Spec.OpsGenieProperties.UseProxy, } if hn.Spec.OpsGenieProperties.GenieKey != "" { - action.OpsGenieAction.GenieKey = hn.Spec.OpsGenieProperties.GenieKey + action.GenieKey = hn.Spec.OpsGenieProperties.GenieKey } else { - action.OpsGenieAction.GenieKey = apiToken + action.GenieKey = apiToken } - - action.Type = humioapi.ActionTypeOpsGenie - action.OpsGenieAction.ApiUrl = hn.Spec.OpsGenieProperties.ApiUrl - action.OpsGenieAction.UseProxy = hn.Spec.OpsGenieProperties.UseProxy - return action, nil } -func pagerDutyAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func pagerDutyAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsPagerDutyAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - apiToken, found := kubernetes.GetSecretForHa(hn) - - var severity string if hn.Spec.PagerDutyProperties.RoutingKey == "" && !found { errorList = append(errorList, "property pagerDutyProperties.routingKey is required") } if hn.Spec.PagerDutyProperties.Severity == "" { errorList = append(errorList, "property pagerDutyProperties.severity is required") } + var severity string if hn.Spec.PagerDutyProperties.Severity != "" { severity = strings.ToLower(hn.Spec.PagerDutyProperties.Severity) acceptedSeverities := []string{"critical", "error", "warning", "info"} @@ -172,28 +148,23 @@ func pagerDutyAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { } } if len(errorList) > 0 { - return ifErrors(action, ActionTypePagerDuty, errorList) + return nil, ifErrors(ActionTypePagerDuty, errorList) + } + action := &humiographql.ActionDetailsPagerDutyAction{ + Name: hn.Spec.Name, + Severity: severity, + UseProxy: hn.Spec.PagerDutyProperties.UseProxy, } if hn.Spec.PagerDutyProperties.RoutingKey != "" { - action.PagerDutyAction.RoutingKey = hn.Spec.PagerDutyProperties.RoutingKey + action.RoutingKey = hn.Spec.PagerDutyProperties.RoutingKey } else { - action.PagerDutyAction.RoutingKey = apiToken + action.RoutingKey = apiToken } - - action.Type = humioapi.ActionTypePagerDuty - action.PagerDutyAction.Severity = severity - action.PagerDutyAction.UseProxy = hn.Spec.PagerDutyProperties.UseProxy - return action, nil } -func slackAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func slackAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsSlackAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - slackUrl, found := kubernetes.GetSecretForHa(hn) if hn.Spec.SlackProperties.Url == "" && !found { errorList = append(errorList, "property slackProperties.url is required") @@ -201,40 +172,34 @@ func slackAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { if hn.Spec.SlackProperties.Fields == nil { errorList = append(errorList, "property slackProperties.fields is required") } + action := &humiographql.ActionDetailsSlackAction{ + Name: hn.Spec.Name, + UseProxy: hn.Spec.SlackProperties.UseProxy, + } if hn.Spec.SlackProperties.Url != "" { - action.SlackAction.Url = hn.Spec.SlackProperties.Url + action.Url = hn.Spec.SlackProperties.Url } else { - action.SlackAction.Url = slackUrl + action.Url = slackUrl } - if _, err := url.ParseRequestURI(action.SlackAction.Url); err != nil { + if _, err := url.ParseRequestURI(action.Url); err != nil { errorList = append(errorList, fmt.Sprintf("invalid url for slackProperties.url: %s", err.Error())) } if len(errorList) > 0 { - return ifErrors(action, ActionTypeSlack, errorList) + return nil, ifErrors(ActionTypeSlack, errorList) } - - action.Type = humioapi.ActionTypeSlack - action.SlackAction.UseProxy = hn.Spec.SlackProperties.UseProxy - action.SlackAction.Fields = []humioapi.SlackFieldEntryInput{} for k, v := range hn.Spec.SlackProperties.Fields { - action.SlackAction.Fields = append(action.SlackAction.Fields, - humioapi.SlackFieldEntryInput{ + action.Fields = append(action.Fields, + humiographql.ActionDetailsFieldsSlackFieldEntry{ FieldName: k, Value: v, }, ) } - return action, nil } -func slackPostMessageAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func slackPostMessageAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsSlackPostMessageAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - apiToken, found := kubernetes.GetSecretForHa(hn) if hn.Spec.SlackPostMessageProperties.ApiToken == "" && !found { errorList = append(errorList, "property slackPostMessageProperties.apiToken is required") @@ -246,21 +211,21 @@ func slackPostMessageAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, er errorList = append(errorList, "property slackPostMessageProperties.fields is required") } if len(errorList) > 0 { - return ifErrors(action, ActionTypeSlackPostMessage, errorList) + return nil, ifErrors(ActionTypeSlackPostMessage, errorList) + } + action := &humiographql.ActionDetailsSlackPostMessageAction{ + Name: hn.Spec.Name, + UseProxy: hn.Spec.SlackPostMessageProperties.UseProxy, + Channels: hn.Spec.SlackPostMessageProperties.Channels, } if hn.Spec.SlackPostMessageProperties.ApiToken != "" { - action.SlackPostMessageAction.ApiToken = hn.Spec.SlackPostMessageProperties.ApiToken + action.ApiToken = hn.Spec.SlackPostMessageProperties.ApiToken } else { - action.SlackPostMessageAction.ApiToken = apiToken + action.ApiToken = apiToken } - - action.Type = humioapi.ActionTypeSlackPostMessage - action.SlackPostMessageAction.Channels = hn.Spec.SlackPostMessageProperties.Channels - action.SlackPostMessageAction.UseProxy = hn.Spec.SlackPostMessageProperties.UseProxy - action.SlackPostMessageAction.Fields = []humioapi.SlackFieldEntryInput{} for k, v := range hn.Spec.SlackPostMessageProperties.Fields { - action.SlackPostMessageAction.Fields = append(action.SlackPostMessageAction.Fields, - humioapi.SlackFieldEntryInput{ + action.Fields = append(action.Fields, + humiographql.ActionDetailsFieldsSlackFieldEntry{ FieldName: k, Value: v, }, @@ -270,15 +235,9 @@ func slackPostMessageAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, er return action, nil } -func victorOpsAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func victorOpsAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsVictorOpsAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - apiToken, found := kubernetes.GetSecretForHa(hn) - var messageType string if hn.Spec.VictorOpsProperties.NotifyUrl == "" && !found { errorList = append(errorList, "property victorOpsProperties.notifyUrl is required") @@ -294,34 +253,28 @@ func victorOpsAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { hn.Spec.VictorOpsProperties.MessageType, strings.Join(acceptedMessageTypes, ", "))) } } + action := &humiographql.ActionDetailsVictorOpsAction{ + Name: hn.Spec.Name, + UseProxy: hn.Spec.VictorOpsProperties.UseProxy, + MessageType: messageType, + } if hn.Spec.VictorOpsProperties.NotifyUrl != "" { - action.VictorOpsAction.NotifyUrl = hn.Spec.VictorOpsProperties.NotifyUrl + action.NotifyUrl = hn.Spec.VictorOpsProperties.NotifyUrl } else { - action.VictorOpsAction.NotifyUrl = apiToken + action.NotifyUrl = apiToken } - if _, err := url.ParseRequestURI(action.VictorOpsAction.NotifyUrl); err != nil { + if _, err := url.ParseRequestURI(action.NotifyUrl); err != nil { errorList = append(errorList, fmt.Sprintf("invalid url for victorOpsProperties.notifyUrl: %s", err.Error())) } if len(errorList) > 0 { - return ifErrors(action, ActionTypeVictorOps, errorList) + return nil, ifErrors(ActionTypeVictorOps, errorList) } - - action.Type = humioapi.ActionTypeVictorOps - action.VictorOpsAction.MessageType = messageType - action.VictorOpsAction.UseProxy = hn.Spec.VictorOpsProperties.UseProxy - return action, nil } -func webhookAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { +func webhookAction(hn *humiov1alpha1.HumioAction) (*humiographql.ActionDetailsWebhookAction, error) { var errorList []string - action, err := baseAction(hn) - if err != nil { - return action, err - } - apiToken, found := kubernetes.GetSecretForHa(hn) - var method string if hn.Spec.WebhookProperties.Url == "" && !found { errorList = append(errorList, "property webhookProperties.url is required") @@ -340,12 +293,19 @@ func webhookAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { hn.Spec.WebhookProperties.Method, strings.Join(acceptedMethods, ", "))) } } + action := &humiographql.ActionDetailsWebhookAction{ + Name: hn.Spec.Name, + WebhookBodyTemplate: hn.Spec.WebhookProperties.BodyTemplate, + Method: method, + UseProxy: hn.Spec.WebhookProperties.UseProxy, + Headers: []humiographql.ActionDetailsHeadersHttpHeaderEntry{}, + } if hn.Spec.WebhookProperties.Url != "" { - action.WebhookAction.Url = hn.Spec.WebhookProperties.Url + action.Url = hn.Spec.WebhookProperties.Url } else { - action.WebhookAction.Url = apiToken + action.Url = apiToken } - if _, err := url.ParseRequestURI(action.WebhookAction.Url); err != nil { + if _, err := url.ParseRequestURI(action.Url); err != nil { errorList = append(errorList, fmt.Sprintf("invalid url for webhookProperties.url: %s", err.Error())) } allHeaders, found := kubernetes.GetFullSetOfMergedWebhookheaders(hn) @@ -353,14 +313,13 @@ func webhookAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { errorList = append(errorList, "webhookProperties contains duplicate keys") } if len(errorList) > 0 { - return ifErrors(action, ActionTypeWebhook, errorList) + return nil, ifErrors(ActionTypeWebhook, errorList) } if found { - action.WebhookAction.Headers = []humioapi.HttpHeaderEntryInput{} for k, v := range allHeaders { - action.WebhookAction.Headers = append(action.WebhookAction.Headers, - humioapi.HttpHeaderEntryInput{ + action.Headers = append(action.Headers, + humiographql.ActionDetailsHeadersHttpHeaderEntry{ Header: k, Value: v, }, @@ -368,29 +327,17 @@ func webhookAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) { } } - action.Type = humioapi.ActionTypeWebhook - action.WebhookAction.BodyTemplate = hn.Spec.WebhookProperties.BodyTemplate - action.WebhookAction.Method = method - action.WebhookAction.UseProxy = hn.Spec.WebhookProperties.UseProxy - return action, nil } -func ifErrors(action *humioapi.Action, actionType string, errorList []string) (*humioapi.Action, error) { +func ifErrors(actionType string, errorList []string) error { if len(errorList) > 0 { - return nil, fmt.Errorf("%s failed due to errors: %s", actionType, strings.Join(errorList, ", ")) + return fmt.Errorf("%s failed due to errors: %s", actionType, strings.Join(errorList, ", ")) } - return action, nil -} - -func baseAction(ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - action := &humioapi.Action{ - Name: ha.Spec.Name, - } - return action, nil + return nil } -func actionType(ha *humiov1alpha1.HumioAction) (string, error) { +func getActionType(ha *humiov1alpha1.HumioAction) (string, error) { var actionTypes []string if ha.Spec.WebhookProperties != nil { diff --git a/pkg/humio/action_transform_test.go b/internal/humio/action_transform_test.go similarity index 95% rename from pkg/humio/action_transform_test.go rename to internal/humio/action_transform_test.go index fdb89174..407edd65 100644 --- a/pkg/humio/action_transform_test.go +++ b/internal/humio/action_transform_test.go @@ -2,10 +2,8 @@ package humio import ( "fmt" - "reflect" "testing" - humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" ) @@ -16,7 +14,6 @@ func TestActionCRAsAction(t *testing.T) { tests := []struct { name string args args - want *humioapi.Action wantErr bool wantErrMessage string }{ @@ -30,7 +27,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property emailProperties.recipients is required", ActionTypeEmail), }, @@ -44,7 +40,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property humioRepositoryProperties.ingestToken is required", ActionTypeHumioRepo), }, @@ -58,7 +53,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property opsGenieProperties.genieKey is required, property opsGenieProperties.apiUrl is required", ActionTypeOpsGenie), }, @@ -72,7 +66,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property pagerDutyProperties.routingKey is required, property pagerDutyProperties.severity is required", ActionTypePagerDuty), }, @@ -86,7 +79,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property slackProperties.url is required, property slackProperties.fields is required, invalid url for slackProperties.url: parse \"\": empty url", ActionTypeSlack), }, @@ -100,7 +92,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property slackPostMessageProperties.apiToken is required, property slackPostMessageProperties.channels is required, property slackPostMessageProperties.fields is required", ActionTypeSlackPostMessage), }, @@ -114,7 +105,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property victorOpsProperties.notifyUrl is required, property victorOpsProperties.messageType is required, invalid url for victorOpsProperties.notifyUrl: parse \"\": empty url", ActionTypeVictorOps), }, @@ -128,7 +118,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: property webhookProperties.url is required, property webhookProperties.bodyTemplate is required, property webhookProperties.method is required, invalid url for webhookProperties.url: parse \"\": empty url", ActionTypeWebhook), }, @@ -145,7 +134,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: unsupported severity for pagerDutyProperties: \"invalid\". must be one of: critical, error, warning, info", ActionTypePagerDuty), }, @@ -162,7 +150,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: unsupported messageType for victorOpsProperties: \"invalid\". must be one of: critical, warning, acknowledgement, info, recovery", ActionTypeVictorOps), }, @@ -177,7 +164,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("could not find action type: found properties for more than one action: %s, %s", ActionTypeVictorOps, ActionTypeEmail), }, @@ -190,7 +176,6 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, "could not find action type: no properties specified for action", }, @@ -217,21 +202,17 @@ func TestActionCRAsAction(t *testing.T) { }, }, }, - nil, true, fmt.Sprintf("%s failed due to errors: webhookProperties contains duplicate keys", ActionTypeWebhook), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := ActionFromActionCR(tt.args.ha) + _, err := ActionFromActionCR(tt.args.ha) if (err != nil) != tt.wantErr { t.Errorf("ActionFromActionCR() error = %v, wantErr = %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ActionFromActionCR() got = %#v, want = %#v", got, tt.want) - } if err != nil && err.Error() != tt.wantErrMessage { t.Errorf("ActionFromActionCR() got = %v, want = %v", err.Error(), tt.wantErrMessage) } diff --git a/internal/humio/client.go b/internal/humio/client.go new file mode 100644 index 00000000..640d13aa --- /dev/null +++ b/internal/humio/client.go @@ -0,0 +1,1689 @@ +/* +Copyright 2020 Humio https://humio.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package humio + +import ( + "context" + "errors" + "fmt" + "net/http" + "sync" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + "github.com/go-logr/logr" + + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" + humioapi "github.com/humio/humio-operator/internal/api" +) + +// Client is the interface that can be mocked +type Client interface { + ClusterClient + IngestTokensClient + ParsersClient + RepositoriesClient + ViewsClient + LicenseClient + ActionsClient + AlertsClient + FilterAlertsClient + AggregateAlertsClient + ScheduledSearchClient + UsersClient +} + +type ClusterClient interface { + GetClusters(context.Context, *humioapi.Client, reconcile.Request) (*humiographql.GetClusterResponse, error) + GetHumioHttpClient(*humioapi.Config, reconcile.Request) *humioapi.Client + ClearHumioClientConnections(string) + TestAPIToken(context.Context, *humioapi.Config, reconcile.Request) error + Status(context.Context, *humioapi.Client, reconcile.Request) (*humioapi.StatusResponse, error) +} + +type IngestTokensClient interface { + AddIngestToken(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioIngestToken) error + GetIngestToken(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioIngestToken) (*humiographql.IngestTokenDetails, error) + UpdateIngestToken(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioIngestToken) error + DeleteIngestToken(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioIngestToken) error +} + +type ParsersClient interface { + AddParser(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioParser) error + GetParser(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioParser) (*humiographql.ParserDetails, error) + UpdateParser(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioParser) error + DeleteParser(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioParser) error +} + +type RepositoriesClient interface { + AddRepository(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioRepository) error + GetRepository(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioRepository) (*humiographql.RepositoryDetails, error) + UpdateRepository(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioRepository) error + DeleteRepository(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioRepository) error +} + +type ViewsClient interface { + AddView(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioView) error + GetView(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioView) (*humiographql.GetSearchDomainSearchDomainView, error) + UpdateView(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioView) error + DeleteView(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioView) error +} + +type ActionsClient interface { + AddAction(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAction) error + GetAction(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAction) (humiographql.ActionDetails, error) + UpdateAction(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAction) error + DeleteAction(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAction) error +} + +type AlertsClient interface { + AddAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAlert) error + GetAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAlert) (*humiographql.AlertDetails, error) + UpdateAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAlert) error + DeleteAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAlert) error +} + +type FilterAlertsClient interface { + AddFilterAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error + GetFilterAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioFilterAlert) (*humiographql.FilterAlertDetails, error) + UpdateFilterAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error + DeleteFilterAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error + ValidateActionsForFilterAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error +} + +type AggregateAlertsClient interface { + AddAggregateAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) error + GetAggregateAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) (*humiographql.AggregateAlertDetails, error) + UpdateAggregateAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) error + DeleteAggregateAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) error + ValidateActionsForAggregateAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) error +} + +type ScheduledSearchClient interface { + AddScheduledSearch(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error + GetScheduledSearch(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) (*humiographql.ScheduledSearchDetails, error) + UpdateScheduledSearch(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error + DeleteScheduledSearch(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error + ValidateActionsForScheduledSearch(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error +} + +type LicenseClient interface { + GetLicenseUIDAndExpiry(context.Context, *humioapi.Client, reconcile.Request) (string, time.Time, error) + InstallLicense(context.Context, *humioapi.Client, reconcile.Request, string) error +} + +type UsersClient interface { + AddUserAndGetUserID(context.Context, *humioapi.Client, reconcile.Request, string, bool) (string, error) + GetUserIDForUsername(context.Context, *humioapi.Client, reconcile.Request, string) (string, error) + RotateUserApiTokenAndGet(context.Context, *humioapi.Client, reconcile.Request, string) (string, error) +} + +// ClientConfig stores our Humio api client +type ClientConfig struct { + humioClients map[humioClientKey]*humioClientConnection + humioClientsMutex sync.Mutex + logger logr.Logger + userAgent string +} + +type humioClientKey struct { + namespace, name string + authenticated bool +} + +type humioClientConnection struct { + client *humioapi.Client + transport *http.Transport +} + +// NewClient returns a ClientConfig +func NewClient(logger logr.Logger, userAgent string) *ClientConfig { + return NewClientWithTransport(logger, userAgent) +} + +// NewClientWithTransport returns a ClientConfig using an existing http.Transport +func NewClientWithTransport(logger logr.Logger, userAgent string) *ClientConfig { + return &ClientConfig{ + logger: logger, + userAgent: userAgent, + humioClients: map[humioClientKey]*humioClientConnection{}, + } +} + +// GetHumioHttpClient takes a Humio API config as input and returns an API client that uses this config +func (h *ClientConfig) GetHumioHttpClient(config *humioapi.Config, req ctrl.Request) *humioapi.Client { + h.humioClientsMutex.Lock() + defer h.humioClientsMutex.Unlock() + + config.UserAgent = h.userAgent + key := humioClientKey{ + namespace: req.Namespace, + name: req.Name, + authenticated: config.Token != "", + } + + c := h.humioClients[key] + if c == nil { + transport := humioapi.NewHttpTransport(*config) + c = &humioClientConnection{ + client: humioapi.NewClientWithTransport(*config, transport), + transport: transport, + } + } else { + existingConfig := c.client.Config() + equal := existingConfig.Token == config.Token && + existingConfig.Insecure == config.Insecure && + existingConfig.CACertificatePEM == config.CACertificatePEM && + existingConfig.Address.String() == config.Address.String() + + // If the cluster address or SSL configuration has changed, we must create a new transport + if !equal { + transport := humioapi.NewHttpTransport(*config) + c = &humioClientConnection{ + client: humioapi.NewClientWithTransport(*config, transport), + transport: transport, + } + + } + if c.transport == nil { + c.transport = humioapi.NewHttpTransport(*config) + } + // Always create a new client and use the existing transport. Since we're using the same transport, connections + // will be cached. + c.client = humioapi.NewClientWithTransport(*config, c.transport) + } + + h.humioClients[key] = c + + return c.client +} + +func (h *ClientConfig) ClearHumioClientConnections(_ string) { + h.humioClientsMutex.Lock() + defer h.humioClientsMutex.Unlock() + + h.humioClients = make(map[humioClientKey]*humioClientConnection) +} + +// Status returns the status of the humio cluster +func (h *ClientConfig) Status(ctx context.Context, client *humioapi.Client, _ reconcile.Request) (*humioapi.StatusResponse, error) { + return client.Status(ctx) +} + +// GetClusters returns a humio cluster and can be mocked via the Client interface +func (h *ClientConfig) GetClusters(ctx context.Context, client *humioapi.Client, _ reconcile.Request) (*humiographql.GetClusterResponse, error) { + resp, err := humiographql.GetCluster( + ctx, + client, + ) + if err != nil { + return nil, err + } + + return resp, nil +} + +// TestAPIToken tests if an API token is valid by fetching the username that the API token belongs to +func (h *ClientConfig) TestAPIToken(ctx context.Context, config *humioapi.Config, req reconcile.Request) error { + humioHttpClient := h.GetHumioHttpClient(config, req) + _, err := humiographql.GetUsername(ctx, humioHttpClient) + return err +} + +func (h *ClientConfig) AddIngestToken(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { + _, err := humiographql.AddIngestToken( + ctx, + client, + hit.Spec.RepositoryName, + hit.Spec.Name, + hit.Spec.ParserName, + ) + return err +} + +func (h *ClientConfig) GetIngestToken(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humiographql.IngestTokenDetails, error) { + resp, err := humiographql.ListIngestTokens( + ctx, + client, + hit.Spec.RepositoryName, + ) + if err != nil { + return nil, err + } + respRepo := resp.GetRepository() + respRepoTokens := respRepo.GetIngestTokens() + tokensInRepo := make([]humiographql.IngestTokenDetails, len(respRepoTokens)) + for idx, token := range respRepoTokens { + tokensInRepo[idx] = humiographql.IngestTokenDetails{ + Name: token.GetName(), + Token: token.GetToken(), + Parser: token.GetParser(), + } + } + + for _, token := range tokensInRepo { + if token.Name == hit.Spec.Name { + return &token, nil + } + } + + return nil, humioapi.IngestTokenNotFound(hit.Spec.Name) +} + +func (h *ClientConfig) UpdateIngestToken(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { + if hit.Spec.ParserName != nil { + _, err := humiographql.AssignParserToIngestToken( + ctx, + client, + hit.Spec.RepositoryName, + hit.Spec.Name, + *hit.Spec.ParserName, + ) + return err + } + + _, err := humiographql.UnassignParserToIngestToken( + ctx, + client, + hit.Spec.RepositoryName, + hit.Spec.Name, + ) + return err +} + +func (h *ClientConfig) DeleteIngestToken(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { + _, err := humiographql.RemoveIngestToken( + ctx, + client, + hit.Spec.RepositoryName, + hit.Spec.Name, + ) + return err +} + +func (h *ClientConfig) AddParser(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) error { + _, err := humiographql.CreateParserOrUpdate( + ctx, + client, + hp.Spec.RepositoryName, + hp.Spec.Name, + hp.Spec.ParserScript, + humioapi.TestDataToParserTestCaseInput(hp.Spec.TestData), + hp.Spec.TagFields, + []string{}, + false, + ) + return err +} + +func (h *ClientConfig) GetParser(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) (*humiographql.ParserDetails, error) { + // list parsers to get the parser ID + resp, err := humiographql.ListParsers( + ctx, + client, + hp.Spec.RepositoryName, + ) + if err != nil { + return nil, err + } + respRepoForParserList := resp.GetRepository() + parserList := respRepoForParserList.GetParsers() + parserID := "" + for i := range parserList { + if parserList[i].Name == hp.Spec.Name { + parserID = parserList[i].GetId() + break + } + } + if parserID == "" { + return nil, humioapi.ParserNotFound(hp.Spec.Name) + } + + // lookup details for the parser id + respDetails, err := humiographql.GetParserByID( + ctx, + client, + hp.Spec.RepositoryName, + parserID, + ) + if err != nil { + return nil, err + } + + respRepoForParser := respDetails.GetRepository() + respParser := respRepoForParser.GetParser() + if respParser != nil { + return &respParser.ParserDetails, nil + } + + return nil, humioapi.ParserNotFound(hp.Spec.Name) +} + +func (h *ClientConfig) UpdateParser(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) error { + _, err := humiographql.CreateParserOrUpdate( + ctx, + client, + hp.Spec.RepositoryName, + hp.Spec.Name, + hp.Spec.ParserScript, + humioapi.TestDataToParserTestCaseInput(hp.Spec.TestData), + hp.Spec.TagFields, + []string{}, + true, + ) + return err +} + +func (h *ClientConfig) DeleteParser(ctx context.Context, client *humioapi.Client, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { + parser, err := h.GetParser(ctx, client, req, hp) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + _, err = humiographql.DeleteParserByID( + ctx, + client, + hp.Spec.RepositoryName, + parser.Id, + ) + return err +} + +func (h *ClientConfig) AddRepository(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + _, err := humiographql.CreateRepository( + ctx, + client, + hr.Spec.Name, + ) + return err +} + +func (h *ClientConfig) GetRepository(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humiographql.RepositoryDetails, error) { + getRepositoryResp, err := humiographql.GetRepository( + ctx, + client, + hr.Spec.Name, + ) + if err != nil { + return nil, humioapi.RepositoryNotFound(hr.Spec.Name) + } + + repository := getRepositoryResp.GetRepository() + return &humiographql.RepositoryDetails{ + Id: repository.GetId(), + Name: repository.GetName(), + Description: repository.GetDescription(), + TimeBasedRetention: repository.GetTimeBasedRetention(), + IngestSizeBasedRetention: repository.GetIngestSizeBasedRetention(), + StorageSizeBasedRetention: repository.GetStorageSizeBasedRetention(), + CompressedByteSize: repository.GetCompressedByteSize(), + AutomaticSearch: repository.GetAutomaticSearch(), + }, nil +} + +func (h *ClientConfig) UpdateRepository(ctx context.Context, client *humioapi.Client, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + curRepository, err := h.GetRepository(ctx, client, req, hr) + if err != nil { + return err + } + + if cmp.Diff(curRepository.GetDescription(), &hr.Spec.Description) != "" { + _, err = humiographql.UpdateDescriptionForSearchDomain( + ctx, + client, + hr.Spec.Name, + hr.Spec.Description, + ) + if err != nil { + return err + } + } + + var desiredRetentionTimeInDays *float64 + if hr.Spec.Retention.TimeInDays != nil { + desiredRetentionTimeInDaysFloat := float64(*hr.Spec.Retention.TimeInDays) + desiredRetentionTimeInDays = &desiredRetentionTimeInDaysFloat + } + if cmp.Diff(curRepository.GetTimeBasedRetention(), desiredRetentionTimeInDays) != "" { + if desiredRetentionTimeInDays != nil && *desiredRetentionTimeInDays > 0 { + if curRepository.GetTimeBasedRetention() == nil || *desiredRetentionTimeInDays < *curRepository.GetTimeBasedRetention() { + if !hr.Spec.AllowDataDeletion { + return fmt.Errorf("repository may contain data and data deletion not enabled") + } + } + } + + _, err = humiographql.UpdateTimeBasedRetention( + ctx, + client, + hr.Spec.Name, + desiredRetentionTimeInDays, + ) + if err != nil { + return err + } + } + + var desiredRetentionStorageSizeInGB *float64 + if hr.Spec.Retention.StorageSizeInGB != nil { + desiredRetentionStorageSizeInGBFloat := float64(*hr.Spec.Retention.StorageSizeInGB) + desiredRetentionStorageSizeInGB = &desiredRetentionStorageSizeInGBFloat + } + if cmp.Diff(curRepository.GetStorageSizeBasedRetention(), desiredRetentionStorageSizeInGB) != "" { + if desiredRetentionStorageSizeInGB != nil && *desiredRetentionStorageSizeInGB > 0 { + if curRepository.GetStorageSizeBasedRetention() == nil || *desiredRetentionStorageSizeInGB < *curRepository.GetStorageSizeBasedRetention() { + if !hr.Spec.AllowDataDeletion { + return fmt.Errorf("repository may contain data and data deletion not enabled") + } + } + } + + _, err = humiographql.UpdateStorageBasedRetention( + ctx, + client, + hr.Spec.Name, + desiredRetentionStorageSizeInGB, + ) + if err != nil { + return err + } + } + + var desiredRetentionIngestSizeInGB *float64 + if hr.Spec.Retention.IngestSizeInGB != nil { + desiredRetentionIngestSizeInGBFloat := float64(*hr.Spec.Retention.IngestSizeInGB) + desiredRetentionIngestSizeInGB = &desiredRetentionIngestSizeInGBFloat + } + if cmp.Diff(curRepository.GetIngestSizeBasedRetention(), desiredRetentionIngestSizeInGB) != "" { + if desiredRetentionIngestSizeInGB != nil && *desiredRetentionIngestSizeInGB > 0 { + if curRepository.GetIngestSizeBasedRetention() == nil || *desiredRetentionIngestSizeInGB < *curRepository.GetIngestSizeBasedRetention() { + if !hr.Spec.AllowDataDeletion { + return fmt.Errorf("repository may contain data and data deletion not enabled") + } + } + } + + _, err = humiographql.UpdateIngestBasedRetention( + ctx, + client, + hr.Spec.Name, + desiredRetentionIngestSizeInGB, + ) + + if err != nil { + return err + } + } + + if curRepository.AutomaticSearch != helpers.BoolTrue(hr.Spec.AutomaticSearch) { + _, err = humiographql.SetAutomaticSearching( + ctx, + client, + hr.Spec.Name, + helpers.BoolTrue(hr.Spec.AutomaticSearch), + ) + if err != nil { + return err + } + } + + return nil +} + +func (h *ClientConfig) DeleteRepository(ctx context.Context, client *humioapi.Client, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + _, err := h.GetRepository(ctx, client, req, hr) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + if !hr.Spec.AllowDataDeletion { + return fmt.Errorf("repository may contain data and data deletion not enabled") + } + + _, err = humiographql.DeleteSearchDomain( + ctx, + client, + hr.Spec.Name, + "deleted by humio-operator", + ) + return err +} + +func (h *ClientConfig) GetView(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hv *humiov1alpha1.HumioView) (*humiographql.GetSearchDomainSearchDomainView, error) { + resp, err := humiographql.GetSearchDomain( + ctx, + client, + hv.Spec.Name, + ) + if err != nil { + return nil, humioapi.ViewNotFound(hv.Spec.Name) + } + + searchDomain := resp.GetSearchDomain() + switch v := searchDomain.(type) { + case *humiographql.GetSearchDomainSearchDomainView: + return v, nil + default: + return nil, humioapi.ViewNotFound(hv.Spec.Name) + } +} + +func (h *ClientConfig) AddView(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hv *humiov1alpha1.HumioView) error { + viewConnections := hv.GetViewConnections() + internalConnType := make([]humiographql.ViewConnectionInput, len(viewConnections)) + for i := range viewConnections { + internalConnType[i] = humiographql.ViewConnectionInput{ + RepositoryName: viewConnections[i].Repository.Name, + Filter: viewConnections[i].Filter, + } + } + _, err := humiographql.CreateView( + ctx, + client, + hv.Spec.Name, + &hv.Spec.Description, + internalConnType, + ) + return err +} + +func (h *ClientConfig) UpdateView(ctx context.Context, client *humioapi.Client, req reconcile.Request, hv *humiov1alpha1.HumioView) error { + curView, err := h.GetView(ctx, client, req, hv) + if err != nil { + return err + } + + if cmp.Diff(curView.Description, &hv.Spec.Description) != "" { + _, err = humiographql.UpdateDescriptionForSearchDomain( + ctx, + client, + hv.Spec.Name, + hv.Spec.Description, + ) + if err != nil { + return err + } + } + + if curView.AutomaticSearch != helpers.BoolTrue(hv.Spec.AutomaticSearch) { + _, err = humiographql.SetAutomaticSearching( + ctx, + client, + hv.Spec.Name, + helpers.BoolTrue(hv.Spec.AutomaticSearch), + ) + if err != nil { + return err + } + } + + connections := hv.GetViewConnections() + if cmp.Diff(curView.Connections, connections) != "" { + internalConnType := make([]humiographql.ViewConnectionInput, len(connections)) + for i := range connections { + internalConnType[i] = humiographql.ViewConnectionInput{ + RepositoryName: connections[i].Repository.Name, + Filter: connections[i].Filter, + } + } + _, err = humiographql.UpdateViewConnections( + ctx, + client, + hv.Spec.Name, + internalConnType, + ) + if err != nil { + return err + } + } + + return nil +} + +func (h *ClientConfig) DeleteView(ctx context.Context, client *humioapi.Client, req reconcile.Request, hv *humiov1alpha1.HumioView) error { + _, err := h.GetView(ctx, client, req, hv) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + _, err = humiographql.DeleteSearchDomain( + ctx, + client, + hv.Spec.Name, + "Deleted by humio-operator", + ) + return err +} + +func validateSearchDomain(ctx context.Context, client *humioapi.Client, searchDomainName string) error { + resp, err := humiographql.GetSearchDomain( + ctx, + client, + searchDomainName, + ) + if err != nil { + return fmt.Errorf("got error fetching searchdomain: %w", err) + } + if resp != nil { + return nil + } + + return humioapi.SearchDomainNotFound(searchDomainName) +} + +func (h *ClientConfig) GetAction(ctx context.Context, client *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAction) (humiographql.ActionDetails, error) { + err := validateSearchDomain(ctx, client, ha.Spec.ViewName) + if err != nil { + return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) + } + + resp, err := humiographql.ListActions( + ctx, + client, + ha.Spec.ViewName, + ) + if err != nil { + return nil, err + } + respSearchDomain := resp.GetSearchDomain() + respSearchDomainActions := respSearchDomain.GetActions() + for idx := range respSearchDomainActions { + if respSearchDomainActions[idx].GetName() == ha.Spec.Name { + switch v := respSearchDomainActions[idx].(type) { + case *humiographql.ListActionsSearchDomainActionsEmailAction: + return &humiographql.ActionDetailsEmailAction{ + Id: v.GetId(), + Name: v.GetName(), + Recipients: v.GetRecipients(), + SubjectTemplate: v.GetSubjectTemplate(), + EmailBodyTemplate: v.GetEmailBodyTemplate(), + UseProxy: v.GetUseProxy(), + }, nil + case *humiographql.ListActionsSearchDomainActionsHumioRepoAction: + return &humiographql.ActionDetailsHumioRepoAction{ + Id: v.GetId(), + Name: v.GetName(), + IngestToken: v.GetIngestToken(), + }, nil + case *humiographql.ListActionsSearchDomainActionsOpsGenieAction: + return &humiographql.ActionDetailsOpsGenieAction{ + Id: v.GetId(), + Name: v.GetName(), + ApiUrl: v.GetApiUrl(), + GenieKey: v.GetGenieKey(), + UseProxy: v.GetUseProxy(), + }, nil + case *humiographql.ListActionsSearchDomainActionsPagerDutyAction: + return &humiographql.ActionDetailsPagerDutyAction{ + Id: v.GetId(), + Name: v.GetName(), + Severity: v.GetSeverity(), + RoutingKey: v.GetRoutingKey(), + UseProxy: v.GetUseProxy(), + }, nil + case *humiographql.ListActionsSearchDomainActionsSlackAction: + return &humiographql.ActionDetailsSlackAction{ + Id: v.GetId(), + Name: v.GetName(), + Url: v.GetUrl(), + Fields: v.GetFields(), + UseProxy: v.GetUseProxy(), + }, nil + case *humiographql.ListActionsSearchDomainActionsSlackPostMessageAction: + return &humiographql.ActionDetailsSlackPostMessageAction{ + Id: v.GetId(), + Name: v.GetName(), + ApiToken: v.GetApiToken(), + Channels: v.GetChannels(), + Fields: v.GetFields(), + UseProxy: v.GetUseProxy(), + }, nil + case *humiographql.ListActionsSearchDomainActionsVictorOpsAction: + return &humiographql.ActionDetailsVictorOpsAction{ + Id: v.GetId(), + Name: v.GetName(), + MessageType: v.GetMessageType(), + NotifyUrl: v.GetNotifyUrl(), + UseProxy: v.GetUseProxy(), + }, nil + case *humiographql.ListActionsSearchDomainActionsWebhookAction: + return &humiographql.ActionDetailsWebhookAction{ + Id: v.GetId(), + Name: v.GetName(), + Method: v.GetMethod(), + Url: v.GetUrl(), + Headers: v.GetHeaders(), + WebhookBodyTemplate: v.GetWebhookBodyTemplate(), + IgnoreSSL: v.GetIgnoreSSL(), + UseProxy: v.GetUseProxy(), + }, nil + } + } + } + + return nil, humioapi.ActionNotFound(ha.Spec.Name) +} + +func (h *ClientConfig) AddAction(ctx context.Context, client *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAction) error { + err := validateSearchDomain(ctx, client, ha.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) + } + + newActionWithResolvedSecrets, err := ActionFromActionCR(ha) + if err != nil { + return err + } + + switch v := (newActionWithResolvedSecrets).(type) { + case *humiographql.ActionDetailsEmailAction: + _, err = humiographql.CreateEmailAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetRecipients(), + v.GetSubjectTemplate(), + v.GetEmailBodyTemplate(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsHumioRepoAction: + _, err = humiographql.CreateHumioRepoAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetIngestToken(), + ) + return err + case *humiographql.ActionDetailsOpsGenieAction: + _, err = humiographql.CreateOpsGenieAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetApiUrl(), + v.GetGenieKey(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsPagerDutyAction: + _, err = humiographql.CreatePagerDutyAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetSeverity(), + v.GetRoutingKey(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsSlackAction: + resolvedFields := v.GetFields() + fields := make([]humiographql.SlackFieldEntryInput, len(resolvedFields)) + for idx := range resolvedFields { + fields[idx] = humiographql.SlackFieldEntryInput{ + FieldName: resolvedFields[idx].GetFieldName(), + Value: resolvedFields[idx].GetValue(), + } + } + _, err = humiographql.CreateSlackAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + fields, + v.GetUrl(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsSlackPostMessageAction: + resolvedFields := v.GetFields() + fields := make([]humiographql.SlackFieldEntryInput, len(resolvedFields)) + for idx := range resolvedFields { + fields[idx] = humiographql.SlackFieldEntryInput{ + FieldName: resolvedFields[idx].GetFieldName(), + Value: resolvedFields[idx].GetValue(), + } + } + _, err = humiographql.CreateSlackPostMessageAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetApiToken(), + v.GetChannels(), + fields, + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsVictorOpsAction: + _, err = humiographql.CreateVictorOpsAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetMessageType(), + v.GetNotifyUrl(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsWebhookAction: + resolvedHeaders := v.GetHeaders() + headers := make([]humiographql.HttpHeaderEntryInput, len(resolvedHeaders)) + for idx := range resolvedHeaders { + headers[idx] = humiographql.HttpHeaderEntryInput{ + Header: resolvedHeaders[idx].GetHeader(), + Value: resolvedHeaders[idx].GetValue(), + } + } + _, err = humiographql.CreateWebhookAction( + ctx, + client, + ha.Spec.ViewName, + v.GetName(), + v.GetUrl(), + v.GetMethod(), + headers, + v.GetWebhookBodyTemplate(), + v.GetIgnoreSSL(), + v.GetUseProxy(), + ) + return err + } + + return fmt.Errorf("no action details specified or unsupported action type used") +} + +func (h *ClientConfig) UpdateAction(ctx context.Context, client *humioapi.Client, req reconcile.Request, ha *humiov1alpha1.HumioAction) error { + err := validateSearchDomain(ctx, client, ha.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) + } + + newActionWithResolvedSecrets, err := ActionFromActionCR(ha) + if err != nil { + return err + } + + currentAction, err := h.GetAction(ctx, client, req, ha) + if err != nil { + return fmt.Errorf("could not find action with name: %q", ha.Spec.Name) + } + + switch v := (newActionWithResolvedSecrets).(type) { + case *humiographql.ActionDetailsEmailAction: + _, err = humiographql.UpdateEmailAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetRecipients(), + v.GetSubjectTemplate(), + v.GetEmailBodyTemplate(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsHumioRepoAction: + _, err = humiographql.UpdateHumioRepoAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetIngestToken(), + ) + return err + case *humiographql.ActionDetailsOpsGenieAction: + _, err = humiographql.UpdateOpsGenieAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetApiUrl(), + v.GetGenieKey(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsPagerDutyAction: + _, err = humiographql.UpdatePagerDutyAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetSeverity(), + v.GetRoutingKey(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsSlackAction: + resolvedFields := v.GetFields() + fields := make([]humiographql.SlackFieldEntryInput, len(resolvedFields)) + for idx := range resolvedFields { + fields[idx] = humiographql.SlackFieldEntryInput{ + FieldName: resolvedFields[idx].GetFieldName(), + Value: resolvedFields[idx].GetValue(), + } + } + _, err = humiographql.UpdateSlackAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + fields, + v.GetUrl(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsSlackPostMessageAction: + resolvedFields := v.GetFields() + fields := make([]humiographql.SlackFieldEntryInput, len(resolvedFields)) + for idx := range resolvedFields { + fields[idx] = humiographql.SlackFieldEntryInput{ + FieldName: resolvedFields[idx].GetFieldName(), + Value: resolvedFields[idx].GetValue(), + } + } + _, err = humiographql.UpdateSlackPostMessageAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetApiToken(), + v.GetChannels(), + fields, + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsVictorOpsAction: + _, err = humiographql.UpdateVictorOpsAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetMessageType(), + v.GetNotifyUrl(), + v.GetUseProxy(), + ) + return err + case *humiographql.ActionDetailsWebhookAction: + resolvedHeaders := v.GetHeaders() + headers := make([]humiographql.HttpHeaderEntryInput, len(resolvedHeaders)) + for idx := range resolvedHeaders { + headers[idx] = humiographql.HttpHeaderEntryInput{ + Header: resolvedHeaders[idx].GetHeader(), + Value: resolvedHeaders[idx].GetValue(), + } + } + _, err = humiographql.UpdateWebhookAction( + ctx, + client, + ha.Spec.ViewName, + currentAction.GetId(), + v.GetName(), + v.GetUrl(), + v.GetMethod(), + headers, + v.GetWebhookBodyTemplate(), + v.GetIgnoreSSL(), + v.GetUseProxy(), + ) + return err + } + + return fmt.Errorf("no action details specified or unsupported action type used") +} + +func (h *ClientConfig) DeleteAction(ctx context.Context, client *humioapi.Client, req reconcile.Request, ha *humiov1alpha1.HumioAction) error { + action, err := h.GetAction(ctx, client, req, ha) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + if action.GetId() == "" { + return humioapi.ActionNotFound(action.GetId()) + } + + _, err = humiographql.DeleteActionByID( + ctx, + client, + ha.Spec.ViewName, + action.GetId(), + ) + return err +} + +func (h *ClientConfig) GetLicenseUIDAndExpiry(ctx context.Context, client *humioapi.Client, _ reconcile.Request) (string, time.Time, error) { + resp, err := humiographql.GetLicense( + ctx, + client, + ) + if err != nil { + return "", time.Time{}, err + } + + installedLicense := resp.GetInstalledLicense() + if installedLicense == nil { + return "", time.Time{}, humioapi.EntityNotFound{} + } + + switch v := (*installedLicense).(type) { + case *humiographql.GetLicenseInstalledLicenseOnPremLicense: + return v.GetUid(), v.GetExpiresAt(), nil + default: + return "", time.Time{}, fmt.Errorf("unknown license type %t", v) + } +} + +func (h *ClientConfig) InstallLicense(ctx context.Context, client *humioapi.Client, _ reconcile.Request, license string) error { + _, err := humiographql.UpdateLicenseKey( + ctx, + client, + license, + ) + return err + +} + +func (h *ClientConfig) GetAlert(ctx context.Context, client *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humiographql.AlertDetails, error) { + err := validateSearchDomain(ctx, client, ha.Spec.ViewName) + if err != nil { + if !errors.As(err, &humioapi.EntityNotFound{}) { + return nil, fmt.Errorf("problem getting view for alert %s: %w", ha.Spec.Name, err) + } + } + + resp, err := humiographql.ListAlerts( + ctx, + client, + ha.Spec.ViewName, + ) + if err != nil { + return nil, err + } + respSearchDomain := resp.GetSearchDomain() + respAlerts := respSearchDomain.GetAlerts() + for idx := range respAlerts { + if respAlerts[idx].Name == ha.Spec.Name { + return &humiographql.AlertDetails{ + Id: respAlerts[idx].GetId(), + Name: respAlerts[idx].GetName(), + QueryString: respAlerts[idx].GetQueryString(), + QueryStart: respAlerts[idx].GetQueryStart(), + ThrottleField: respAlerts[idx].GetThrottleField(), + Description: respAlerts[idx].GetDescription(), + ThrottleTimeMillis: respAlerts[idx].GetThrottleTimeMillis(), + Enabled: respAlerts[idx].GetEnabled(), + ActionsV2: respAlerts[idx].GetActionsV2(), + Labels: respAlerts[idx].GetLabels(), + QueryOwnership: respAlerts[idx].GetQueryOwnership(), + }, nil + } + } + + return nil, humioapi.AlertNotFound(ha.Spec.Name) +} + +func (h *ClientConfig) AddAlert(ctx context.Context, client *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAlert) error { + err := validateSearchDomain(ctx, client, ha.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for alert: %w", err) + } + + isEnabled := !ha.Spec.Silenced + queryOwnershipType := humiographql.QueryOwnershipTypeOrganization + _, err = humiographql.CreateAlert( + ctx, + client, + ha.Spec.ViewName, + ha.Spec.Name, + &ha.Spec.Description, + ha.Spec.Query.QueryString, + ha.Spec.Query.Start, + int64(ha.Spec.ThrottleTimeMillis), + &isEnabled, + ha.Spec.Actions, + ha.Spec.Labels, + &queryOwnershipType, + ha.Spec.ThrottleField, + ) + return err +} + +func (h *ClientConfig) UpdateAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, ha *humiov1alpha1.HumioAlert) error { + err := validateSearchDomain(ctx, client, ha.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for action: %w", err) + } + + currentAlert, err := h.GetAlert(ctx, client, req, ha) + if err != nil { + return fmt.Errorf("could not find alert with name: %q", ha.Spec.Name) + } + + queryOwnershipType := humiographql.QueryOwnershipTypeOrganization + _, err = humiographql.UpdateAlert( + ctx, + client, + ha.Spec.ViewName, + currentAlert.GetId(), + ha.Spec.Name, + &ha.Spec.Description, + ha.Spec.Query.QueryString, + ha.Spec.Query.Start, + int64(ha.Spec.ThrottleTimeMillis), + !ha.Spec.Silenced, + ha.Spec.Actions, + ha.Spec.Labels, + &queryOwnershipType, + ha.Spec.ThrottleField, + ) + return err +} + +func (h *ClientConfig) DeleteAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, ha *humiov1alpha1.HumioAlert) error { + alert, err := h.GetAlert(ctx, client, req, ha) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + _, err = humiographql.DeleteAlertByID( + ctx, + client, + ha.Spec.ViewName, + alert.GetId(), + ) + return err +} + +func (h *ClientConfig) GetFilterAlert(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humiographql.FilterAlertDetails, error) { + err := validateSearchDomain(ctx, client, hfa.Spec.ViewName) + if err != nil { + return nil, fmt.Errorf("problem getting view for filter alert %s: %w", hfa.Spec.Name, err) + } + + respList, err := humiographql.ListFilterAlerts( + ctx, + client, + hfa.Spec.ViewName, + ) + if err != nil { + return nil, err + } + respSearchDomain := respList.GetSearchDomain() + respFilterAlerts := respSearchDomain.GetFilterAlerts() + + var filterAlertId string + for _, filterAlert := range respFilterAlerts { + if filterAlert.Name == hfa.Spec.Name { + filterAlertId = filterAlert.GetId() + } + } + if filterAlertId == "" { + return nil, humioapi.FilterAlertNotFound(hfa.Spec.Name) + } + + respGet, err := humiographql.GetFilterAlertByID( + ctx, + client, + hfa.Spec.ViewName, + filterAlertId, + ) + if err != nil { + return nil, err + } + respFilterAlert := respGet.GetSearchDomain().GetFilterAlert() + return &respFilterAlert.FilterAlertDetails, nil +} + +func (h *ClientConfig) AddFilterAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + err := validateSearchDomain(ctx, client, hfa.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for filter alert: %w", err) + } + if err = h.ValidateActionsForFilterAlert(ctx, client, req, hfa); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + + _, err = humiographql.CreateFilterAlert( + ctx, + client, + hfa.Spec.ViewName, + hfa.Spec.Name, + &hfa.Spec.Description, + hfa.Spec.QueryString, + hfa.Spec.Actions, + hfa.Spec.Labels, + hfa.Spec.Enabled, + hfa.Spec.ThrottleField, + int64(hfa.Spec.ThrottleTimeSeconds), + humiographql.QueryOwnershipTypeOrganization, + ) + return err +} + +func (h *ClientConfig) UpdateFilterAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + err := validateSearchDomain(ctx, client, hfa.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for action: %w", err) + } + if err = h.ValidateActionsForFilterAlert(ctx, client, req, hfa); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + + currentAlert, err := h.GetFilterAlert(ctx, client, req, hfa) + if err != nil { + return fmt.Errorf("could not find filter alert with name: %q", hfa.Spec.Name) + } + + _, err = humiographql.UpdateFilterAlert( + ctx, + client, + hfa.Spec.ViewName, + currentAlert.GetId(), + hfa.Spec.Name, + &hfa.Spec.Description, + hfa.Spec.QueryString, + hfa.Spec.Actions, + hfa.Spec.Labels, + hfa.Spec.Enabled, + hfa.Spec.ThrottleField, + int64(hfa.Spec.ThrottleTimeSeconds), + humiographql.QueryOwnershipTypeOrganization, + ) + return err +} + +func (h *ClientConfig) DeleteFilterAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + currentFilterAlert, err := h.GetFilterAlert(ctx, client, req, hfa) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + _, err = humiographql.DeleteFilterAlert( + ctx, + client, + hfa.Spec.ViewName, + currentFilterAlert.GetId(), + ) + return err +} + +func (h *ClientConfig) AddScheduledSearch(ctx context.Context, client *humioapi.Client, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + err := validateSearchDomain(ctx, client, hss.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for scheduled search: %w", err) + } + if err = h.ValidateActionsForScheduledSearch(ctx, client, req, hss); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + queryOwnershipType := humiographql.QueryOwnershipTypeOrganization + _, err = humiographql.CreateScheduledSearch( + ctx, + client, + hss.Spec.ViewName, + hss.Spec.Name, + &hss.Spec.Description, + hss.Spec.QueryString, + hss.Spec.QueryStart, + hss.Spec.QueryEnd, + hss.Spec.Schedule, + hss.Spec.TimeZone, + hss.Spec.BackfillLimit, + hss.Spec.Enabled, + hss.Spec.Actions, + hss.Spec.Labels, + &queryOwnershipType, + ) + return err +} + +func (h *ClientConfig) GetScheduledSearch(ctx context.Context, client *humioapi.Client, _ reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humiographql.ScheduledSearchDetails, error) { + err := validateSearchDomain(ctx, client, hss.Spec.ViewName) + if err != nil { + return nil, fmt.Errorf("problem getting view for scheduled search %s: %w", hss.Spec.Name, err) + } + + var scheduledSearchId string + respList, err := humiographql.ListScheduledSearches( + ctx, + client, + hss.Spec.ViewName, + ) + if err != nil { + return nil, err + } + respListSearchDomain := respList.GetSearchDomain() + for _, scheduledSearch := range respListSearchDomain.GetScheduledSearches() { + if scheduledSearch.Name == hss.Spec.Name { + scheduledSearchId = scheduledSearch.GetId() + } + } + if scheduledSearchId == "" { + return nil, humioapi.ScheduledSearchNotFound(hss.Spec.Name) + } + + respGet, err := humiographql.GetScheduledSearchByID( + ctx, + client, + hss.Spec.ViewName, + scheduledSearchId, + ) + if err != nil { + return nil, err + } + respGetSearchDomain := respGet.GetSearchDomain() + respGetScheduledSearch := respGetSearchDomain.GetScheduledSearch() + return &respGetScheduledSearch.ScheduledSearchDetails, nil +} + +func (h *ClientConfig) UpdateScheduledSearch(ctx context.Context, client *humioapi.Client, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + err := validateSearchDomain(ctx, client, hss.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for scheduled search: %w", err) + } + if err = h.ValidateActionsForScheduledSearch(ctx, client, req, hss); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + currentScheduledSearch, err := h.GetScheduledSearch(ctx, client, req, hss) + if err != nil { + return fmt.Errorf("could not find scheduled search with name: %q", hss.Spec.Name) + } + + queryOwnershipType := humiographql.QueryOwnershipTypeOrganization + _, err = humiographql.UpdateScheduledSearch( + ctx, + client, + hss.Spec.ViewName, + currentScheduledSearch.GetId(), + hss.Spec.Name, + &hss.Spec.Description, + hss.Spec.QueryString, + hss.Spec.QueryStart, + hss.Spec.QueryEnd, + hss.Spec.Schedule, + hss.Spec.TimeZone, + hss.Spec.BackfillLimit, + hss.Spec.Enabled, + hss.Spec.Actions, + hss.Spec.Labels, + &queryOwnershipType, + ) + return err +} + +func (h *ClientConfig) DeleteScheduledSearch(ctx context.Context, client *humioapi.Client, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + currentScheduledSearch, err := h.GetScheduledSearch(ctx, client, req, hss) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + _, err = humiographql.DeleteScheduledSearchByID( + ctx, + client, + hss.Spec.ViewName, + currentScheduledSearch.GetId(), + ) + return err +} + +func (h *ClientConfig) getAndValidateAction(ctx context.Context, client *humioapi.Client, req reconcile.Request, actionName string, viewName string) error { + action := &humiov1alpha1.HumioAction{ + Spec: humiov1alpha1.HumioActionSpec{ + Name: actionName, + ViewName: viewName, + }, + } + + _, err := h.GetAction(ctx, client, req, action) + return err +} + +func (h *ClientConfig) ValidateActionsForFilterAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + for _, actionNameForAlert := range hfa.Spec.Actions { + if err := h.getAndValidateAction(ctx, client, req, actionNameForAlert, hfa.Spec.ViewName); err != nil { + return fmt.Errorf("problem getting action for filter alert %s: %w", hfa.Spec.Name, err) + } + } + return nil +} + +func (h *ClientConfig) ValidateActionsForScheduledSearch(ctx context.Context, client *humioapi.Client, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + for _, actionNameForScheduledSearch := range hss.Spec.Actions { + if err := h.getAndValidateAction(ctx, client, req, actionNameForScheduledSearch, hss.Spec.ViewName); err != nil { + return fmt.Errorf("problem getting action for scheduled search %s: %w", hss.Spec.Name, err) + } + } + return nil +} + +func (h *ClientConfig) AddAggregateAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + err := validateSearchDomain(ctx, client, haa.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for action: %w", err) + } + if err = h.ValidateActionsForAggregateAlert(ctx, client, req, haa); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + + _, err = humiographql.CreateAggregateAlert( + ctx, + client, + haa.Spec.ViewName, + haa.Spec.Name, + &haa.Spec.Description, + haa.Spec.QueryString, + int64(haa.Spec.SearchIntervalSeconds), + haa.Spec.Actions, + haa.Spec.Labels, + haa.Spec.Enabled, + haa.Spec.ThrottleField, + int64(haa.Spec.ThrottleTimeSeconds), + humiographql.TriggerMode(haa.Spec.TriggerMode), + humiographql.QueryTimestampType(haa.Spec.QueryTimestampType), + humiographql.QueryOwnershipTypeOrganization, + ) + return err +} + +func (h *ClientConfig) GetAggregateAlert(ctx context.Context, client *humioapi.Client, _ reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humiographql.AggregateAlertDetails, error) { + err := validateSearchDomain(ctx, client, haa.Spec.ViewName) + if err != nil { + return nil, fmt.Errorf("problem getting view for action %s: %w", haa.Spec.Name, err) + } + + var aggregateAlertId string + respList, err := humiographql.ListAggregateAlerts( + ctx, + client, + haa.Spec.ViewName, + ) + if err != nil { + return nil, err + } + respSearchDomain := respList.GetSearchDomain() + respAggregateAlerts := respSearchDomain.GetAggregateAlerts() + for _, aggregateAlert := range respAggregateAlerts { + if aggregateAlert.Name == haa.Spec.Name { + aggregateAlertId = aggregateAlert.GetId() + } + } + if aggregateAlertId == "" { + return nil, humioapi.AggregateAlertNotFound(haa.Spec.Name) + } + respGet, err := humiographql.GetAggregateAlertByID( + ctx, + client, + haa.Spec.ViewName, + aggregateAlertId, + ) + if err != nil { + return nil, err + } + respAggregateAlert := respGet.GetSearchDomain().GetAggregateAlert() + return &respAggregateAlert.AggregateAlertDetails, nil +} + +func (h *ClientConfig) UpdateAggregateAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + err := validateSearchDomain(ctx, client, haa.Spec.ViewName) + if err != nil { + return fmt.Errorf("problem getting view for action %s: %w", haa.Spec.Name, err) + } + if err = h.ValidateActionsForAggregateAlert(ctx, client, req, haa); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + currentAggregateAlert, err := h.GetAggregateAlert(ctx, client, req, haa) + if err != nil { + return fmt.Errorf("could not find aggregate alert with name: %q", haa.Spec.Name) + } + + _, err = humiographql.UpdateAggregateAlert( + ctx, + client, + haa.Spec.ViewName, + currentAggregateAlert.GetId(), + haa.Spec.Name, + &haa.Spec.Description, + haa.Spec.QueryString, + int64(haa.Spec.SearchIntervalSeconds), + haa.Spec.Actions, + haa.Spec.Labels, + haa.Spec.Enabled, + haa.Spec.ThrottleField, + int64(haa.Spec.ThrottleTimeSeconds), + humiographql.TriggerMode(haa.Spec.TriggerMode), + humiographql.QueryTimestampType(haa.Spec.QueryTimestampType), + humiographql.QueryOwnershipTypeOrganization, + ) + return err +} + +func (h *ClientConfig) DeleteAggregateAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + currentAggregateAlert, err := h.GetAggregateAlert(ctx, client, req, haa) + if err != nil { + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } + return err + } + + _, err = humiographql.DeleteAggregateAlert( + ctx, + client, + haa.Spec.ViewName, + currentAggregateAlert.GetId(), + ) + return err +} + +func (h *ClientConfig) ValidateActionsForAggregateAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + // validate action + for _, actionNameForAlert := range haa.Spec.Actions { + if err := h.getAndValidateAction(ctx, client, req, actionNameForAlert, haa.Spec.ViewName); err != nil { + return fmt.Errorf("problem getting action for aggregate alert %s: %w", haa.Spec.Name, err) + } + } + return nil +} + +func (h *ClientConfig) GetUserIDForUsername(ctx context.Context, client *humioapi.Client, _ reconcile.Request, username string) (string, error) { + resp, err := humiographql.GetUsersByUsername( + ctx, + client, + username, + ) + if err != nil { + return "", err + } + + respUsers := resp.GetUsers() + for _, user := range respUsers { + if user.Username == username { + return user.GetId(), nil + } + } + + return "", humioapi.UserNotFound(username) +} + +func (h *ClientConfig) RotateUserApiTokenAndGet(ctx context.Context, client *humioapi.Client, _ reconcile.Request, userID string) (string, error) { + if userID == "" { + return "", fmt.Errorf("userID must not be empty") + } + resp, err := humiographql.RotateTokenByID( + ctx, + client, + userID, + ) + if err != nil { + return "", err + } + + return resp.GetRotateToken(), nil +} + +func (h *ClientConfig) AddUserAndGetUserID(ctx context.Context, client *humioapi.Client, _ reconcile.Request, username string, isRoot bool) (string, error) { + resp, err := humiographql.AddUser( + ctx, + client, + username, + &isRoot, + ) + if err != nil { + return "", err + } + + createdUser := resp.GetAddUserV2() + switch v := createdUser.(type) { + case *humiographql.AddUserAddUserV2User: + return v.GetId(), nil + default: + return "", fmt.Errorf("got unknown user type=%v", v) + } +} diff --git a/internal/humio/client_mock.go b/internal/humio/client_mock.go new file mode 100644 index 00000000..c3168878 --- /dev/null +++ b/internal/humio/client_mock.go @@ -0,0 +1,1277 @@ +/* +Copyright 2020 Humio https://humio.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package humio + +import ( + "context" + "fmt" + "net/url" + "sync" + "time" + + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" + humioapi "github.com/humio/humio-operator/internal/api" + "github.com/humio/humio-operator/internal/api/humiographql" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/kubernetes" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +var ( + humioClientMu sync.Mutex +) + +type resourceKey struct { + // clusterName holds the value of the cluster + clusterName string + // searchDomainName is the name of the repository or view + searchDomainName string + // resourceName is the name of resource, like IngestToken, Parser, etc. + resourceName string +} + +type ClientMock struct { + LicenseUID map[resourceKey]string + Repository map[resourceKey]humiographql.RepositoryDetails + View map[resourceKey]humiographql.GetSearchDomainSearchDomainView + IngestToken map[resourceKey]humiographql.IngestTokenDetails + Parser map[resourceKey]humiographql.ParserDetails + Action map[resourceKey]humiographql.ActionDetails + Alert map[resourceKey]humiographql.AlertDetails + FilterAlert map[resourceKey]humiographql.FilterAlertDetails + AggregateAlert map[resourceKey]humiographql.AggregateAlertDetails + ScheduledSearch map[resourceKey]humiographql.ScheduledSearchDetails + UserID map[resourceKey]string +} + +type MockClientConfig struct { + apiClient *ClientMock +} + +func NewMockClient() *MockClientConfig { + mockClientConfig := &MockClientConfig{ + apiClient: &ClientMock{ + LicenseUID: make(map[resourceKey]string), + Repository: make(map[resourceKey]humiographql.RepositoryDetails), + View: make(map[resourceKey]humiographql.GetSearchDomainSearchDomainView), + IngestToken: make(map[resourceKey]humiographql.IngestTokenDetails), + Parser: make(map[resourceKey]humiographql.ParserDetails), + Action: make(map[resourceKey]humiographql.ActionDetails), + Alert: make(map[resourceKey]humiographql.AlertDetails), + FilterAlert: make(map[resourceKey]humiographql.FilterAlertDetails), + AggregateAlert: make(map[resourceKey]humiographql.AggregateAlertDetails), + ScheduledSearch: make(map[resourceKey]humiographql.ScheduledSearchDetails), + UserID: make(map[resourceKey]string), + }, + } + + return mockClientConfig +} + +func (h *MockClientConfig) ClearHumioClientConnections(repoNameToKeep string) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + for k := range h.apiClient.Repository { + if k.resourceName != repoNameToKeep { + delete(h.apiClient.Repository, k) + } + } + h.apiClient.View = make(map[resourceKey]humiographql.GetSearchDomainSearchDomainView) + h.apiClient.IngestToken = make(map[resourceKey]humiographql.IngestTokenDetails) + h.apiClient.Parser = make(map[resourceKey]humiographql.ParserDetails) + h.apiClient.Action = make(map[resourceKey]humiographql.ActionDetails) + h.apiClient.Alert = make(map[resourceKey]humiographql.AlertDetails) + h.apiClient.FilterAlert = make(map[resourceKey]humiographql.FilterAlertDetails) + h.apiClient.AggregateAlert = make(map[resourceKey]humiographql.AggregateAlertDetails) + h.apiClient.ScheduledSearch = make(map[resourceKey]humiographql.ScheduledSearchDetails) + h.apiClient.UserID = make(map[resourceKey]string) +} + +func (h *MockClientConfig) Status(_ context.Context, _ *humioapi.Client, _ reconcile.Request) (*humioapi.StatusResponse, error) { + return &humioapi.StatusResponse{ + Version: "x.y.z", + }, nil +} + +func (h *MockClientConfig) GetClusters(_ context.Context, _ *humioapi.Client, _ reconcile.Request) (*humiographql.GetClusterResponse, error) { + return nil, nil +} + +func (h *MockClientConfig) TestAPIToken(_ context.Context, _ *humioapi.Config, _ reconcile.Request) error { + return nil +} + +func (h *MockClientConfig) AddIngestToken(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hit.Spec.RepositoryName) { + return fmt.Errorf("search domain name does not exist") + } + + key := resourceKey{ + clusterName: clusterName, + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + + if _, found := h.apiClient.IngestToken[key]; found { + return fmt.Errorf("ingest token already exists with name %s", hit.Spec.Name) + } + + var parser *humiographql.IngestTokenDetailsParser + if hit.Spec.ParserName != nil { + parser = &humiographql.IngestTokenDetailsParser{Name: *hit.Spec.ParserName} + } + h.apiClient.IngestToken[key] = humiographql.IngestTokenDetails{ + Name: hit.Spec.Name, + Parser: parser, + Token: kubernetes.RandomString(), + } + return nil +} + +func (h *MockClientConfig) GetIngestToken(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humiographql.IngestTokenDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + if value, found := h.apiClient.IngestToken[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find ingest token in repository %s with name %s, err=%w", hit.Spec.RepositoryName, hit.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) UpdateIngestToken(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + + currentIngestToken, found := h.apiClient.IngestToken[key] + + if !found { + return fmt.Errorf("ingest token not found with name %s, err=%w", hit.Spec.Name, humioapi.EntityNotFound{}) + } + + var parser *humiographql.IngestTokenDetailsParser + if hit.Spec.ParserName != nil { + parser = &humiographql.IngestTokenDetailsParser{Name: *hit.Spec.ParserName} + } + h.apiClient.IngestToken[key] = humiographql.IngestTokenDetails{ + Name: hit.Spec.Name, + Parser: parser, + Token: currentIngestToken.GetToken(), + } + + return nil +} + +func (h *MockClientConfig) DeleteIngestToken(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + + delete(h.apiClient.IngestToken, key) + return nil +} + +func (h *MockClientConfig) AddParser(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hp.Spec.RepositoryName) { + return fmt.Errorf("search domain name does not exist") + } + + key := resourceKey{ + clusterName: clusterName, + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, + } + + if _, found := h.apiClient.Parser[key]; found { + return fmt.Errorf("parser already exists with name %s", hp.Spec.Name) + } + + h.apiClient.Parser[key] = humiographql.ParserDetails{ + Id: kubernetes.RandomString(), + Name: hp.Spec.Name, + Script: hp.Spec.ParserScript, + FieldsToTag: hp.Spec.TagFields, + TestCases: humioapi.TestDataToParserDetailsTestCasesParserTestCase(hp.Spec.TestData), + } + return nil +} + +func (h *MockClientConfig) GetParser(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) (*humiographql.ParserDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, + } + if value, found := h.apiClient.Parser[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find parser in repository %s with name %s, err=%w", hp.Spec.RepositoryName, hp.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) UpdateParser(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, + } + + currentParser, found := h.apiClient.Parser[key] + + if !found { + return fmt.Errorf("parser not found with name %s, err=%w", hp.Spec.Name, humioapi.EntityNotFound{}) + } + + h.apiClient.Parser[key] = humiographql.ParserDetails{ + Id: currentParser.GetId(), + Name: hp.Spec.Name, + Script: hp.Spec.ParserScript, + FieldsToTag: hp.Spec.TagFields, + TestCases: humioapi.TestDataToParserDetailsTestCasesParserTestCase(hp.Spec.TestData), + } + return nil +} + +func (h *MockClientConfig) DeleteParser(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hp *humiov1alpha1.HumioParser) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, + } + + delete(h.apiClient.Parser, key) + return nil +} + +func (h *MockClientConfig) AddRepository(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName) + if h.searchDomainNameExists(clusterName, hr.Spec.Name) { + return fmt.Errorf("search domain name already in use") + } + + key := resourceKey{ + clusterName: clusterName, + resourceName: hr.Spec.Name, + } + + if _, found := h.apiClient.Repository[key]; found { + return fmt.Errorf("repository already exists with name %s", hr.Spec.Name) + } + + var retentionInDays, ingestSizeInGB, storageSizeInGB float64 + if hr.Spec.Retention.TimeInDays != nil { + retentionInDays = float64(*hr.Spec.Retention.TimeInDays) + } + if hr.Spec.Retention.IngestSizeInGB != nil { + ingestSizeInGB = float64(*hr.Spec.Retention.IngestSizeInGB) + } + if hr.Spec.Retention.StorageSizeInGB != nil { + storageSizeInGB = float64(*hr.Spec.Retention.StorageSizeInGB) + } + + value := &humiographql.RepositoryDetails{ + Id: kubernetes.RandomString(), + Name: hr.Spec.Name, + Description: &hr.Spec.Description, + TimeBasedRetention: &retentionInDays, + IngestSizeBasedRetention: &ingestSizeInGB, + StorageSizeBasedRetention: &storageSizeInGB, + AutomaticSearch: helpers.BoolTrue(hr.Spec.AutomaticSearch), + } + + h.apiClient.Repository[key] = *value + return nil +} + +func (h *MockClientConfig) GetRepository(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humiographql.RepositoryDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + if value, found := h.apiClient.Repository[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find repository with name %s, err=%w", hr.Spec.Name, humioapi.EntityNotFound{}) + +} + +func (h *MockClientConfig) UpdateRepository(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + + currentRepository, found := h.apiClient.Repository[key] + + if !found { + return fmt.Errorf("repository not found with name %s, err=%w", hr.Spec.Name, humioapi.EntityNotFound{}) + } + + var retentionInDays, ingestSizeInGB, storageSizeInGB float64 + if hr.Spec.Retention.TimeInDays != nil { + retentionInDays = float64(*hr.Spec.Retention.TimeInDays) + } + if hr.Spec.Retention.IngestSizeInGB != nil { + ingestSizeInGB = float64(*hr.Spec.Retention.IngestSizeInGB) + } + if hr.Spec.Retention.StorageSizeInGB != nil { + storageSizeInGB = float64(*hr.Spec.Retention.StorageSizeInGB) + } + value := &humiographql.RepositoryDetails{ + Id: currentRepository.GetId(), + Name: hr.Spec.Name, + Description: &hr.Spec.Description, + TimeBasedRetention: &retentionInDays, + IngestSizeBasedRetention: &ingestSizeInGB, + StorageSizeBasedRetention: &storageSizeInGB, + AutomaticSearch: helpers.BoolTrue(hr.Spec.AutomaticSearch), + } + + h.apiClient.Repository[key] = *value + return nil +} + +func (h *MockClientConfig) DeleteRepository(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + // TODO: consider finding all entities referring to this searchDomainName and remove them as well + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + + delete(h.apiClient.Repository, key) + return nil +} + +func (h *MockClientConfig) GetView(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hv *humiov1alpha1.HumioView) (*humiographql.GetSearchDomainSearchDomainView, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + if value, found := h.apiClient.View[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find view with name %s, err=%w", hv.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) AddView(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hv *humiov1alpha1.HumioView) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName) + if h.searchDomainNameExists(clusterName, hv.Spec.Name) { + return fmt.Errorf("search domain name already in use") + } + + key := resourceKey{ + clusterName: clusterName, + resourceName: hv.Spec.Name, + } + + if _, found := h.apiClient.Repository[key]; found { + return fmt.Errorf("view already exists with name %s", hv.Spec.Name) + } + + connections := make([]humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection, 0) + for _, connection := range hv.Spec.Connections { + connections = append(connections, humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection{ + Repository: humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository{ + Name: connection.RepositoryName, + }, + Filter: connection.Filter, + }) + } + + value := &humiographql.GetSearchDomainSearchDomainView{ + Typename: helpers.StringPtr("View"), + Id: kubernetes.RandomString(), + Name: hv.Spec.Name, + Description: &hv.Spec.Description, + AutomaticSearch: helpers.BoolTrue(hv.Spec.AutomaticSearch), + Connections: connections, + } + h.apiClient.View[key] = *value + return nil +} + +func (h *MockClientConfig) UpdateView(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hv *humiov1alpha1.HumioView) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + + currentView, found := h.apiClient.View[key] + + if !found { + return fmt.Errorf("view not found with name %s, err=%w", hv.Spec.Name, humioapi.EntityNotFound{}) + } + + connections := make([]humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection, 0) + for _, connection := range hv.Spec.Connections { + connections = append(connections, humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnection{ + Repository: humiographql.GetSearchDomainSearchDomainViewConnectionsViewConnectionRepository{ + Name: connection.RepositoryName, + }, + Filter: connection.Filter, + }) + } + + value := &humiographql.GetSearchDomainSearchDomainView{ + Typename: helpers.StringPtr("View"), + Id: currentView.GetId(), + Name: hv.Spec.Name, + Description: &hv.Spec.Description, + Connections: connections, + AutomaticSearch: helpers.BoolTrue(hv.Spec.AutomaticSearch), + } + h.apiClient.View[key] = *value + return nil +} + +func (h *MockClientConfig) DeleteView(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hv *humiov1alpha1.HumioView) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + // TODO: consider finding all entities referring to this searchDomainName and remove them as well + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + + delete(h.apiClient.View, key) + return nil +} + +func (h *MockClientConfig) GetLicenseUIDAndExpiry(_ context.Context, _ *humioapi.Client, req reconcile.Request) (string, time.Time, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + + if value, found := h.apiClient.LicenseUID[key]; found { + return value, time.Now(), nil + } + + return "", time.Time{}, humioapi.EntityNotFound{} +} + +func (h *MockClientConfig) InstallLicense(_ context.Context, _ *humioapi.Client, req reconcile.Request, licenseString string) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + + licenseUID, err := GetLicenseUIDFromLicenseString(licenseString) + if err != nil { + return fmt.Errorf("failed to parse license: %w", err) + } + + h.apiClient.LicenseUID[key] = licenseUID + return nil +} + +func (h *MockClientConfig) GetAction(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAction) (humiographql.ActionDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + if value, found := h.apiClient.Action[key]; found { + return value, nil + + } + return nil, fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) AddAction(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAction) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, ha.Spec.ViewName) { + return fmt.Errorf("search domain name does not exist") + } + + key := resourceKey{ + clusterName: clusterName, + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + if _, found := h.apiClient.Action[key]; found { + return fmt.Errorf("action already exists with name %s", ha.Spec.Name) + } + + newActionWithResolvedSecrets, err := ActionFromActionCR(ha) + if err != nil { + return err + } + + switch v := (newActionWithResolvedSecrets).(type) { + case *humiographql.ActionDetailsEmailAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsEmailAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + Recipients: v.GetRecipients(), + SubjectTemplate: v.GetSubjectTemplate(), + EmailBodyTemplate: v.GetEmailBodyTemplate(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsHumioRepoAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsHumioRepoAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + IngestToken: v.GetIngestToken(), + } + case *humiographql.ActionDetailsOpsGenieAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsOpsGenieAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + ApiUrl: v.GetApiUrl(), + GenieKey: v.GetGenieKey(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsPagerDutyAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsPagerDutyAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + Severity: v.GetSeverity(), + RoutingKey: v.GetRoutingKey(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsSlackAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsSlackAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + Url: v.GetUrl(), + Fields: v.GetFields(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsSlackPostMessageAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsSlackPostMessageAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + ApiToken: v.GetApiToken(), + Channels: v.GetChannels(), + Fields: v.GetFields(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsVictorOpsAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsVictorOpsAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + MessageType: v.GetMessageType(), + NotifyUrl: v.GetNotifyUrl(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsWebhookAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsWebhookAction{ + Id: kubernetes.RandomString(), + Name: v.GetName(), + Method: v.GetMethod(), + Url: v.GetUrl(), + Headers: v.GetHeaders(), + WebhookBodyTemplate: v.GetWebhookBodyTemplate(), + IgnoreSSL: v.GetIgnoreSSL(), + UseProxy: v.GetUseProxy(), + } + } + + return nil +} + +func (h *MockClientConfig) UpdateAction(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAction) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + currentAction, found := h.apiClient.Action[key] + + if !found { + return fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) + } + + newActionWithResolvedSecrets, err := ActionFromActionCR(ha) + if err != nil { + return err + } + + switch v := (newActionWithResolvedSecrets).(type) { + case *humiographql.ActionDetailsEmailAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsEmailAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + Recipients: v.GetRecipients(), + SubjectTemplate: v.GetSubjectTemplate(), + EmailBodyTemplate: v.GetEmailBodyTemplate(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsHumioRepoAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsHumioRepoAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + IngestToken: v.GetIngestToken(), + } + case *humiographql.ActionDetailsOpsGenieAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsOpsGenieAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + ApiUrl: v.GetApiUrl(), + GenieKey: v.GetGenieKey(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsPagerDutyAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsPagerDutyAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + Severity: v.GetSeverity(), + RoutingKey: v.GetRoutingKey(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsSlackAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsSlackAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + Url: v.GetUrl(), + Fields: v.GetFields(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsSlackPostMessageAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsSlackPostMessageAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + ApiToken: v.GetApiToken(), + Channels: v.GetChannels(), + Fields: v.GetFields(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsVictorOpsAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsVictorOpsAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + MessageType: v.GetMessageType(), + NotifyUrl: v.GetNotifyUrl(), + UseProxy: v.GetUseProxy(), + } + case *humiographql.ActionDetailsWebhookAction: + h.apiClient.Action[key] = &humiographql.ActionDetailsWebhookAction{ + Id: currentAction.GetId(), + Name: v.GetName(), + Method: v.GetMethod(), + Url: v.GetUrl(), + Headers: v.GetHeaders(), + WebhookBodyTemplate: v.GetWebhookBodyTemplate(), + IgnoreSSL: v.GetIgnoreSSL(), + UseProxy: v.GetUseProxy(), + } + } + + return nil +} + +func (h *MockClientConfig) DeleteAction(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAction) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + delete(h.apiClient.Action, key) + return nil +} + +func (h *MockClientConfig) GetAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humiographql.AlertDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + if value, found := h.apiClient.Alert[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) AddAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, ha.Spec.ViewName) { + return fmt.Errorf("search domain name does not exist") + } + + key := resourceKey{ + clusterName: clusterName, + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + if _, found := h.apiClient.Alert[key]; found { + return fmt.Errorf("alert already exists with name %s", ha.Spec.Name) + } + + h.apiClient.Alert[key] = humiographql.AlertDetails{ + Id: kubernetes.RandomString(), + Name: ha.Spec.Name, + QueryString: ha.Spec.Query.QueryString, + QueryStart: ha.Spec.Query.Start, + ThrottleField: ha.Spec.ThrottleField, + Description: &ha.Spec.Description, + ThrottleTimeMillis: int64(ha.Spec.ThrottleTimeMillis), + Enabled: !ha.Spec.Silenced, + ActionsV2: humioapi.ActionNamesToEmailActions(ha.Spec.Actions), + Labels: ha.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + return nil +} + +func (h *MockClientConfig) UpdateAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + currentAlert, found := h.apiClient.Alert[key] + if !found { + return fmt.Errorf("alert not found with name %s, err=%w", ha.Spec.Name, humioapi.EntityNotFound{}) + } + + h.apiClient.Alert[key] = humiographql.AlertDetails{ + Id: currentAlert.GetId(), + Name: ha.Spec.Name, + QueryString: ha.Spec.Query.QueryString, + QueryStart: ha.Spec.Query.Start, + ThrottleField: ha.Spec.ThrottleField, + Description: &ha.Spec.Description, + ThrottleTimeMillis: int64(ha.Spec.ThrottleTimeMillis), + Enabled: !ha.Spec.Silenced, + ActionsV2: humioapi.ActionNamesToEmailActions(ha.Spec.Actions), + Labels: ha.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + return nil +} + +func (h *MockClientConfig) DeleteAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, ha *humiov1alpha1.HumioAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + delete(h.apiClient.Alert, key) + return nil +} + +func (h *MockClientConfig) GetFilterAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humiographql.FilterAlertDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, + } + if value, found := h.apiClient.FilterAlert[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) AddFilterAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hfa.Spec.ViewName) { + return fmt.Errorf("search domain name does not exist") + } + + key := resourceKey{ + clusterName: clusterName, + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, + } + + if _, found := h.apiClient.FilterAlert[key]; found { + return fmt.Errorf("filter alert already exists with name %s", hfa.Spec.Name) + } + + h.apiClient.FilterAlert[key] = humiographql.FilterAlertDetails{ + Id: kubernetes.RandomString(), + Name: hfa.Spec.Name, + Description: &hfa.Spec.Description, + QueryString: hfa.Spec.QueryString, + ThrottleTimeSeconds: helpers.Int64Ptr(int64(hfa.Spec.ThrottleTimeSeconds)), + ThrottleField: hfa.Spec.ThrottleField, + Labels: hfa.Spec.Labels, + Enabled: hfa.Spec.Enabled, + Actions: humioapi.ActionNamesToEmailActions(hfa.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + return nil +} + +func (h *MockClientConfig) UpdateFilterAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, + } + + currentFilterAlert, found := h.apiClient.FilterAlert[key] + + if !found { + return fmt.Errorf("could not find filter alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) + } + + h.apiClient.FilterAlert[key] = humiographql.FilterAlertDetails{ + Id: currentFilterAlert.GetId(), + Name: hfa.Spec.Name, + Description: &hfa.Spec.Description, + QueryString: hfa.Spec.QueryString, + ThrottleTimeSeconds: helpers.Int64Ptr(int64(hfa.Spec.ThrottleTimeSeconds)), + ThrottleField: hfa.Spec.ThrottleField, + Labels: hfa.Spec.Labels, + Enabled: hfa.Spec.Enabled, + Actions: humioapi.ActionNamesToEmailActions(hfa.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + return nil +} + +func (h *MockClientConfig) DeleteFilterAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, + } + + delete(h.apiClient.FilterAlert, key) + return nil +} + +func (h *MockClientConfig) ValidateActionsForFilterAlert(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error { + return nil +} + +func (h *MockClientConfig) GetAggregateAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humiographql.AggregateAlertDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, + } + if value, found := h.apiClient.AggregateAlert[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) AddAggregateAlert(ctx context.Context, client *humioapi.Client, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, + } + + if _, found := h.apiClient.AggregateAlert[key]; found { + return fmt.Errorf("aggregate alert already exists with name %s", haa.Spec.Name) + } + if err := h.ValidateActionsForAggregateAlert(ctx, client, req, haa); err != nil { + return fmt.Errorf("could not get action id mapping: %w", err) + } + + h.apiClient.AggregateAlert[key] = humiographql.AggregateAlertDetails{ + Id: kubernetes.RandomString(), + Name: haa.Spec.Name, + Description: &haa.Spec.Description, + QueryString: haa.Spec.QueryString, + SearchIntervalSeconds: int64(haa.Spec.SearchIntervalSeconds), + ThrottleTimeSeconds: int64(haa.Spec.ThrottleTimeSeconds), + ThrottleField: haa.Spec.ThrottleField, + Labels: haa.Spec.Labels, + Enabled: haa.Spec.Enabled, + TriggerMode: humiographql.TriggerMode(haa.Spec.TriggerMode), + QueryTimestampType: humiographql.QueryTimestampType(haa.Spec.QueryTimestampType), + Actions: humioapi.ActionNamesToEmailActions(haa.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + return nil +} + +func (h *MockClientConfig) UpdateAggregateAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, + } + + currentAggregateAlert, found := h.apiClient.AggregateAlert[key] + + if !found { + return fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) + } + + h.apiClient.AggregateAlert[key] = humiographql.AggregateAlertDetails{ + Id: currentAggregateAlert.GetId(), + Name: haa.Spec.Name, + Description: &haa.Spec.Description, + QueryString: haa.Spec.QueryString, + SearchIntervalSeconds: int64(haa.Spec.SearchIntervalSeconds), + ThrottleTimeSeconds: int64(haa.Spec.ThrottleTimeSeconds), + ThrottleField: haa.Spec.ThrottleField, + Labels: haa.Spec.Labels, + Enabled: haa.Spec.Enabled, + TriggerMode: humiographql.TriggerMode(haa.Spec.TriggerMode), + QueryTimestampType: humiographql.QueryTimestampType(haa.Spec.QueryTimestampType), + Actions: humioapi.ActionNamesToEmailActions(haa.Spec.Actions), + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + } + return nil +} + +func (h *MockClientConfig) DeleteAggregateAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, + } + + delete(h.apiClient.AggregateAlert, key) + return nil +} + +func (h *MockClientConfig) ValidateActionsForAggregateAlert(_ context.Context, _ *humioapi.Client, _ reconcile.Request, _ *humiov1alpha1.HumioAggregateAlert) error { + return nil +} + +func (h *MockClientConfig) AddScheduledSearch(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + clusterName := fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hss.Spec.ViewName) { + return fmt.Errorf("search domain name does not exist") + } + + key := resourceKey{ + clusterName: clusterName, + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + + if _, found := h.apiClient.ScheduledSearch[key]; found { + return fmt.Errorf("scheduled search already exists with name %s", hss.Spec.Name) + } + + h.apiClient.ScheduledSearch[key] = humiographql.ScheduledSearchDetails{ + Id: kubernetes.RandomString(), + Name: hss.Spec.Name, + Description: &hss.Spec.Description, + QueryString: hss.Spec.QueryString, + Start: hss.Spec.QueryStart, + End: hss.Spec.QueryEnd, + TimeZone: hss.Spec.TimeZone, + Schedule: hss.Spec.Schedule, + BackfillLimit: hss.Spec.BackfillLimit, + Enabled: hss.Spec.Enabled, + Labels: hss.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + ActionsV2: humioapi.ActionNamesToEmailActions(hss.Spec.Actions), + } + return nil +} + +func (h *MockClientConfig) GetScheduledSearch(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humiographql.ScheduledSearchDetails, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + if value, found := h.apiClient.ScheduledSearch[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) +} + +func (h *MockClientConfig) UpdateScheduledSearch(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + + currentScheduledSearch, found := h.apiClient.ScheduledSearch[key] + + if !found { + return fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) + } + + h.apiClient.ScheduledSearch[key] = humiographql.ScheduledSearchDetails{ + Id: currentScheduledSearch.GetId(), + Name: hss.Spec.Name, + Description: &hss.Spec.Description, + QueryString: hss.Spec.QueryString, + Start: hss.Spec.QueryStart, + End: hss.Spec.QueryEnd, + TimeZone: hss.Spec.TimeZone, + Schedule: hss.Spec.Schedule, + BackfillLimit: hss.Spec.BackfillLimit, + Enabled: hss.Spec.Enabled, + Labels: hss.Spec.Labels, + QueryOwnership: &humiographql.SharedQueryOwnershipTypeOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + QueryOwnershipOrganizationOwnership: humiographql.QueryOwnershipOrganizationOwnership{ + Typename: helpers.StringPtr("OrganizationOwnership"), + }, + }, + ActionsV2: humioapi.ActionNamesToEmailActions(hss.Spec.Actions), + } + return nil +} + +func (h *MockClientConfig) DeleteScheduledSearch(_ context.Context, _ *humioapi.Client, _ reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + + delete(h.apiClient.ScheduledSearch, key) + return nil +} + +func (h *MockClientConfig) ValidateActionsForScheduledSearch(context.Context, *humioapi.Client, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error { + return nil +} + +func (h *MockClientConfig) GetHumioHttpClient(_ *humioapi.Config, _ ctrl.Request) *humioapi.Client { + clusterURL, _ := url.Parse("http://localhost:8080/") + return humioapi.NewClient(humioapi.Config{Address: clusterURL}) +} + +// searchDomainNameExists returns a boolean if either a repository or view exists with the given search domain name. +// It assumes the caller already holds the lock humioClientMu. +func (h *MockClientConfig) searchDomainNameExists(clusterName, searchDomainName string) bool { + key := resourceKey{ + clusterName: clusterName, + resourceName: searchDomainName, + } + + if _, found := h.apiClient.Repository[key]; found { + return true + } + + if _, found := h.apiClient.View[key]; found { + return true + } + + return false +} + +func (h *MockClientConfig) GetUserIDForUsername(_ context.Context, _ *humioapi.Client, req reconcile.Request, _ string) (string, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + + currentUserID, found := h.apiClient.UserID[key] + if !found { + return "", humioapi.EntityNotFound{} + } + + return currentUserID, nil +} + +func (h *MockClientConfig) RotateUserApiTokenAndGet(_ context.Context, _ *humioapi.Client, req reconcile.Request, _ string) (string, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + + currentUserID, found := h.apiClient.UserID[key] + if !found { + return "", fmt.Errorf("could not find user") + } + + return currentUserID, nil +} + +func (h *MockClientConfig) AddUserAndGetUserID(_ context.Context, _ *humioapi.Client, req reconcile.Request, _ string, _ bool) (string, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + + h.apiClient.UserID[key] = kubernetes.RandomString() + return h.apiClient.UserID[key], nil +} diff --git a/internal/humio/license.go b/internal/humio/license.go new file mode 100644 index 00000000..cd8cd445 --- /dev/null +++ b/internal/humio/license.go @@ -0,0 +1,31 @@ +package humio + +import ( + "fmt" + + "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/jwt" +) + +type license struct { + UID string `json:"uid,omitempty"` +} + +// GetLicenseUIDFromLicenseString parses the user-specified license string and returns the id of the license +func GetLicenseUIDFromLicenseString(licenseString string) (string, error) { + token, err := jwt.ParseSigned(licenseString, []jose.SignatureAlgorithm{jose.ES256, jose.ES512}) + if err != nil { + return "", fmt.Errorf("error when parsing license: %w", err) + } + + licenseContent := &license{} + err = token.UnsafeClaimsWithoutVerification(&licenseContent) + if err != nil { + return "", fmt.Errorf("error when parsing license: %w", err) + } + if licenseContent.UID == "" { + return "", fmt.Errorf("error when parsing license, license was valid jwt string but missing uid") + } + + return licenseContent.UID, nil +} diff --git a/pkg/kubernetes/certificates.go b/internal/kubernetes/certificates.go similarity index 100% rename from pkg/kubernetes/certificates.go rename to internal/kubernetes/certificates.go diff --git a/pkg/kubernetes/cluster_role_bindings.go b/internal/kubernetes/cluster_role_bindings.go similarity index 100% rename from pkg/kubernetes/cluster_role_bindings.go rename to internal/kubernetes/cluster_role_bindings.go diff --git a/pkg/kubernetes/cluster_roles.go b/internal/kubernetes/cluster_roles.go similarity index 100% rename from pkg/kubernetes/cluster_roles.go rename to internal/kubernetes/cluster_roles.go diff --git a/pkg/kubernetes/configmaps.go b/internal/kubernetes/configmaps.go similarity index 100% rename from pkg/kubernetes/configmaps.go rename to internal/kubernetes/configmaps.go diff --git a/pkg/kubernetes/humio_bootstrap_tokens.go b/internal/kubernetes/humio_bootstrap_tokens.go similarity index 100% rename from pkg/kubernetes/humio_bootstrap_tokens.go rename to internal/kubernetes/humio_bootstrap_tokens.go diff --git a/pkg/kubernetes/humioaction_secret_helpers.go b/internal/kubernetes/humioaction_secret_helpers.go similarity index 99% rename from pkg/kubernetes/humioaction_secret_helpers.go rename to internal/kubernetes/humioaction_secret_helpers.go index 6989c674..f6ccc58d 100644 --- a/pkg/kubernetes/humioaction_secret_helpers.go +++ b/internal/kubernetes/humioaction_secret_helpers.go @@ -2,8 +2,9 @@ package kubernetes import ( "fmt" - "github.com/humio/humio-operator/api/v1alpha1" "sync" + + "github.com/humio/humio-operator/api/v1alpha1" ) var ( diff --git a/pkg/kubernetes/ingresses.go b/internal/kubernetes/ingresses.go similarity index 99% rename from pkg/kubernetes/ingresses.go rename to internal/kubernetes/ingresses.go index 67bba1a2..d6fb43cc 100644 --- a/pkg/kubernetes/ingresses.go +++ b/internal/kubernetes/ingresses.go @@ -18,6 +18,7 @@ package kubernetes import ( "context" + "k8s.io/apimachinery/pkg/types" networkingv1 "k8s.io/api/networking/v1" diff --git a/pkg/kubernetes/kubernetes.go b/internal/kubernetes/kubernetes.go similarity index 89% rename from pkg/kubernetes/kubernetes.go rename to internal/kubernetes/kubernetes.go index 4ad3159f..4cd36908 100644 --- a/pkg/kubernetes/kubernetes.go +++ b/internal/kubernetes/kubernetes.go @@ -45,16 +45,6 @@ func MatchingLabelsForHumio(clusterName string) client.MatchingLabels { return LabelsForHumio(clusterName) } -// LabelListContainsLabel returns true if the set of labels contain a label with the specified name -func LabelListContainsLabel(labelList map[string]string, label string) bool { - for labelName := range labelList { - if labelName == label { - return true - } - } - return false -} - // RandomString returns a string of fixed length. The random strings are valid to use in Kubernetes object names. func RandomString() string { chars := []rune("abcdefghijklmnopqrstuvwxyz") diff --git a/pkg/kubernetes/nodes.go b/internal/kubernetes/nodes.go similarity index 100% rename from pkg/kubernetes/nodes.go rename to internal/kubernetes/nodes.go diff --git a/pkg/kubernetes/persistent_volume_claims.go b/internal/kubernetes/persistent_volume_claims.go similarity index 100% rename from pkg/kubernetes/persistent_volume_claims.go rename to internal/kubernetes/persistent_volume_claims.go diff --git a/pkg/kubernetes/pods.go b/internal/kubernetes/pods.go similarity index 95% rename from pkg/kubernetes/pods.go rename to internal/kubernetes/pods.go index f195e62e..f4381077 100644 --- a/pkg/kubernetes/pods.go +++ b/internal/kubernetes/pods.go @@ -24,7 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -// ListPods grabs the list of all pods associated to a an instance of HumioCluster +// ListPods grabs the list of all pods associated to an instance of HumioCluster func ListPods(ctx context.Context, c client.Client, humioClusterNamespace string, matchingLabels client.MatchingLabels) ([]corev1.Pod, error) { var foundPodList corev1.PodList err := c.List(ctx, &foundPodList, client.InNamespace(humioClusterNamespace), matchingLabels) diff --git a/pkg/kubernetes/secrets.go b/internal/kubernetes/secrets.go similarity index 100% rename from pkg/kubernetes/secrets.go rename to internal/kubernetes/secrets.go diff --git a/pkg/kubernetes/service_accounts.go b/internal/kubernetes/service_accounts.go similarity index 100% rename from pkg/kubernetes/service_accounts.go rename to internal/kubernetes/service_accounts.go diff --git a/pkg/kubernetes/services.go b/internal/kubernetes/services.go similarity index 100% rename from pkg/kubernetes/services.go rename to internal/kubernetes/services.go diff --git a/main.go b/main.go index 0f6edcbe..9fbd2564 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,8 @@ import ( "os" "strings" + "github.com/humio/humio-operator/internal/helpers" + "github.com/humio/humio-operator/internal/humio" "sigs.k8s.io/controller-runtime/pkg/webhook" cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" @@ -38,9 +40,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/healthz" - "github.com/humio/humio-operator/pkg/helpers" - "github.com/humio/humio-operator/pkg/humio" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" "github.com/humio/humio-operator/controllers" //+kubebuilder:scaffold:imports diff --git a/pkg/humio/aggregatealert_transform.go b/pkg/humio/aggregatealert_transform.go deleted file mode 100644 index 8a183d68..00000000 --- a/pkg/humio/aggregatealert_transform.go +++ /dev/null @@ -1,45 +0,0 @@ -package humio - -import ( - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" -) - -func AggregateAlertTransform(haa *humiov1alpha1.HumioAggregateAlert) *humioapi.AggregateAlert { - aggregateAlert := &humioapi.AggregateAlert{ - Name: haa.Spec.Name, - QueryString: haa.Spec.QueryString, - QueryTimestampType: haa.Spec.QueryTimestampType, - Description: haa.Spec.Description, - SearchIntervalSeconds: haa.Spec.SearchIntervalSeconds, - ThrottleTimeSeconds: haa.Spec.ThrottleTimeSeconds, - ThrottleField: haa.Spec.ThrottleField, - TriggerMode: haa.Spec.TriggerMode, - Enabled: haa.Spec.Enabled, - ActionNames: haa.Spec.Actions, - Labels: haa.Spec.Labels, - QueryOwnershipType: humioapi.QueryOwnershipTypeOrganization, - } - - if aggregateAlert.Labels == nil { - aggregateAlert.Labels = []string{} - } - - return aggregateAlert -} - -func AggregateAlertHydrate(haa *humiov1alpha1.HumioAggregateAlert, aggregateAlert *humioapi.AggregateAlert) { - haa.Spec = humiov1alpha1.HumioAggregateAlertSpec{ - Name: aggregateAlert.Name, - QueryString: aggregateAlert.QueryString, - QueryTimestampType: aggregateAlert.QueryTimestampType, - Description: aggregateAlert.Description, - SearchIntervalSeconds: aggregateAlert.SearchIntervalSeconds, - ThrottleTimeSeconds: aggregateAlert.ThrottleTimeSeconds, - ThrottleField: aggregateAlert.ThrottleField, - TriggerMode: aggregateAlert.TriggerMode, - Enabled: aggregateAlert.Enabled, - Actions: aggregateAlert.ActionNames, - Labels: aggregateAlert.Labels, - } -} diff --git a/pkg/humio/alert_transform.go b/pkg/humio/alert_transform.go deleted file mode 100644 index 4c71792a..00000000 --- a/pkg/humio/alert_transform.go +++ /dev/null @@ -1,38 +0,0 @@ -package humio - -import ( - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" -) - -func AlertTransform(ha *humiov1alpha1.HumioAlert, actionIdMap map[string]string) *humioapi.Alert { - alert := &humioapi.Alert{ - Name: ha.Spec.Name, - QueryString: ha.Spec.Query.QueryString, - QueryStart: ha.Spec.Query.Start, - Description: ha.Spec.Description, - ThrottleTimeMillis: ha.Spec.ThrottleTimeMillis, - ThrottleField: ha.Spec.ThrottleField, - Enabled: !ha.Spec.Silenced, - Actions: actionIdsFromActionMap(ha.Spec.Actions, actionIdMap), - Labels: ha.Spec.Labels, - } - - if alert.QueryStart == "" { - alert.QueryStart = "1d" - } - - return alert -} - -func actionIdsFromActionMap(actionList []string, actionIdMap map[string]string) []string { - var actionIds []string - for _, action := range actionList { - for actionName, actionId := range actionIdMap { - if actionName == action { - actionIds = append(actionIds, actionId) - } - } - } - return actionIds -} diff --git a/pkg/humio/client.go b/pkg/humio/client.go deleted file mode 100644 index 01be6281..00000000 --- a/pkg/humio/client.go +++ /dev/null @@ -1,930 +0,0 @@ -/* -Copyright 2020 Humio https://humio.com - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package humio - -import ( - "errors" - "fmt" - "net/http" - "reflect" - "sync" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - graphql "github.com/cli/shurcooL-graphql" - "github.com/go-logr/logr" - - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/helpers" -) - -// Client is the interface that can be mocked -type Client interface { - ClusterClient - IngestTokensClient - ParsersClient - RepositoriesClient - ViewsClient - LicenseClient - ActionsClient - AlertsClient - FilterAlertsClient - AggregateAlertsClient - ScheduledSearchClient - UsersClient -} - -type ClusterClient interface { - GetClusters(*humioapi.Config, reconcile.Request) (humioapi.Cluster, error) - GetHumioClient(*humioapi.Config, reconcile.Request) *humioapi.Client - ClearHumioClientConnections(string) - TestAPIToken(*humioapi.Config, reconcile.Request) error - Status(*humioapi.Config, reconcile.Request) (*humioapi.StatusResponse, error) -} - -type IngestTokensClient interface { - AddIngestToken(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) - GetIngestToken(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) - UpdateIngestToken(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) - DeleteIngestToken(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioIngestToken) error -} - -type ParsersClient interface { - AddParser(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioParser) (*humioapi.Parser, error) - GetParser(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioParser) (*humioapi.Parser, error) - UpdateParser(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioParser) (*humioapi.Parser, error) - DeleteParser(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioParser) error -} - -type RepositoriesClient interface { - AddRepository(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) - GetRepository(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) - UpdateRepository(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) - DeleteRepository(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioRepository) error -} - -type ViewsClient interface { - AddView(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioView) (*humioapi.View, error) - GetView(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioView) (*humioapi.View, error) - UpdateView(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioView) (*humioapi.View, error) - DeleteView(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioView) error -} - -type ActionsClient interface { - AddAction(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAction) (*humioapi.Action, error) - GetAction(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAction) (*humioapi.Action, error) - UpdateAction(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAction) (*humioapi.Action, error) - DeleteAction(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAction) error -} - -type AlertsClient interface { - AddAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) - GetAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) - UpdateAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) - DeleteAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAlert) error - GetActionIDsMapForAlerts(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAlert) (map[string]string, error) -} - -type FilterAlertsClient interface { - AddFilterAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) - GetFilterAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) - UpdateFilterAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) - DeleteFilterAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error - ValidateActionsForFilterAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioFilterAlert) error -} - -type AggregateAlertsClient interface { - AddAggregateAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) - GetAggregateAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) - UpdateAggregateAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) - DeleteAggregateAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) error - ValidateActionsForAggregateAlert(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioAggregateAlert) error -} - -type ScheduledSearchClient interface { - AddScheduledSearch(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) - GetScheduledSearch(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) - UpdateScheduledSearch(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) - DeleteScheduledSearch(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error - ValidateActionsForScheduledSearch(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioScheduledSearch) error -} - -type LicenseClient interface { - GetLicense(*humioapi.Config, reconcile.Request) (humioapi.License, error) - InstallLicense(*humioapi.Config, reconcile.Request, string) error -} - -type UsersClient interface { - AddUser(*humioapi.Config, reconcile.Request, string, bool) (*humioapi.User, error) - ListAllHumioUsersInCurrentOrganization(*humioapi.Config, reconcile.Request) ([]user, error) - RotateUserApiTokenAndGet(*humioapi.Config, reconcile.Request, string) (string, error) -} - -// ClientConfig stores our Humio api client -type ClientConfig struct { - humioClients map[humioClientKey]*humioClientConnection - humioClientsMutex sync.Mutex - logger logr.Logger - userAgent string -} - -type humioClientKey struct { - namespace, name string - authenticated bool -} - -type humioClientConnection struct { - client *humioapi.Client - transport *http.Transport -} - -// NewClient returns a ClientConfig -func NewClient(logger logr.Logger, userAgent string) *ClientConfig { - return NewClientWithTransport(logger, userAgent) -} - -// NewClientWithTransport returns a ClientConfig using an existing http.Transport -func NewClientWithTransport(logger logr.Logger, userAgent string) *ClientConfig { - return &ClientConfig{ - logger: logger, - userAgent: userAgent, - humioClients: map[humioClientKey]*humioClientConnection{}, - } -} - -// GetHumioClient takes a Humio API config as input and returns an API client that uses this config -func (h *ClientConfig) GetHumioClient(config *humioapi.Config, req ctrl.Request) *humioapi.Client { - h.humioClientsMutex.Lock() - defer h.humioClientsMutex.Unlock() - - config.UserAgent = h.userAgent - key := humioClientKey{ - namespace: req.Namespace, - name: req.Name, - authenticated: config.Token != "", - } - - c := h.humioClients[key] - if c == nil { - transport := humioapi.NewHttpTransport(*config) - c = &humioClientConnection{ - client: humioapi.NewClientWithTransport(*config, transport), - transport: transport, - } - } else { - existingConfig := c.client.Config() - equal := existingConfig.Token == config.Token && - existingConfig.Insecure == config.Insecure && - existingConfig.CACertificatePEM == config.CACertificatePEM && - existingConfig.ProxyOrganization == config.ProxyOrganization && - existingConfig.Address.String() == config.Address.String() - - // If the cluster address or SSL configuration has changed, we must create a new transport - if !equal { - transport := humioapi.NewHttpTransport(*config) - c = &humioClientConnection{ - client: humioapi.NewClientWithTransport(*config, transport), - transport: transport, - } - - } - if c.transport == nil { - c.transport = humioapi.NewHttpTransport(*config) - } - // Always create a new client and use the existing transport. Since we're using the same transport, connections - // will be cached. - c.client = humioapi.NewClientWithTransport(*config, c.transport) - } - - h.humioClients[key] = c - - return c.client -} - -func (h *ClientConfig) ClearHumioClientConnections(string) { - h.humioClientsMutex.Lock() - defer h.humioClientsMutex.Unlock() - - h.humioClients = make(map[humioClientKey]*humioClientConnection) -} - -// Status returns the status of the humio cluster -func (h *ClientConfig) Status(config *humioapi.Config, req reconcile.Request) (*humioapi.StatusResponse, error) { - return h.GetHumioClient(config, req).Status() -} - -// GetClusters returns a humio cluster and can be mocked via the Client interface -func (h *ClientConfig) GetClusters(config *humioapi.Config, req reconcile.Request) (humioapi.Cluster, error) { - return h.GetHumioClient(config, req).Clusters().Get() -} - -// TestAPIToken tests if an API token is valid by fetching the username that the API token belongs to -func (h *ClientConfig) TestAPIToken(config *humioapi.Config, req reconcile.Request) error { - _, err := h.GetHumioClient(config, req).Viewer().Username() - return err -} - -func (h *ClientConfig) AddIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - return h.GetHumioClient(config, req).IngestTokens().Add(hit.Spec.RepositoryName, hit.Spec.Name, hit.Spec.ParserName) -} - -func (h *ClientConfig) GetIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - return h.GetHumioClient(config, req).IngestTokens().Get(hit.Spec.RepositoryName, hit.Spec.Name) -} - -func (h *ClientConfig) UpdateIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - return h.GetHumioClient(config, req).IngestTokens().Update(hit.Spec.RepositoryName, hit.Spec.Name, hit.Spec.ParserName) -} - -func (h *ClientConfig) DeleteIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { - return h.GetHumioClient(config, req).IngestTokens().Remove(hit.Spec.RepositoryName, hit.Spec.Name) -} - -func (h *ClientConfig) AddParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - parser := humioapi.Parser{ - Name: hp.Spec.Name, - Script: hp.Spec.ParserScript, - FieldsToTag: hp.Spec.TagFields, - } - - testCasesGQL := make([]humioapi.ParserTestCase, len(hp.Spec.TestData)) - for i := range hp.Spec.TestData { - testCasesGQL[i] = humioapi.ParserTestCase{ - Event: humioapi.ParserTestEvent{ - RawString: hp.Spec.TestData[i], - }, - } - } - parser.TestCases = testCasesGQL - - return h.GetHumioClient(config, req).Parsers().Add( - hp.Spec.RepositoryName, - &parser, - false, - ) -} - -func (h *ClientConfig) GetParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - return h.GetHumioClient(config, req).Parsers().Get(hp.Spec.RepositoryName, hp.Spec.Name) -} - -func (h *ClientConfig) UpdateParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - parser := humioapi.Parser{ - Name: hp.Spec.Name, - Script: hp.Spec.ParserScript, - FieldsToTag: hp.Spec.TagFields, - } - - testCasesGQL := make([]humioapi.ParserTestCase, len(hp.Spec.TestData)) - for i := range hp.Spec.TestData { - testCasesGQL[i] = humioapi.ParserTestCase{ - Event: humioapi.ParserTestEvent{RawString: hp.Spec.TestData[i]}, - } - } - parser.TestCases = testCasesGQL - - return h.GetHumioClient(config, req).Parsers().Add( - hp.Spec.RepositoryName, - &parser, - true, - ) -} - -func (h *ClientConfig) DeleteParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { - _, err := h.GetParser(config, req, hp) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - return h.GetHumioClient(config, req).Parsers().Delete(hp.Spec.RepositoryName, hp.Spec.Name) -} - -func (h *ClientConfig) AddRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - repository := humioapi.Repository{Name: hr.Spec.Name} - err := h.GetHumioClient(config, req).Repositories().Create(hr.Spec.Name) - return &repository, err -} - -func (h *ClientConfig) GetRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - repo, err := h.GetHumioClient(config, req).Repositories().Get(hr.Spec.Name) - if err != nil { - return nil, err - } - return &repo, nil -} - -func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - curRepository, err := h.GetRepository(config, req, hr) - if err != nil { - return nil, err - } - - if curRepository.Description != hr.Spec.Description { - err = h.GetHumioClient(config, req).Repositories().UpdateDescription( - hr.Spec.Name, - hr.Spec.Description, - ) - if err != nil { - return nil, err - } - } - - if curRepository.RetentionDays != float64(hr.Spec.Retention.TimeInDays) { - err = h.GetHumioClient(config, req).Repositories().UpdateTimeBasedRetention( - hr.Spec.Name, - float64(hr.Spec.Retention.TimeInDays), - hr.Spec.AllowDataDeletion, - ) - if err != nil { - return nil, err - } - } - - if curRepository.StorageRetentionSizeGB != float64(hr.Spec.Retention.StorageSizeInGB) { - err = h.GetHumioClient(config, req).Repositories().UpdateStorageBasedRetention( - hr.Spec.Name, - float64(hr.Spec.Retention.StorageSizeInGB), - hr.Spec.AllowDataDeletion, - ) - if err != nil { - return nil, err - } - } - - if curRepository.IngestRetentionSizeGB != float64(hr.Spec.Retention.IngestSizeInGB) { - err = h.GetHumioClient(config, req).Repositories().UpdateIngestBasedRetention( - hr.Spec.Name, - float64(hr.Spec.Retention.IngestSizeInGB), - hr.Spec.AllowDataDeletion, - ) - if err != nil { - return nil, err - } - } - - if curRepository.AutomaticSearch != helpers.BoolTrue(hr.Spec.AutomaticSearch) { - err = h.GetHumioClient(config, req).Repositories().UpdateAutomaticSearch( - hr.Spec.Name, - helpers.BoolTrue(hr.Spec.AutomaticSearch), - ) - if err != nil { - return nil, err - } - } - - return h.GetRepository(config, req, hr) -} - -func (h *ClientConfig) DeleteRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { - _, err := h.GetRepository(config, req, hr) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - // TODO: perhaps we should allow calls to DeleteRepository() to include the reason instead of hardcoding it - return h.GetHumioClient(config, req).Repositories().Delete( - hr.Spec.Name, - "deleted by humio-operator", - hr.Spec.AllowDataDeletion, - ) -} - -func (h *ClientConfig) GetView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - return h.GetHumioClient(config, req).Views().Get(hv.Spec.Name) -} - -func (h *ClientConfig) AddView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - viewConnections := hv.GetViewConnections() - - view := humioapi.View{ - Name: hv.Spec.Name, - Connections: viewConnections, - } - - description := "" - - err := h.GetHumioClient(config, req).Views().Create(hv.Spec.Name, description, getConnectionMap(viewConnections)) - return &view, err -} - -func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - curView, err := h.GetView(config, req, hv) - if err != nil { - return nil, err - } - - if curView.Description != hv.Spec.Description { - err = h.GetHumioClient(config, req).Views().UpdateDescription( - hv.Spec.Name, - hv.Spec.Description, - ) - if err != nil { - return nil, err - } - } - - if curView.AutomaticSearch != helpers.BoolTrue(hv.Spec.AutomaticSearch) { - err = h.GetHumioClient(config, req).Views().UpdateAutomaticSearch( - hv.Spec.Name, - helpers.BoolTrue(hv.Spec.AutomaticSearch), - ) - if err != nil { - return nil, err - } - } - - connections := hv.GetViewConnections() - if reflect.DeepEqual(curView.Connections, connections) { - return h.GetView(config, req, hv) - } - - err = h.GetHumioClient(config, req).Views().UpdateConnections( - hv.Spec.Name, - getConnectionMap(connections), - ) - if err != nil { - return nil, err - } - - return h.GetView(config, req, hv) -} - -func (h *ClientConfig) DeleteView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) error { - _, err := h.GetView(config, req, hv) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - return h.GetHumioClient(config, req).Views().Delete(hv.Spec.Name, "Deleted by humio-operator") -} - -func (h *ClientConfig) validateSearchDomain(config *humioapi.Config, req reconcile.Request, searchDomainName string) error { - _, err := h.GetHumioClient(config, req).SearchDomains().Get(searchDomainName) - return err -} - -func (h *ClientConfig) GetAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - err := h.validateSearchDomain(config, req, ha.Spec.ViewName) - if err != nil { - return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) - } - - return h.GetHumioClient(config, req).Actions().Get(ha.Spec.ViewName, ha.Spec.Name) -} - -func (h *ClientConfig) AddAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - err := h.validateSearchDomain(config, req, ha.Spec.ViewName) - if err != nil { - return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) - } - - action, err := ActionFromActionCR(ha) - if err != nil { - return action, err - } - - createdAction, err := h.GetHumioClient(config, req).Actions().Add(ha.Spec.ViewName, action) - if err != nil { - return createdAction, fmt.Errorf("got error when attempting to add action: %w", err) - } - return createdAction, nil -} - -func (h *ClientConfig) UpdateAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - err := h.validateSearchDomain(config, req, ha.Spec.ViewName) - if err != nil { - return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) - } - - action, err := ActionFromActionCR(ha) - if err != nil { - return action, err - } - - currentAction, err := h.GetAction(config, req, ha) - if err != nil { - return nil, fmt.Errorf("could not find action with name: %q", ha.Spec.Name) - } - action.ID = currentAction.ID - - return h.GetHumioClient(config, req).Actions().Update(ha.Spec.ViewName, action) -} - -func (h *ClientConfig) DeleteAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) error { - _, err := h.GetAction(config, req, ha) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - return h.GetHumioClient(config, req).Actions().Delete(ha.Spec.ViewName, ha.Spec.Name) -} - -func getConnectionMap(viewConnections []humioapi.ViewConnection) []humioapi.ViewConnectionInput { - connectionMap := make([]humioapi.ViewConnectionInput, 0) - for _, connection := range viewConnections { - connectionMap = append(connectionMap, humioapi.ViewConnectionInput{ - RepositoryName: graphql.String(connection.RepoName), - Filter: graphql.String(connection.Filter), - }) - } - return connectionMap -} - -func (h *ClientConfig) GetLicense(config *humioapi.Config, req reconcile.Request) (humioapi.License, error) { - return h.GetHumioClient(config, req).Licenses().Get() -} - -func (h *ClientConfig) InstallLicense(config *humioapi.Config, req reconcile.Request, license string) error { - return h.GetHumioClient(config, req).Licenses().Install(license) -} - -func (h *ClientConfig) GetAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - err := h.validateSearchDomain(config, req, ha.Spec.ViewName) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("problem getting view for alert %s: %w", ha.Spec.Name, err) - } - - return h.GetHumioClient(config, req).Alerts().Get(ha.Spec.ViewName, ha.Spec.Name) -} - -func (h *ClientConfig) AddAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - err := h.validateSearchDomain(config, req, ha.Spec.ViewName) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("problem getting view for alert: %w", err) - } - - actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("could not get action id mapping: %w", err) - } - - alert := AlertTransform(ha, actionIdMap) - createdAlert, err := h.GetHumioClient(config, req).Alerts().Add(ha.Spec.ViewName, alert) - if err != nil { - return createdAlert, fmt.Errorf("got error when attempting to add alert: %w, alert: %#v", err, *alert) - } - return createdAlert, nil -} - -func (h *ClientConfig) UpdateAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - err := h.validateSearchDomain(config, req, ha.Spec.ViewName) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("problem getting view for action: %w", err) - } - - actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("could not get action id mapping: %w", err) - } - - alert := AlertTransform(ha, actionIdMap) - currentAlert, err := h.GetAlert(config, req, ha) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("could not find alert with name: %q", alert.Name) - } - alert.ID = currentAlert.ID - - return h.GetHumioClient(config, req).Alerts().Update(ha.Spec.ViewName, alert) -} - -func (h *ClientConfig) DeleteAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) error { - _, err := h.GetAlert(config, req, ha) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - return h.GetHumioClient(config, req).Alerts().Delete(ha.Spec.ViewName, ha.Spec.Name) -} - -func (h *ClientConfig) GetFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - err := h.validateSearchDomain(config, req, hfa.Spec.ViewName) - if err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("problem getting view for filter alert %s: %w", hfa.Spec.Name, err) - } - - var filterAlertId string - filterAlertsList, err := h.GetHumioClient(config, req).FilterAlerts().List(hfa.Spec.ViewName) - if err != nil { - return nil, fmt.Errorf("unable to list filter alerts: %w", err) - } - for _, filterAlert := range filterAlertsList { - if filterAlert.Name == hfa.Spec.Name { - filterAlertId = filterAlert.ID - } - } - if filterAlertId == "" { - return nil, humioapi.FilterAlertNotFound(hfa.Spec.Name) - } - filterAlert, err := h.GetHumioClient(config, req).FilterAlerts().Get(hfa.Spec.ViewName, filterAlertId) - if err != nil { - return filterAlert, fmt.Errorf("error when trying to get filter alert %+v, name=%s, view=%s: %w", filterAlert, hfa.Spec.Name, hfa.Spec.ViewName, err) - } - - if filterAlert == nil || filterAlert.Name == "" { - return nil, nil - } - - return filterAlert, nil -} - -func (h *ClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - err := h.validateSearchDomain(config, req, hfa.Spec.ViewName) - if err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("problem getting view for filter alert: %w", err) - } - if err = h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("could not get action id mapping: %w", err) - } - - filterAlert := FilterAlertTransform(hfa) - createdAlert, err := h.GetHumioClient(config, req).FilterAlerts().Create(hfa.Spec.ViewName, filterAlert) - if err != nil { - return createdAlert, fmt.Errorf("got error when attempting to add filter alert: %w, filteralert: %#v", err, *filterAlert) - } - return createdAlert, nil -} - -func (h *ClientConfig) UpdateFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - err := h.validateSearchDomain(config, req, hfa.Spec.ViewName) - if err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("problem getting view for action: %w", err) - } - if err = h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("could not get action id mapping: %w", err) - } - - filterAlert := FilterAlertTransform(hfa) - currentAlert, err := h.GetFilterAlert(config, req, hfa) - if err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("could not find filter alert with name: %q", filterAlert.Name) - } - filterAlert.ID = currentAlert.ID - - return h.GetHumioClient(config, req).FilterAlerts().Update(hfa.Spec.ViewName, filterAlert) -} - -func (h *ClientConfig) DeleteFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { - currentAlert, err := h.GetFilterAlert(config, req, hfa) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - if err != nil { - return fmt.Errorf("could not find filter alert with name: %q", hfa.Name) - } - return h.GetHumioClient(config, req).FilterAlerts().Delete(hfa.Spec.ViewName, currentAlert.ID) -} - -func (h *ClientConfig) AddScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - err := h.validateSearchDomain(config, req, hss.Spec.ViewName) - if err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("problem getting view for scheduled search: %w", err) - } - if err = h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("could not get action id mapping: %w", err) - } - scheduledSearch := ScheduledSearchTransform(hss) - - createdScheduledSearch, err := h.GetHumioClient(config, req).ScheduledSearches().Create(hss.Spec.ViewName, scheduledSearch) - if err != nil { - return createdScheduledSearch, fmt.Errorf("got error when attempting to add scheduled search: %w, scheduledsearch: %#v", err, *scheduledSearch) - } - return createdScheduledSearch, nil -} - -func (h *ClientConfig) GetScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - err := h.validateSearchDomain(config, req, hss.Spec.ViewName) - if err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("problem getting view for scheduled search %s: %w", hss.Spec.Name, err) - } - - var scheduledSearchId string - scheduledSearchList, err := h.GetHumioClient(config, req).ScheduledSearches().List(hss.Spec.ViewName) - if err != nil { - return nil, fmt.Errorf("unable to list scheduled searches: %w", err) - } - for _, scheduledSearch := range scheduledSearchList { - if scheduledSearch.Name == hss.Spec.Name { - scheduledSearchId = scheduledSearch.ID - } - } - if scheduledSearchId == "" { - return nil, humioapi.ScheduledSearchNotFound(hss.Spec.Name) - } - scheduledSearch, err := h.GetHumioClient(config, req).ScheduledSearches().Get(hss.Spec.ViewName, scheduledSearchId) - if err != nil { - return scheduledSearch, fmt.Errorf("error when trying to get scheduled search %+v, name=%s, view=%s: %w", scheduledSearch, hss.Spec.Name, hss.Spec.ViewName, err) - } - - if scheduledSearch == nil || scheduledSearch.Name == "" { - return nil, nil - } - - return scheduledSearch, nil -} - -func (h *ClientConfig) UpdateScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - err := h.validateSearchDomain(config, req, hss.Spec.ViewName) - if err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("problem getting view for scheduled search: %w", err) - } - if err = h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("could not get action id mapping: %w", err) - } - scheduledSearch := ScheduledSearchTransform(hss) - - currentScheduledSearch, err := h.GetScheduledSearch(config, req, hss) - if err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("could not find scheduled search with name: %q", scheduledSearch.Name) - } - scheduledSearch.ID = currentScheduledSearch.ID - - return h.GetHumioClient(config, req).ScheduledSearches().Update(hss.Spec.ViewName, scheduledSearch) -} - -func (h *ClientConfig) DeleteScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { - currentScheduledSearch, err := h.GetScheduledSearch(config, req, hss) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - if err != nil { - return fmt.Errorf("could not find scheduled search with name: %q", hss.Name) - } - return h.GetHumioClient(config, req).ScheduledSearches().Delete(hss.Spec.ViewName, currentScheduledSearch.ID) -} - -func (h *ClientConfig) getAndValidateAction(config *humioapi.Config, req reconcile.Request, actionName string, viewName string) (*humioapi.Action, error) { - action := &humiov1alpha1.HumioAction{ - Spec: humiov1alpha1.HumioActionSpec{ - Name: actionName, - ViewName: viewName, - }, - } - - return h.GetAction(config, req, action) -} - -func (h *ClientConfig) GetActionIDsMapForAlerts(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (map[string]string, error) { - actionIdMap := make(map[string]string) - for _, actionNameForAlert := range ha.Spec.Actions { - action, err := h.getAndValidateAction(config, req, actionNameForAlert, ha.Spec.ViewName) - if err != nil { - return actionIdMap, fmt.Errorf("problem getting action for alert %s: %w", ha.Spec.Name, err) - } - actionIdMap[actionNameForAlert] = action.ID - - } - return actionIdMap, nil -} - -func (h *ClientConfig) ValidateActionsForFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { - for _, actionNameForAlert := range hfa.Spec.Actions { - if _, err := h.getAndValidateAction(config, req, actionNameForAlert, hfa.Spec.ViewName); err != nil { - return fmt.Errorf("problem getting action for filter alert %s: %w", hfa.Spec.Name, err) - } - } - return nil -} - -func (h *ClientConfig) ValidateActionsForScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { - for _, actionNameForScheduledSearch := range hss.Spec.Actions { - if _, err := h.getAndValidateAction(config, req, actionNameForScheduledSearch, hss.Spec.ViewName); err != nil { - return fmt.Errorf("problem getting action for scheduled search %s: %w", hss.Spec.Name, err) - } - } - return nil -} - -func (h *ClientConfig) AddAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - err := h.validateSearchDomain(config, req, haa.Spec.ViewName) - if err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("problem getting view for action: %w", err) - } - if err = h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("could not get action id mapping: %w", err) - } - - aggregateAlert := AggregateAlertTransform(haa) - createdAggregateAlert, err := h.GetHumioClient(config, req).AggregateAlerts().Create(haa.Spec.ViewName, aggregateAlert) - if err != nil { - return createdAggregateAlert, fmt.Errorf("got error when attempting to add aggregate alert: %w, aggregatealert: %#v", err, *aggregateAlert) - } - return createdAggregateAlert, nil -} - -func (h *ClientConfig) GetAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - err := h.validateSearchDomain(config, req, haa.Spec.ViewName) - if err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("problem getting view for action %s: %w", haa.Spec.Name, err) - } - - var aggregateAlertId string - aggregateAlertsList, err := h.GetHumioClient(config, req).AggregateAlerts().List(haa.Spec.ViewName) - if err != nil { - return nil, fmt.Errorf("unable to list aggregate alerts: %w", err) - } - for _, aggregateAlert := range aggregateAlertsList { - if aggregateAlert.Name == haa.Spec.Name { - aggregateAlertId = aggregateAlert.ID - } - } - if aggregateAlertId == "" { - return nil, humioapi.AggregateAlertNotFound(haa.Spec.Name) - } - aggregateAlert, err := h.GetHumioClient(config, req).AggregateAlerts().Get(haa.Spec.ViewName, aggregateAlertId) - if err != nil { - return aggregateAlert, fmt.Errorf("error when trying to get aggregate alert %+v, name=%s, view=%s: %w", aggregateAlert, haa.Spec.Name, haa.Spec.ViewName, err) - } - - if aggregateAlert == nil || aggregateAlert.Name == "" { - return nil, nil - } - - return aggregateAlert, nil -} - -func (h *ClientConfig) UpdateAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - err := h.validateSearchDomain(config, req, haa.Spec.ViewName) - if err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("problem getting view for action %s: %w", haa.Spec.Name, err) - } - if err = h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("could not get action id mapping: %w", err) - } - aggregateAlert := AggregateAlertTransform(haa) - currentAggregateAlert, err := h.GetAggregateAlert(config, req, haa) - if err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("could not find aggregate alert with namer: %q", aggregateAlert.Name) - } - aggregateAlert.ID = currentAggregateAlert.ID - - return h.GetHumioClient(config, req).AggregateAlerts().Update(haa.Spec.ViewName, aggregateAlert) -} - -func (h *ClientConfig) DeleteAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { - currentAggregateAlert, err := h.GetAggregateAlert(config, req, haa) - if errors.As(err, &humioapi.EntityNotFound{}) { - return nil - } - if err != nil { - return fmt.Errorf("could not find aggregate alert with name: %q", haa.Name) - } - return h.GetHumioClient(config, req).AggregateAlerts().Delete(haa.Spec.ViewName, currentAggregateAlert.ID) -} - -func (h *ClientConfig) ValidateActionsForAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { - // validate action - for _, actionNameForAlert := range haa.Spec.Actions { - if _, err := h.getAndValidateAction(config, req, actionNameForAlert, haa.Spec.ViewName); err != nil { - return fmt.Errorf("problem getting action for aggregate alert %s: %w", haa.Spec.Name, err) - } - } - return nil -} - -type user struct { - Id string - Username string -} - -type OrganizationSearchResultEntry struct { - EntityId string `graphql:"entityId"` - SearchMatch string `graphql:"searchMatch"` - OrganizationName string `graphql:"organizationName"` -} - -func (h *ClientConfig) ListAllHumioUsersInCurrentOrganization(config *humioapi.Config, req reconcile.Request) ([]user, error) { - var q struct { - Users []user `graphql:"users"` - } - err := h.GetHumioClient(config, req).Query(&q, nil) - return q.Users, err -} - -func (h *ClientConfig) RotateUserApiTokenAndGet(config *humioapi.Config, req reconcile.Request, userID string) (string, error) { - token, err := h.GetHumioClient(config, req).Users().RotateToken(userID) - if err != nil { - return "", fmt.Errorf("could not rotate apiToken for userID %s, err: %w", userID, err) - } - return token, nil -} - -func (h *ClientConfig) AddUser(config *humioapi.Config, req reconcile.Request, username string, isRoot bool) (*humioapi.User, error) { - user, err := h.GetHumioClient(config, req).Users().Add(username, humioapi.UserChangeSet{ - IsRoot: &isRoot, - }) - if err != nil { - return &humioapi.User{}, err - } - return &user, nil -} diff --git a/pkg/humio/client_mock.go b/pkg/humio/client_mock.go deleted file mode 100644 index c1720528..00000000 --- a/pkg/humio/client_mock.go +++ /dev/null @@ -1,1024 +0,0 @@ -/* -Copyright 2020 Humio https://humio.com - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package humio - -import ( - "crypto/sha512" - "encoding/hex" - "fmt" - "net/url" - "sync" - - "github.com/humio/humio-operator/pkg/helpers" - - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/kubernetes" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var ( - humioClientMu sync.Mutex -) - -type resourceKey struct { - // clusterName holds the value of the cluster - clusterName string - // searchDomainName is the name of the repository or view - searchDomainName string - // resourceName is the name of resource, like IngestToken, Parser, etc. - resourceName string -} - -type ClientMock struct { - OnPremLicense map[resourceKey]humioapi.OnPremLicense - Repository map[resourceKey]humioapi.Repository - View map[resourceKey]humioapi.View - IngestToken map[resourceKey]humioapi.IngestToken - Parser map[resourceKey]humioapi.Parser - Action map[resourceKey]humioapi.Action - Alert map[resourceKey]humioapi.Alert - FilterAlert map[resourceKey]humioapi.FilterAlert - AggregateAlert map[resourceKey]humioapi.AggregateAlert - ScheduledSearch map[resourceKey]humioapi.ScheduledSearch - User map[resourceKey]humioapi.User -} - -type MockClientConfig struct { - apiClient *ClientMock -} - -func NewMockClient() *MockClientConfig { - mockClientConfig := &MockClientConfig{ - apiClient: &ClientMock{ - OnPremLicense: make(map[resourceKey]humioapi.OnPremLicense), - Repository: make(map[resourceKey]humioapi.Repository), - View: make(map[resourceKey]humioapi.View), - IngestToken: make(map[resourceKey]humioapi.IngestToken), - Parser: make(map[resourceKey]humioapi.Parser), - Action: make(map[resourceKey]humioapi.Action), - Alert: make(map[resourceKey]humioapi.Alert), - FilterAlert: make(map[resourceKey]humioapi.FilterAlert), - AggregateAlert: make(map[resourceKey]humioapi.AggregateAlert), - ScheduledSearch: make(map[resourceKey]humioapi.ScheduledSearch), - User: make(map[resourceKey]humioapi.User), - }, - } - - return mockClientConfig -} - -func (h *MockClientConfig) Status(config *humioapi.Config, req reconcile.Request) (*humioapi.StatusResponse, error) { - return &humioapi.StatusResponse{ - Status: "OK", - Version: "x.y.z", - }, nil -} - -func (h *MockClientConfig) GetClusters(config *humioapi.Config, req reconcile.Request) (humioapi.Cluster, error) { - return humioapi.Cluster{}, nil -} - -func (h *MockClientConfig) TestAPIToken(config *humioapi.Config, req reconcile.Request) error { - return nil -} - -func (h *MockClientConfig) AddIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName) - if !h.searchDomainNameExists(clusterName, hit.Spec.RepositoryName) { - return nil, fmt.Errorf("search domain name does not exist") - } - - key := resourceKey{ - clusterName: clusterName, - searchDomainName: hit.Spec.RepositoryName, - resourceName: hit.Spec.Name, - } - - if _, found := h.apiClient.IngestToken[key]; found { - return nil, fmt.Errorf("ingest token already exists with name %s", hit.Spec.Name) - } - - value := IngestTokenTransform(hit) - if value.Token == "" { - value.Token = kubernetes.RandomString() - } - h.apiClient.IngestToken[key] = *value - return value, nil -} - -func (h *MockClientConfig) GetIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), - searchDomainName: hit.Spec.RepositoryName, - resourceName: hit.Spec.Name, - } - if value, found := h.apiClient.IngestToken[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find ingest token in repository %s with name %s, err=%w", hit.Spec.RepositoryName, hit.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) UpdateIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), - searchDomainName: hit.Spec.RepositoryName, - resourceName: hit.Spec.Name, - } - - if _, found := h.apiClient.IngestToken[key]; !found { - return nil, fmt.Errorf("ingest token not found with name %s, err=%w", hit.Spec.Name, humioapi.EntityNotFound{}) - } - - value := IngestTokenTransform(hit) - if value.Token == "" { - value.Token = h.apiClient.IngestToken[key].Token - } - h.apiClient.IngestToken[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), - searchDomainName: hit.Spec.RepositoryName, - resourceName: hit.Spec.Name, - } - - delete(h.apiClient.IngestToken, key) - return nil -} - -func (h *MockClientConfig) AddParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName) - if !h.searchDomainNameExists(clusterName, hp.Spec.RepositoryName) { - return nil, fmt.Errorf("search domain name does not exist") - } - - key := resourceKey{ - clusterName: clusterName, - searchDomainName: hp.Spec.RepositoryName, - resourceName: hp.Spec.Name, - } - - if _, found := h.apiClient.Parser[key]; found { - return nil, fmt.Errorf("parser already exists with name %s", hp.Spec.Name) - } - - value := ParserTransform(hp) - if value.ID == "" { - value.ID = kubernetes.RandomString() - } - h.apiClient.Parser[key] = *value - return value, nil -} - -func (h *MockClientConfig) GetParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), - searchDomainName: hp.Spec.RepositoryName, - resourceName: hp.Spec.Name, - } - if value, found := h.apiClient.Parser[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find parser in repository %s with name %s, err=%w", hp.Spec.RepositoryName, hp.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) UpdateParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), - searchDomainName: hp.Spec.RepositoryName, - resourceName: hp.Spec.Name, - } - - if _, found := h.apiClient.Parser[key]; !found { - return nil, fmt.Errorf("parser not found with name %s, err=%w", hp.Spec.Name, humioapi.EntityNotFound{}) - } - - value := ParserTransform(hp) - - h.apiClient.Parser[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), - searchDomainName: hp.Spec.RepositoryName, - resourceName: hp.Spec.Name, - } - - delete(h.apiClient.Parser, key) - return nil -} - -func (h *MockClientConfig) AddRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName) - if h.searchDomainNameExists(clusterName, hr.Spec.Name) { - return nil, fmt.Errorf("search domain name already in use") - } - - key := resourceKey{ - clusterName: clusterName, - resourceName: hr.Spec.Name, - } - - if _, found := h.apiClient.Repository[key]; found { - return nil, fmt.Errorf("repository already exists with name %s", hr.Spec.Name) - } - - value := &humioapi.Repository{ - ID: kubernetes.RandomString(), - Name: hr.Spec.Name, - Description: hr.Spec.Description, - RetentionDays: float64(hr.Spec.Retention.TimeInDays), - IngestRetentionSizeGB: float64(hr.Spec.Retention.IngestSizeInGB), - StorageRetentionSizeGB: float64(hr.Spec.Retention.StorageSizeInGB), - AutomaticSearch: helpers.BoolTrue(hr.Spec.AutomaticSearch), - } - - h.apiClient.Repository[key] = *value - return value, nil -} - -func (h *MockClientConfig) GetRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), - resourceName: hr.Spec.Name, - } - if value, found := h.apiClient.Repository[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find repository with name %s, err=%w", hr.Spec.Name, humioapi.EntityNotFound{}) - -} - -func (h *MockClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), - resourceName: hr.Spec.Name, - } - - if _, found := h.apiClient.Repository[key]; !found { - return nil, fmt.Errorf("repository not found with name %s, err=%w", hr.Spec.Name, humioapi.EntityNotFound{}) - } - - value := &humioapi.Repository{ - ID: kubernetes.RandomString(), - Name: hr.Spec.Name, - Description: hr.Spec.Description, - RetentionDays: float64(hr.Spec.Retention.TimeInDays), - IngestRetentionSizeGB: float64(hr.Spec.Retention.IngestSizeInGB), - StorageRetentionSizeGB: float64(hr.Spec.Retention.StorageSizeInGB), - AutomaticSearch: helpers.BoolTrue(hr.Spec.AutomaticSearch), - } - - h.apiClient.Repository[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - // TODO: consider finding all entities referring to this searchDomainName and remove them as well - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), - resourceName: hr.Spec.Name, - } - - delete(h.apiClient.Repository, key) - return nil -} - -func (h *MockClientConfig) GetView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), - resourceName: hv.Spec.Name, - } - if value, found := h.apiClient.View[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find view with name %s, err=%w", hv.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) AddView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName) - if h.searchDomainNameExists(clusterName, hv.Spec.Name) { - return nil, fmt.Errorf("search domain name already in use") - } - - key := resourceKey{ - clusterName: clusterName, - resourceName: hv.Spec.Name, - } - - if _, found := h.apiClient.Repository[key]; found { - return nil, fmt.Errorf("view already exists with name %s", hv.Spec.Name) - } - - connections := make([]humioapi.ViewConnection, 0) - for _, connection := range hv.Spec.Connections { - connections = append(connections, humioapi.ViewConnection{ - RepoName: connection.RepositoryName, - Filter: connection.Filter, - }) - } - - value := &humioapi.View{ - Name: hv.Spec.Name, - Description: hv.Spec.Description, - Connections: connections, - AutomaticSearch: helpers.BoolTrue(hv.Spec.AutomaticSearch), - } - h.apiClient.View[key] = *value - return value, nil -} - -func (h *MockClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), - resourceName: hv.Spec.Name, - } - - if _, found := h.apiClient.View[key]; !found { - return nil, fmt.Errorf("view not found with name %s, err=%w", hv.Spec.Name, humioapi.EntityNotFound{}) - } - - connections := make([]humioapi.ViewConnection, 0) - for _, connection := range hv.Spec.Connections { - connections = append(connections, humioapi.ViewConnection{ - RepoName: connection.RepositoryName, - Filter: connection.Filter, - }) - } - - value := &humioapi.View{ - Name: hv.Spec.Name, - Description: hv.Spec.Description, - Connections: connections, - AutomaticSearch: helpers.BoolTrue(hv.Spec.AutomaticSearch), - } - h.apiClient.View[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - // TODO: consider finding all entities referring to this searchDomainName and remove them as well - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), - resourceName: hv.Spec.Name, - } - - delete(h.apiClient.View, key) - return nil -} - -func (h *MockClientConfig) GetLicense(config *humioapi.Config, req reconcile.Request) (humioapi.License, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), - } - - if value, found := h.apiClient.OnPremLicense[key]; found { - return &value, nil - - } - - return humioapi.OnPremLicense{}, nil -} - -func (h *MockClientConfig) InstallLicense(config *humioapi.Config, req reconcile.Request, licenseString string) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), - } - - onPremLicense, err := ParseLicenseType(licenseString) - if err != nil { - return fmt.Errorf("failed to parse license type: %w", err) - } - - h.apiClient.OnPremLicense[key] = *onPremLicense - return nil -} - -func (h *MockClientConfig) GetAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - if value, found := h.apiClient.Action[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) AddAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName) - if !h.searchDomainNameExists(clusterName, ha.Spec.ViewName) { - return nil, fmt.Errorf("search domain name does not exist") - } - - key := resourceKey{ - clusterName: clusterName, - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - - if _, found := h.apiClient.Action[key]; found { - return nil, fmt.Errorf("action already exists with name %s", ha.Spec.Name) - } - - action, err := ActionFromActionCR(ha) - if err != nil { - return nil, err - } - action.ID = kubernetes.RandomString() - - h.apiClient.Action[key] = *action - return action, nil -} - -func (h *MockClientConfig) UpdateAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - - currentAction, found := h.apiClient.Action[key] - - if !found { - return nil, fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) - } - - action, err := ActionFromActionCR(ha) - if err != nil { - return nil, err - } - action.ID = currentAction.ID - - h.apiClient.Action[key] = *action - return action, nil -} - -func (h *MockClientConfig) DeleteAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - - delete(h.apiClient.Action, key) - return nil -} - -func (h *MockClientConfig) GetAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - if value, found := h.apiClient.Alert[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) AddAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName) - if !h.searchDomainNameExists(clusterName, ha.Spec.ViewName) { - return nil, fmt.Errorf("search domain name does not exist") - } - - key := resourceKey{ - clusterName: clusterName, - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - - if _, found := h.apiClient.Alert[key]; found { - return nil, fmt.Errorf("alert already exists with name %s", ha.Spec.Name) - } - actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) - if err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := AlertTransform(ha, actionIdMap) - value.ID = kubernetes.RandomString() - - h.apiClient.Alert[key] = *value - return value, nil -} - -func (h *MockClientConfig) UpdateAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - - currentAlert, found := h.apiClient.Alert[key] - - if !found { - return nil, fmt.Errorf("alert not found with name %s, err=%w", ha.Spec.Name, humioapi.EntityNotFound{}) - } - actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) - if err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := AlertTransform(ha, actionIdMap) - value.ID = currentAlert.ID - - h.apiClient.Alert[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), - searchDomainName: ha.Spec.ViewName, - resourceName: ha.Spec.Name, - } - - delete(h.apiClient.Alert, key) - return nil -} - -func (h *MockClientConfig) GetActionIDsMapForAlerts(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (map[string]string, error) { - actionIdMap := make(map[string]string) - for _, action := range ha.Spec.Actions { - hash := sha512.Sum512([]byte(action)) - actionIdMap[action] = hex.EncodeToString(hash[:]) - } - return actionIdMap, nil -} - -func (h *MockClientConfig) GetFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), - searchDomainName: hfa.Spec.ViewName, - resourceName: hfa.Spec.Name, - } - if value, found := h.apiClient.FilterAlert[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName) - if !h.searchDomainNameExists(clusterName, hfa.Spec.ViewName) { - return nil, fmt.Errorf("search domain name does not exist") - } - - key := resourceKey{ - clusterName: clusterName, - searchDomainName: hfa.Spec.ViewName, - resourceName: hfa.Spec.Name, - } - - if _, found := h.apiClient.FilterAlert[key]; found { - return nil, fmt.Errorf("filter alert already exists with name %s", hfa.Spec.Name) - } - if err := h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := FilterAlertTransform(hfa) - value.ID = kubernetes.RandomString() - - h.apiClient.FilterAlert[key] = *value - return value, nil -} - -func (h *MockClientConfig) UpdateFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), - searchDomainName: hfa.Spec.ViewName, - resourceName: hfa.Spec.Name, - } - - currentFilterAlert, found := h.apiClient.FilterAlert[key] - - if !found { - return nil, fmt.Errorf("could not find filter alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) - } - if err := h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := FilterAlertTransform(hfa) - value.ID = currentFilterAlert.ID - - h.apiClient.FilterAlert[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), - searchDomainName: hfa.Spec.ViewName, - resourceName: hfa.Spec.Name, - } - - delete(h.apiClient.FilterAlert, key) - return nil -} - -func (h *MockClientConfig) ValidateActionsForFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { - return nil -} - -func (h *MockClientConfig) GetAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), - searchDomainName: haa.Spec.ViewName, - resourceName: haa.Spec.Name, - } - if value, found := h.apiClient.AggregateAlert[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) AddAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), - searchDomainName: haa.Spec.ViewName, - resourceName: haa.Spec.Name, - } - - if _, found := h.apiClient.AggregateAlert[key]; found { - return nil, fmt.Errorf("aggregate alert already exists with name %s", haa.Spec.Name) - } - if err := h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := AggregateAlertTransform(haa) - value.ID = kubernetes.RandomString() - - h.apiClient.AggregateAlert[key] = *value - return value, nil -} - -func (h *MockClientConfig) UpdateAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), - searchDomainName: haa.Spec.ViewName, - resourceName: haa.Spec.Name, - } - - currentAggregateAlert, found := h.apiClient.AggregateAlert[key] - - if !found { - return nil, fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) - } - if err := h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := AggregateAlertTransform(haa) - value.ID = currentAggregateAlert.ID - - h.apiClient.AggregateAlert[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), - searchDomainName: haa.Spec.ViewName, - resourceName: haa.Spec.Name, - } - - delete(h.apiClient.AggregateAlert, key) - return nil -} - -func (h *MockClientConfig) ValidateActionsForAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { - return nil -} - -func (h *MockClientConfig) AddScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - clusterName := fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName) - if !h.searchDomainNameExists(clusterName, hss.Spec.ViewName) { - return nil, fmt.Errorf("search domain name does not exist") - } - - key := resourceKey{ - clusterName: clusterName, - searchDomainName: hss.Spec.ViewName, - resourceName: hss.Spec.Name, - } - - if _, found := h.apiClient.ScheduledSearch[key]; found { - return nil, fmt.Errorf("scheduled search already exists with name %s", hss.Spec.Name) - } - if err := h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := ScheduledSearchTransform(hss) - value.ID = kubernetes.RandomString() - - h.apiClient.ScheduledSearch[key] = *value - return value, nil -} - -func (h *MockClientConfig) GetScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), - searchDomainName: hss.Spec.ViewName, - resourceName: hss.Spec.Name, - } - if value, found := h.apiClient.ScheduledSearch[key]; found { - return &value, nil - - } - return nil, fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) -} - -func (h *MockClientConfig) UpdateScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), - searchDomainName: hss.Spec.ViewName, - resourceName: hss.Spec.Name, - } - - currentScheduledSearch, found := h.apiClient.ScheduledSearch[key] - - if !found { - return nil, fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) - } - if err := h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { - return nil, fmt.Errorf("could not get action id mapping: %w", err) - } - - value := ScheduledSearchTransform(hss) - value.ID = currentScheduledSearch.ID - - h.apiClient.ScheduledSearch[key] = *value - return value, nil -} - -func (h *MockClientConfig) DeleteScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), - searchDomainName: hss.Spec.ViewName, - resourceName: hss.Spec.Name, - } - - delete(h.apiClient.ScheduledSearch, key) - return nil -} - -func (h *MockClientConfig) ValidateActionsForScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { - return nil -} - -func (h *MockClientConfig) GetHumioClient(config *humioapi.Config, req ctrl.Request) *humioapi.Client { - clusterURL, _ := url.Parse("http://localhost:8080/") - return humioapi.NewClient(humioapi.Config{Address: clusterURL}) -} - -func (h *MockClientConfig) ClearHumioClientConnections(repoNameToKeep string) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - for k := range h.apiClient.Repository { - if k.resourceName != repoNameToKeep { - delete(h.apiClient.Repository, k) - } - } - h.apiClient.View = make(map[resourceKey]humioapi.View) - h.apiClient.IngestToken = make(map[resourceKey]humioapi.IngestToken) - h.apiClient.Parser = make(map[resourceKey]humioapi.Parser) - h.apiClient.Action = make(map[resourceKey]humioapi.Action) - h.apiClient.Alert = make(map[resourceKey]humioapi.Alert) - h.apiClient.FilterAlert = make(map[resourceKey]humioapi.FilterAlert) - h.apiClient.AggregateAlert = make(map[resourceKey]humioapi.AggregateAlert) - h.apiClient.ScheduledSearch = make(map[resourceKey]humioapi.ScheduledSearch) - h.apiClient.User = make(map[resourceKey]humioapi.User) -} - -// searchDomainNameExists returns a boolean if either a repository or view exists with the given search domain name. -// It assumes the caller already holds the lock humioClientMu. -func (h *MockClientConfig) searchDomainNameExists(clusterName, searchDomainName string) bool { - key := resourceKey{ - clusterName: clusterName, - resourceName: searchDomainName, - } - - if _, found := h.apiClient.Repository[key]; found { - return true - } - - if _, found := h.apiClient.View[key]; found { - return true - } - - return false -} - -func (h *MockClientConfig) ListAllHumioUsersInCurrentOrganization(config *humioapi.Config, req reconcile.Request) ([]user, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), - } - - currentUser, found := h.apiClient.User[key] - if !found { - return []user{}, nil - } - - return []user{ - { - Id: currentUser.ID, - Username: currentUser.Username, - }, - }, nil -} - -func (h *MockClientConfig) RotateUserApiTokenAndGet(config *humioapi.Config, req reconcile.Request, username string) (string, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), - } - - currentUser, found := h.apiClient.User[key] - if !found { - return "", fmt.Errorf("could not find user") - } - - userWithNewToken := humioapi.User{ - ID: currentUser.ID, - Username: username, - IsRoot: currentUser.IsRoot, - } - h.apiClient.User[key] = userWithNewToken - - return userWithNewToken.ID, nil -} - -func (h *MockClientConfig) AddUser(config *humioapi.Config, req reconcile.Request, username string, isRoot bool) (*humioapi.User, error) { - humioClientMu.Lock() - defer humioClientMu.Unlock() - - key := resourceKey{ - resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), - } - - newUser := humioapi.User{ - ID: kubernetes.RandomString(), - Username: username, - IsRoot: isRoot, - } - h.apiClient.User[key] = newUser - - return &newUser, nil -} diff --git a/pkg/humio/filteralert_transform.go b/pkg/humio/filteralert_transform.go deleted file mode 100644 index 00c90dfa..00000000 --- a/pkg/humio/filteralert_transform.go +++ /dev/null @@ -1,39 +0,0 @@ -package humio - -import ( - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" -) - -func FilterAlertTransform(hfa *humiov1alpha1.HumioFilterAlert) *humioapi.FilterAlert { - filterAlert := &humioapi.FilterAlert{ - Name: hfa.Spec.Name, - QueryString: hfa.Spec.QueryString, - Description: hfa.Spec.Description, - ThrottleTimeSeconds: hfa.Spec.ThrottleTimeSeconds, - ThrottleField: hfa.Spec.ThrottleField, - Enabled: hfa.Spec.Enabled, - ActionNames: hfa.Spec.Actions, - Labels: hfa.Spec.Labels, - QueryOwnershipType: humioapi.QueryOwnershipTypeOrganization, - } - - if filterAlert.Labels == nil { - filterAlert.Labels = []string{} - } - - return filterAlert -} - -func FilterAlertHydrate(hfa *humiov1alpha1.HumioFilterAlert, alert *humioapi.FilterAlert) { - hfa.Spec = humiov1alpha1.HumioFilterAlertSpec{ - Name: alert.Name, - QueryString: alert.QueryString, - Description: alert.Description, - ThrottleTimeSeconds: alert.ThrottleTimeSeconds, - ThrottleField: alert.ThrottleField, - Enabled: alert.Enabled, - Actions: alert.ActionNames, - Labels: alert.Labels, - } -} diff --git a/pkg/humio/ingesttoken_transform.go b/pkg/humio/ingesttoken_transform.go deleted file mode 100644 index 35ac2126..00000000 --- a/pkg/humio/ingesttoken_transform.go +++ /dev/null @@ -1,15 +0,0 @@ -package humio - -import ( - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" -) - -func IngestTokenTransform(hit *humiov1alpha1.HumioIngestToken) *humioapi.IngestToken { - ingestToken := &humioapi.IngestToken{ - Name: hit.Spec.Name, - AssignedParser: hit.Spec.ParserName, - } - - return ingestToken -} diff --git a/pkg/humio/license.go b/pkg/humio/license.go deleted file mode 100644 index 15f9bea1..00000000 --- a/pkg/humio/license.go +++ /dev/null @@ -1,64 +0,0 @@ -package humio - -import ( - "fmt" - "time" - - jose "github.com/go-jose/go-jose/v4" - "github.com/go-jose/go-jose/v4/jwt" - - humioapi "github.com/humio/cli/api" -) - -type license struct { - IDVal string `json:"uid,omitempty"` - ValidUntilVal int `json:"validUntil,omitempty"` - IssuedAtVal int `json:"iat,omitempty"` -} - -func (l license) LicenseType() string { - if l.IDVal == "" { - return "trial" - } - return "onprem" -} - -func ParseLicense(licenseString string) (humioapi.License, error) { - onPremLicense, err := ParseLicenseType(licenseString) - if onPremLicense != nil { - return &humioapi.OnPremLicense{ - ID: onPremLicense.ID, - ExpiresAtVal: onPremLicense.ExpiresAtVal, - IssuedAtVal: onPremLicense.IssuedAtVal, - }, nil - } - return nil, fmt.Errorf("invalid license: %w", err) -} - -func ParseLicenseType(licenseString string) (*humioapi.OnPremLicense, error) { - licenseContent := &license{} - - token, err := jwt.ParseSigned(licenseString, []jose.SignatureAlgorithm{jose.ES256, jose.ES512}) - if err != nil { - return nil, fmt.Errorf("error when parsing license: %w", err) - } - err = token.UnsafeClaimsWithoutVerification(&licenseContent) - if err != nil { - return nil, fmt.Errorf("error when parsing license: %w", err) - } - - locUTC, _ := time.LoadLocation("UTC") - - expiresAtVal := time.Unix(int64(licenseContent.ValidUntilVal), 0).In(locUTC) - issuedAtVal := time.Unix(int64(licenseContent.IssuedAtVal), 0).In(locUTC) - - if licenseContent.LicenseType() == "onprem" { - return &humioapi.OnPremLicense{ - ID: licenseContent.IDVal, - ExpiresAtVal: expiresAtVal.Format(time.RFC3339), - IssuedAtVal: issuedAtVal.Format(time.RFC3339), - }, nil - } - - return nil, fmt.Errorf("invalid license type: %s", licenseContent.LicenseType()) -} diff --git a/pkg/humio/parser_transform.go b/pkg/humio/parser_transform.go deleted file mode 100644 index e6a603fa..00000000 --- a/pkg/humio/parser_transform.go +++ /dev/null @@ -1,26 +0,0 @@ -package humio - -import ( - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" -) - -func ParserTransform(hp *humiov1alpha1.HumioParser) *humioapi.Parser { - parser := &humioapi.Parser{ - Name: hp.Spec.Name, - Script: hp.Spec.ParserScript, - FieldsToTag: hp.Spec.TagFields, - FieldsToBeRemovedBeforeParsing: []string{}, - } - - testCasesGQL := make([]humioapi.ParserTestCase, len(hp.Spec.TestData)) - for i := range hp.Spec.TestData { - testCasesGQL[i] = humioapi.ParserTestCase{ - Event: humioapi.ParserTestEvent{RawString: hp.Spec.TestData[i]}, - Assertions: []humioapi.ParserTestCaseAssertions{}, - } - } - parser.TestCases = testCasesGQL - - return parser -} diff --git a/pkg/humio/scheduledsearch_transform.go b/pkg/humio/scheduledsearch_transform.go deleted file mode 100644 index 599af1f6..00000000 --- a/pkg/humio/scheduledsearch_transform.go +++ /dev/null @@ -1,45 +0,0 @@ -package humio - -import ( - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" -) - -func ScheduledSearchTransform(hss *humiov1alpha1.HumioScheduledSearch) *humioapi.ScheduledSearch { - scheduledSearch := &humioapi.ScheduledSearch{ - Name: hss.Spec.Name, - QueryString: hss.Spec.QueryString, - Description: hss.Spec.Description, - QueryStart: hss.Spec.QueryStart, - QueryEnd: hss.Spec.QueryEnd, - Schedule: hss.Spec.Schedule, - TimeZone: hss.Spec.TimeZone, - BackfillLimit: hss.Spec.BackfillLimit, - Enabled: hss.Spec.Enabled, - ActionNames: hss.Spec.Actions, - Labels: hss.Spec.Labels, - QueryOwnershipType: humioapi.QueryOwnershipTypeOrganization, - } - - if scheduledSearch.Labels == nil { - scheduledSearch.Labels = []string{} - } - - return scheduledSearch -} - -func ScheduledSearchHydrate(hss *humiov1alpha1.HumioScheduledSearch, scheduledSearch *humioapi.ScheduledSearch) { - hss.Spec = humiov1alpha1.HumioScheduledSearchSpec{ - Name: scheduledSearch.Name, - QueryString: scheduledSearch.QueryString, - Description: scheduledSearch.Description, - QueryStart: scheduledSearch.QueryStart, - QueryEnd: scheduledSearch.QueryEnd, - Schedule: scheduledSearch.Schedule, - TimeZone: scheduledSearch.TimeZone, - BackfillLimit: scheduledSearch.BackfillLimit, - Enabled: scheduledSearch.Enabled, - Actions: scheduledSearch.ActionNames, - Labels: scheduledSearch.Labels, - } -} diff --git a/pkg/kubernetes/role_bindings.go b/pkg/kubernetes/role_bindings.go deleted file mode 100644 index b7bd250d..00000000 --- a/pkg/kubernetes/role_bindings.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2020 Humio https://humio.com - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package kubernetes - -import ( - "context" - - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// ConstructRoleBinding constructs a role binding which binds the given serviceAccountName to the role passed in -func ConstructRoleBinding(roleBindingName, roleName, humioClusterNamespace, serviceAccountName string, labels map[string]string) *rbacv1.RoleBinding { - return &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: roleBindingName, - Namespace: humioClusterNamespace, - Labels: labels, - }, - RoleRef: rbacv1.RoleRef{ - Kind: "Role", - APIGroup: "rbac.authorization.k8s.io", - Name: roleName, - }, - Subjects: []rbacv1.Subject{ - { - Kind: "ServiceAccount", - Name: serviceAccountName, - Namespace: humioClusterNamespace, - }, - }, - } -} - -// GetRoleBinding returns the given role if it exists -func GetRoleBinding(ctx context.Context, c client.Client, roleBindingName, roleBindingNamespace string) (*rbacv1.RoleBinding, error) { - var existingRoleBinding rbacv1.RoleBinding - err := c.Get(ctx, types.NamespacedName{ - Name: roleBindingName, - Namespace: roleBindingNamespace, - }, &existingRoleBinding) - return &existingRoleBinding, err -}