diff --git a/src/operator/controllers/webhook_traffic/network_policy_handler.go b/src/operator/controllers/webhook_traffic/network_policy_handler.go index ed64812c1..9c4b207e6 100644 --- a/src/operator/controllers/webhook_traffic/network_policy_handler.go +++ b/src/operator/controllers/webhook_traffic/network_policy_handler.go @@ -10,6 +10,7 @@ import ( "github.com/otterize/intents-operator/src/shared/serviceidresolver" "github.com/otterize/intents-operator/src/shared/serviceidresolver/serviceidentity" "github.com/samber/lo" + "github.com/sirupsen/logrus" "golang.org/x/exp/slices" admissionv1 "k8s.io/api/admissionregistration/v1" corev1 "k8s.io/api/core/v1" @@ -33,6 +34,7 @@ const ( ReasonPatchingWebhookTrafficNetpol = "PatchingNetworkPolicyForWebhook" ReasonPatchingWebhookTrafficNetpolFailed = "PatchingNetworkPolicyForWebhookFailed" ReasonPatchingWebhookTrafficNetpolSuccess = "PatchingNetworkPolicyForWebhookSucceeded" + ReasonWebhookPortNotFoundOnServiceError = "WebhookPortNotFoundOnServiceError" ) type WebhookClientConfigurationWithMeta struct { @@ -168,7 +170,7 @@ func (n *NetworkPolicyHandler) reduceWebhooksNetpols(ctx context.Context, webhoo // At this point we want to create the network policy, because the configuration is either set to "always" or // that it is set to "if blocked by otterize" and the service is blocked by otterize // TODO: do we also need to create netpol for Otterize? - netpol, err := n.buildNetworkPolicy(ctx, webhookClientConfig.webhookName, service) + netpol, err := n.buildNetworkPolicy(ctx, webhookClientConfig.webhookName, webhookClientConfig.clientConfiguration.Service, service) if err != nil { return make(NetworkPolicyWithMetaByName), errors.Wrap(err) } @@ -192,6 +194,9 @@ func (n *NetworkPolicyHandler) reduceWebhooksNetpols(ctx context.Context, webhoo func (n *NetworkPolicyHandler) isServiceBlockedByOtterize(ctx context.Context, service *corev1.Service) (bool, error) { endpoints := &corev1.Endpoints{} err := n.client.Get(ctx, types.NamespacedName{Namespace: service.Namespace, Name: service.Name}, endpoints) + if err != nil && k8serrors.IsNotFound(err) { + return false, nil + } if err != nil { return false, errors.Wrap(err) } @@ -200,10 +205,8 @@ func (n *NetworkPolicyHandler) isServiceBlockedByOtterize(ctx context.Context, s for _, address := range endpointsAddresses { pod, err := n.getAffectedPod(ctx, address) - if k8sErr := &(k8serrors.StatusError{}); errors.As(err, &k8sErr) { - if k8serrors.IsNotFound(k8sErr) { - continue - } + if k8serrors.IsNotFound(err) { + continue } if err != nil { @@ -307,7 +310,7 @@ func (n *NetworkPolicyHandler) getWebhookService(ctx context.Context, webhookSer return service, true, nil } -func (n *NetworkPolicyHandler) buildNetworkPolicy(ctx context.Context, webhookName string, service *corev1.Service) (v1.NetworkPolicy, error) { +func (n *NetworkPolicyHandler) buildNetworkPolicy(ctx context.Context, webhookName string, webhookService *admissionv1.ServiceReference, service *corev1.Service) (v1.NetworkPolicy, error) { policyName := fmt.Sprintf("webhook-%s-access-to-%s", strings.ToLower(webhookName), strings.ToLower(service.Name)) rule := v1.NetworkPolicyIngressRule{} @@ -352,23 +355,43 @@ func (n *NetworkPolicyHandler) buildNetworkPolicy(ctx context.Context, webhookNa }, } - netpolPorts := make([]v1.NetworkPolicyPort, 0, 2*len(service.Spec.Ports)) - - for _, servicePort := range service.Spec.Ports { - // Add the port - netpolPorts = append(netpolPorts, - v1.NetworkPolicyPort{ - Port: lo.ToPtr(intstr.IntOrString{IntVal: servicePort.Port, Type: intstr.Int}), - Protocol: lo.ToPtr(servicePort.Protocol), - }) - // Add the target port - if servicePort.TargetPort.IntVal != 0 || servicePort.TargetPort.StrVal != "" { - netpolPorts = append(netpolPorts, - v1.NetworkPolicyPort{ - Port: lo.ToPtr(servicePort.TargetPort), - Protocol: lo.ToPtr(servicePort.Protocol), - }) - } + netpolPorts := make([]v1.NetworkPolicyPort, 0, 2) + if webhookService.Port != nil { + // If the webhook defines a port - lets use it + netpolPorts = append(netpolPorts, v1.NetworkPolicyPort{ + Port: lo.ToPtr(intstr.IntOrString{IntVal: *webhookService.Port, Type: intstr.Int}), + Protocol: lo.ToPtr(corev1.ProtocolTCP), + }) + } else { + // Otherwise, use the defaukt webhook port - 443 + netpolPorts = append(netpolPorts, v1.NetworkPolicyPort{ + Port: lo.ToPtr(intstr.IntOrString{IntVal: 443, Type: intstr.Int}), + Protocol: lo.ToPtr(corev1.ProtocolTCP), + }) + } + + // Find the webhook's-service's-port in the service + servicePort, servicePortFound := lo.Find(service.Spec.Ports, func(item corev1.ServicePort) bool { + return item.Port == netpolPorts[0].Port.IntVal + }) + + if !servicePortFound { + logrus.WithFields(logrus.Fields{ + "WebhookName": webhookName, + "ServiceName": service.Name, + "ServiceNamespace": service.Namespace, + "ServicePort": netpolPorts[0].Port.IntVal, + }).Warning("Webhook service port not found on service resource") + n.RecordWarningEventf(service, ReasonWebhookPortNotFoundOnServiceError, "Webhook %s is defined to work on port %d", webhookName, netpolPorts[0].Port.IntVal) + return v1.NetworkPolicy{}, errors.New("Webhook port was not found on service") + } + + // Add the service's target port if exists + if servicePort.TargetPort.IntVal != 0 || servicePort.TargetPort.StrVal != "" { + netpolPorts = append(netpolPorts, v1.NetworkPolicyPort{ + Port: lo.ToPtr(servicePort.TargetPort), + Protocol: lo.ToPtr(servicePort.Protocol), + }) } newPolicy.Spec.Ingress[0].Ports = netpolPorts diff --git a/src/operator/controllers/webhook_traffic/network_policy_handler_test.go b/src/operator/controllers/webhook_traffic/network_policy_handler_test.go index ede45dcbb..bdba95197 100644 --- a/src/operator/controllers/webhook_traffic/network_policy_handler_test.go +++ b/src/operator/controllers/webhook_traffic/network_policy_handler_test.go @@ -407,6 +407,101 @@ func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleAlways_Se s.ExpectEvent(ReasonCreatingWebhookTrafficNetpolSuccess) } +func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleAlways_ServiceHasNoTargetPortThanPort_CreatePolicy() { + s.handler = NewNetworkPolicyHandler(s.Client, &runtime.Scheme{}, automate_third_party_network_policy.Always, 32, false) + s.handler.InjectRecorder(s.Recorder) + + s.webhookService = &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestServiceName, + Namespace: TestNamespace, + }, + Spec: corev1.ServiceSpec{ + Selector: map[string]string{ + "Taylor": "Swift", + }, + Ports: []corev1.ServicePort{ + { + Port: TestServicePort, + Protocol: corev1.ProtocolTCP, + }, + }, + }, + } + + s.mockForReturningValidatingWebhook() + s.mockReturningWebhookService() + //s.mockServiceIsBlockedByOtterize(make([]v1.NetworkPolicy, 0)) + s.mockGetControlPlaneIPs() + s.mockGetExistingOtterizeWebhooksNetpols([]v1.NetworkPolicy{}) + + netpolMatcher := NewNetworkPolicyMatcher([]int32{TestServicePort}, s.handler.allowAllIncomingTraffic, nil) + s.Client.EXPECT().Create(gomock.Any(), gomock.All(netpolMatcher)).Return(nil) + err := s.handler.HandleAll(context.Background()) + s.Require().NoError(err) + s.ExpectEvent(ReasonCreatingWebhookTrafficNetpol) + s.ExpectEvent(ReasonCreatingWebhookTrafficNetpolSuccess) +} + +func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleAlways_WebhookDoesNotDefinePort_CreatePolicyWithDefaultPort() { + s.handler = NewNetworkPolicyHandler(s.Client, &runtime.Scheme{}, automate_third_party_network_policy.Always, 32, false) + s.handler.InjectRecorder(s.Recorder) + + s.validatingWebhook = ValidatingWebhookConfiguration.DeepCopy() + s.validatingWebhook.Webhooks[0].ClientConfig.Service.Port = nil + + s.webhookService = &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: TestServiceName, + Namespace: TestNamespace, + }, + Spec: corev1.ServiceSpec{ + Selector: map[string]string{ + "Taylor": "Swift", + }, + Ports: []corev1.ServicePort{ + { + Port: 443, + Protocol: corev1.ProtocolTCP, + }, + }, + }, + } + + s.mockForReturningValidatingWebhook() + s.mockReturningWebhookService() + //s.mockServiceIsBlockedByOtterize(make([]v1.NetworkPolicy, 0)) + s.mockGetControlPlaneIPs() + s.mockGetExistingOtterizeWebhooksNetpols([]v1.NetworkPolicy{}) + + netpolMatcher := NewNetworkPolicyMatcher([]int32{443}, s.handler.allowAllIncomingTraffic, nil) + s.Client.EXPECT().Create(gomock.Any(), gomock.All(netpolMatcher)).Return(nil) + err := s.handler.HandleAll(context.Background()) + s.Require().NoError(err) + s.ExpectEvent(ReasonCreatingWebhookTrafficNetpol) + s.ExpectEvent(ReasonCreatingWebhookTrafficNetpolSuccess) +} + +func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleAlways_WebhookPortNotFoundOnService_ExpectErrors() { + s.handler = NewNetworkPolicyHandler(s.Client, &runtime.Scheme{}, automate_third_party_network_policy.Always, 32, false) + s.handler.InjectRecorder(s.Recorder) + + s.validatingWebhook = ValidatingWebhookConfiguration.DeepCopy() + s.validatingWebhook.Webhooks[0].ClientConfig.Service.Port = nil + + s.mockForReturningValidatingWebhook() + s.mockReturningWebhookService() + //s.mockServiceIsBlockedByOtterize(make([]v1.NetworkPolicy, 0)) + s.mockGetControlPlaneIPs() + //s.mockGetExistingOtterizeWebhooksNetpols([]v1.NetworkPolicy{}) + + //netpolMatcher := NewNetworkPolicyMatcher([]int32{443}, s.handler.allowAllIncomingTraffic, nil) + //s.Client.EXPECT().Create(gomock.Any(), gomock.All(netpolMatcher)).Return(nil) + err := s.handler.HandleAll(context.Background()) + s.Require().Error(err, "Webhook port was not found on service") + s.ExpectEvent(ReasonWebhookPortNotFoundOnServiceError) +} + func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleAlways_WebhookNameTooLong_CreatePolicy() { s.handler = NewNetworkPolicyHandler(s.Client, &runtime.Scheme{}, automate_third_party_network_policy.Always, 32, false) s.handler.InjectRecorder(s.Recorder) @@ -427,6 +522,46 @@ func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleAlways_We s.ExpectEvent(ReasonCreatingWebhookTrafficNetpolSuccess) } +func (s *NetworkPolicyHandlerTestSuite) TestNetworkPolicyHandler_HandleIfBlockedByOtterize_ServiceIsBlockedByOtterize_TwoWebhooksToSameServiceDifferentPorts_CreatingOneWebhookPolicy() { + secondPort := int32(1432) + s.validatingWebhook.Webhooks = append(s.validatingWebhook.Webhooks, + admissionv1.ValidatingWebhook{ + Name: "Second", + ClientConfig: admissionv1.WebhookClientConfig{ + Service: &admissionv1.ServiceReference{ + Name: TestServiceName, + Namespace: TestNamespace, + Port: lo.ToPtr(secondPort), + }, + }, + }) + s.webhookService.Spec.Ports = append(s.webhookService.Spec.Ports, corev1.ServicePort{ + Port: secondPort, + Protocol: corev1.ProtocolTCP, + }) + + s.mockForReturningValidatingWebhook() + + // Called once for "First" webhook + s.mockReturningWebhookService() + s.mockServiceIsBlockedByOtterize(OtterizeIngressNetpols) + s.mockGetControlPlaneIPs() + + // Called second time for "Second"" webhook + s.mockReturningWebhookService() + s.mockServiceIsBlockedByOtterize(OtterizeIngressNetpols) + s.mockGetControlPlaneIPs() + + s.mockGetExistingOtterizeWebhooksNetpols([]v1.NetworkPolicy{}) + + netpolMatcher := NewNetworkPolicyMatcher([]int32{secondPort, TestServicePort}, s.handler.allowAllIncomingTraffic, nil) + s.Client.EXPECT().Create(gomock.Any(), gomock.All(netpolMatcher)).Return(nil) + err := s.handler.HandleAll(context.Background()) + s.Require().NoError(err) + s.ExpectEvent(ReasonCreatingWebhookTrafficNetpol) + s.ExpectEvent(ReasonCreatingWebhookTrafficNetpolSuccess) +} + func (s *NetworkPolicyHandlerTestSuite) mockForReturningValidatingWebhook() { s.Client.EXPECT().List( gomock.Any(), gomock.Eq(&admissionv1.ValidatingWebhookConfigurationList{}), diff --git a/src/operator/main.go b/src/operator/main.go index 7ade92570..208f4c56a 100644 --- a/src/operator/main.go +++ b/src/operator/main.go @@ -52,7 +52,6 @@ import ( "github.com/otterize/intents-operator/src/shared/k8sconf" "github.com/otterize/intents-operator/src/shared/operator_cloud_client" "github.com/otterize/intents-operator/src/shared/operatorconfig" - "github.com/otterize/intents-operator/src/shared/operatorconfig/automate_third_party_network_policy" "github.com/otterize/intents-operator/src/shared/operatorconfig/enforcement" "github.com/otterize/intents-operator/src/shared/reconcilergroup" "github.com/otterize/intents-operator/src/shared/serviceidresolver" @@ -240,7 +239,7 @@ func main() { webhooksTrafficNetworkHandler := webhook_traffic.NewNetworkPolicyHandler(mgr.GetClient(), scheme, - automate_third_party_network_policy.Off, + enforcementConfig.GetAutomateAllowWebhookTraffic(), viper.GetInt(operatorconfig.ControlPlaneIPv4CidrPrefixLength), viper.GetBool(operatorconfig.WebhookTrafficAllowAllKey)) webhookTrafficReconcilerManager := webhook_traffic.NewWebhookTrafficReconcilerManager(mgr.GetClient(), webhooksTrafficNetworkHandler) diff --git a/src/shared/operator_cloud_client/status_report.go b/src/shared/operator_cloud_client/status_report.go index 934a4c7ca..fd534bc10 100644 --- a/src/shared/operator_cloud_client/status_report.go +++ b/src/shared/operator_cloud_client/status_report.go @@ -94,6 +94,19 @@ func getAllowExternalTrafficConfig() graphqlclient.AllowExternalTrafficPolicy { } } +func getAutomateAllowWebhookTrafficConfig() graphqlclient.AutomateThirdPartyNetworkPolicy { + switch enforcement.GetConfig().AutomateAllowWebhookTraffic { + case automate_third_party_network_policy.Always: + return graphqlclient.AutomateThirdPartyNetworkPolicyAlways + case automate_third_party_network_policy.Off: + return graphqlclient.AutomateThirdPartyNetworkPolicyOff + case automate_third_party_network_policy.IfBlockedByOtterize: + return graphqlclient.AutomateThirdPartyNetworkPolicyIfBlockedByOtterize + default: + return "" + } +} + func uploadConfiguration(ctx context.Context, client CloudClient, mgr manager.Manager) { ingressConfigIdentities := operatorconfig.GetIngressControllerServiceIdentities() externallyManagedPolicyWorkloadIdentities := operatorconfig.GetExternallyManagedPoliciesServiceIdentities() @@ -143,6 +156,7 @@ func uploadConfiguration(ctx context.Context, client CloudClient, mgr manager.Ma AllowExternalTrafficPolicy: getAllowExternalTrafficConfig(), // The server expect for AllowExternalTrafficPolicy because of backwards compatibility AutomateThirdPartyNetworkPolicies: getAutomateThirdPartyNetworkPoliciesConfig(), PrometheusServerConfigs: getPrometheusServiceIdentities(), + AutomateAllowWebhookTraffic: getAutomateAllowWebhookTrafficConfig(), } configInput.IngressControllerConfig = lo.Map(ingressConfigIdentities, func(identity serviceidentity.ServiceIdentity, _ int) graphqlclient.IngressControllerConfigInput { @@ -165,7 +179,6 @@ func uploadConfiguration(ctx context.Context, client CloudClient, mgr manager.Ma configInput.AutomatedThirdPartyPolicyTypes = []graphqlclient.AutomatedThirdPartyPolicyTypes{ graphqlclient.AutomatedThirdPartyPolicyTypesExternalTraffic, graphqlclient.AutomatedThirdPartyPolicyTypesMetricsTraffic, - graphqlclient.AutomatedThirdPartyPolicyTypesWebhookTraffic, } client.ReportIntentsOperatorConfiguration(timeoutCtx, configInput) diff --git a/src/shared/operatorconfig/enforcement/config.go b/src/shared/operatorconfig/enforcement/config.go index 6d6646c93..3a53bf8e9 100644 --- a/src/shared/operatorconfig/enforcement/config.go +++ b/src/shared/operatorconfig/enforcement/config.go @@ -25,6 +25,7 @@ type Config struct { EnforcedNamespaces *goset.Set[string] ExcludedStrictModeNamespaces *goset.Set[string] AutomateThirdPartyNetworkPolicies automate_third_party_network_policy.Enum + AutomateAllowWebhookTraffic automate_third_party_network_policy.Enum PrometheusServiceIdentities []serviceidentity.ServiceIdentity } @@ -46,10 +47,29 @@ func (c Config) GetAutomateThirdPartyNetworkPolicy() automate_third_party_networ } } +func (c Config) GetAutomateAllowWebhookTraffic() automate_third_party_network_policy.Enum { + switch c.AutomateAllowWebhookTraffic { + case automate_third_party_network_policy.Off: + return automate_third_party_network_policy.Off + case automate_third_party_network_policy.Always: + if !c.EnforcementDefaultState { + // We don't want to create network policies for third parties when enforcement is disabled. + // However, if one uses shadow mode we can still block third party traffic to his protected services + // therefore we should return automate_third_party_network_policy.IfBlockedByOtterize + return automate_third_party_network_policy.IfBlockedByOtterize + } + return automate_third_party_network_policy.Always + default: + return automate_third_party_network_policy.IfBlockedByOtterize + } +} + const ( ActiveEnforcementNamespacesKey = "active-enforcement-namespaces" // When using the "shadow enforcement" mode, namespaces in this list will be treated as if the enforcement were active AutomateThirdPartyNetworkPoliciesKey = "automate-third-party-network-policies" // Whether to automatically create network policies for external traffic & metrics collection traffic AutomateThirdPartyNetworkPoliciesDefault = string(automate_third_party_network_policy.IfBlockedByOtterize) + AutomateAllowWebhookTrafficKey = "automate-allow-webhook-traffic" // Whether to automatically create network policies for webhook services + AutomateAllowWebhookTrafficDefault = string(automate_third_party_network_policy.IfBlockedByOtterize) EnforcementDefaultStateKey = "enforcement-default-state" // Sets the default state of the If true, always enforces. If false, can be overridden using ProtectedService. EnforcementDefaultStateDefault = true EnableNetworkPolicyKey = "enable-network-policy-creation" // Whether to enable Intents network policy creation @@ -88,6 +108,7 @@ func init() { viper.SetDefault(EnableGCPPolicyKey, EnableGCPPolicyDefault) viper.SetDefault(EnableAzurePolicyKey, EnableAzurePolicyDefault) viper.SetDefault(AutomateThirdPartyNetworkPoliciesKey, AutomateThirdPartyNetworkPoliciesDefault) + viper.SetDefault(AutomateAllowWebhookTrafficKey, AutomateAllowWebhookTrafficDefault) viper.SetDefault(EnableStrictModeIntentsKey, EnableStrictModeIntentsDefault) } @@ -121,6 +142,7 @@ func GetConfig() Config { EnforcedNamespaces: goset.FromSlice(viper.GetStringSlice(ActiveEnforcementNamespacesKey)), ExcludedStrictModeNamespaces: goset.FromSlice(viper.GetStringSlice(ActiveEnforcementNamespacesKey)), AutomateThirdPartyNetworkPolicies: automate_third_party_network_policy.Enum(viper.GetString(AutomateThirdPartyNetworkPoliciesKey)), + AutomateAllowWebhookTraffic: automate_third_party_network_policy.Enum(viper.GetString(AutomateAllowWebhookTrafficKey)), PrometheusServiceIdentities: GetPrometheusServiceIdentities(), } } diff --git a/src/shared/otterizecloud/graphqlclient/generated.go b/src/shared/otterizecloud/graphqlclient/generated.go index 56ad1ce6f..6c0960b17 100644 --- a/src/shared/otterizecloud/graphqlclient/generated.go +++ b/src/shared/otterizecloud/graphqlclient/generated.go @@ -31,7 +31,6 @@ type AutomatedThirdPartyPolicyTypes string const ( AutomatedThirdPartyPolicyTypesExternalTraffic AutomatedThirdPartyPolicyTypes = "EXTERNAL_TRAFFIC" AutomatedThirdPartyPolicyTypesMetricsTraffic AutomatedThirdPartyPolicyTypes = "METRICS_TRAFFIC" - AutomatedThirdPartyPolicyTypesWebhookTraffic AutomatedThirdPartyPolicyTypes = "WEBHOOK_TRAFFIC" ) type AzureKeyVaultPolicyInput struct { @@ -458,6 +457,7 @@ type IntentsOperatorConfigurationInput struct { AutomateThirdPartyNetworkPolicies AutomateThirdPartyNetworkPolicy `json:"automateThirdPartyNetworkPolicies"` PrometheusServerConfigs []PrometheusServerConfigInput `json:"prometheusServerConfigs"` AutomatedThirdPartyPolicyTypes []AutomatedThirdPartyPolicyTypes `json:"automatedThirdPartyPolicyTypes"` + AutomateAllowWebhookTraffic AutomateThirdPartyNetworkPolicy `json:"automateAllowWebhookTraffic"` } // GetGlobalEnforcementEnabled returns IntentsOperatorConfigurationInput.GlobalEnforcementEnabled, and is useful for accessing the field via an interface. @@ -563,6 +563,11 @@ func (v *IntentsOperatorConfigurationInput) GetAutomatedThirdPartyPolicyTypes() return v.AutomatedThirdPartyPolicyTypes } +// GetAutomateAllowWebhookTraffic returns IntentsOperatorConfigurationInput.AutomateAllowWebhookTraffic, and is useful for accessing the field via an interface. +func (v *IntentsOperatorConfigurationInput) GetAutomateAllowWebhookTraffic() AutomateThirdPartyNetworkPolicy { + return v.AutomateAllowWebhookTraffic +} + type InternetConfigInput struct { Domains []*string `json:"domains"` DiscoveredTarget *DNSIPPairInput `json:"discoveredTarget"` @@ -956,310 +961,340 @@ type dummyResponse struct { // GetDummyError returns dummyResponse.DummyError, and is useful for accessing the field via an interface. func (v *dummyResponse) GetDummyError() UserErrorType { return v.DummyError } +// The query or mutation executed by ReportAppliedKubernetesIntents. +const ReportAppliedKubernetesIntents_Operation = ` +mutation ReportAppliedKubernetesIntents ($namespace: String!, $intents: [IntentInput!]!, $clusterId: String!) { + reportAppliedKubernetesIntents(namespace: $namespace, intents: $intents, ossClusterId: $clusterId) +} +` + func ReportAppliedKubernetesIntents( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, namespace *string, intents []*IntentInput, clusterId *string, ) (*ReportAppliedKubernetesIntentsResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportAppliedKubernetesIntents", - Query: ` -mutation ReportAppliedKubernetesIntents ($namespace: String!, $intents: [IntentInput!]!, $clusterId: String!) { - reportAppliedKubernetesIntents(namespace: $namespace, intents: $intents, ossClusterId: $clusterId) -} -`, + Query: ReportAppliedKubernetesIntents_Operation, Variables: &__ReportAppliedKubernetesIntentsInput{ Namespace: namespace, Intents: intents, ClusterId: clusterId, }, } - var err error + var err_ error - var data ReportAppliedKubernetesIntentsResponse - resp := &graphql.Response{Data: &data} + var data_ ReportAppliedKubernetesIntentsResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } +// The query or mutation executed by ReportClientIntentEvents. +const ReportClientIntentEvents_Operation = ` +mutation ReportClientIntentEvents ($events: [ClientIntentEventInput!]!) { + reportClientIntentEvent(events: $events) +} +` + func ReportClientIntentEvents( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, events []ClientIntentEventInput, ) (*ReportClientIntentEventsResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportClientIntentEvents", - Query: ` -mutation ReportClientIntentEvents ($events: [ClientIntentEventInput!]!) { - reportClientIntentEvent(events: $events) -} -`, + Query: ReportClientIntentEvents_Operation, Variables: &__ReportClientIntentEventsInput{ Events: events, }, } - var err error + var err_ error - var data ReportClientIntentEventsResponse - resp := &graphql.Response{Data: &data} + var data_ ReportClientIntentEventsResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ +} + +// The query or mutation executed by ReportClientIntentStatuses. +const ReportClientIntentStatuses_Operation = ` +mutation ReportClientIntentStatuses ($statuses: [ClientIntentStatusInput!]!) { + reportClientIntentStatus(statuses: $statuses) } +` func ReportClientIntentStatuses( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, statuses []ClientIntentStatusInput, ) (*ReportClientIntentStatusesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportClientIntentStatuses", - Query: ` -mutation ReportClientIntentStatuses ($statuses: [ClientIntentStatusInput!]!) { - reportClientIntentStatus(statuses: $statuses) -} -`, + Query: ReportClientIntentStatuses_Operation, Variables: &__ReportClientIntentStatusesInput{ Statuses: statuses, }, } - var err error + var err_ error - var data ReportClientIntentStatusesResponse - resp := &graphql.Response{Data: &data} + var data_ ReportClientIntentStatusesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ +} + +// The query or mutation executed by ReportComponentStatus. +const ReportComponentStatus_Operation = ` +mutation ReportComponentStatus ($component: ComponentType!) { + reportIntegrationComponentStatus(component: $component) } +` func ReportComponentStatus( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, component ComponentType, ) (*ReportComponentStatusResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportComponentStatus", - Query: ` -mutation ReportComponentStatus ($component: ComponentType!) { - reportIntegrationComponentStatus(component: $component) -} -`, + Query: ReportComponentStatus_Operation, Variables: &__ReportComponentStatusInput{ Component: component, }, } - var err error + var err_ error - var data ReportComponentStatusResponse - resp := &graphql.Response{Data: &data} + var data_ ReportComponentStatusResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } +// The query or mutation executed by ReportExternallyAccessibleServices. +const ReportExternallyAccessibleServices_Operation = ` +mutation ReportExternallyAccessibleServices ($namespace: String!, $services: [ExternallyAccessibleServiceInput!]!) { + reportExternallyAccessibleServices(namespace: $namespace, services: $services) +} +` + func ReportExternallyAccessibleServices( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, namespace string, services []ExternallyAccessibleServiceInput, ) (*ReportExternallyAccessibleServicesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportExternallyAccessibleServices", - Query: ` -mutation ReportExternallyAccessibleServices ($namespace: String!, $services: [ExternallyAccessibleServiceInput!]!) { - reportExternallyAccessibleServices(namespace: $namespace, services: $services) -} -`, + Query: ReportExternallyAccessibleServices_Operation, Variables: &__ReportExternallyAccessibleServicesInput{ Namespace: namespace, Services: services, }, } - var err error + var err_ error - var data ReportExternallyAccessibleServicesResponse - resp := &graphql.Response{Data: &data} + var data_ ReportExternallyAccessibleServicesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ +} + +// The query or mutation executed by ReportIntentsOperatorConfiguration. +const ReportIntentsOperatorConfiguration_Operation = ` +mutation ReportIntentsOperatorConfiguration ($configuration: IntentsOperatorConfigurationInput!) { + reportIntentsOperatorConfiguration(configuration: $configuration) } +` func ReportIntentsOperatorConfiguration( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, configuration IntentsOperatorConfigurationInput, ) (*ReportIntentsOperatorConfigurationResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportIntentsOperatorConfiguration", - Query: ` -mutation ReportIntentsOperatorConfiguration ($configuration: IntentsOperatorConfigurationInput!) { - reportIntentsOperatorConfiguration(configuration: $configuration) -} -`, + Query: ReportIntentsOperatorConfiguration_Operation, Variables: &__ReportIntentsOperatorConfigurationInput{ Configuration: configuration, }, } - var err error + var err_ error - var data ReportIntentsOperatorConfigurationResponse - resp := &graphql.Response{Data: &data} + var data_ ReportIntentsOperatorConfigurationResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ +} + +// The query or mutation executed by ReportKafkaServerConfig. +const ReportKafkaServerConfig_Operation = ` +mutation ReportKafkaServerConfig ($namespace: String!, $kafkaServerConfigs: [KafkaServerConfigInput!]!) { + reportKafkaServerConfigs(namespace: $namespace, serverConfigs: $kafkaServerConfigs) } +` func ReportKafkaServerConfig( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, namespace string, kafkaServerConfigs []KafkaServerConfigInput, ) (*ReportKafkaServerConfigResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportKafkaServerConfig", - Query: ` -mutation ReportKafkaServerConfig ($namespace: String!, $kafkaServerConfigs: [KafkaServerConfigInput!]!) { - reportKafkaServerConfigs(namespace: $namespace, serverConfigs: $kafkaServerConfigs) -} -`, + Query: ReportKafkaServerConfig_Operation, Variables: &__ReportKafkaServerConfigInput{ Namespace: namespace, KafkaServerConfigs: kafkaServerConfigs, }, } - var err error + var err_ error - var data ReportKafkaServerConfigResponse - resp := &graphql.Response{Data: &data} + var data_ ReportKafkaServerConfigResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ +} + +// The query or mutation executed by ReportNetworkPolicies. +const ReportNetworkPolicies_Operation = ` +mutation ReportNetworkPolicies ($namespace: String!, $policies: [NetworkPolicyInput!]!) { + reportNetworkPolicies(namespace: $namespace, networkPolicies: $policies) } +` func ReportNetworkPolicies( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, namespace string, policies []NetworkPolicyInput, ) (*ReportNetworkPoliciesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportNetworkPolicies", - Query: ` -mutation ReportNetworkPolicies ($namespace: String!, $policies: [NetworkPolicyInput!]!) { - reportNetworkPolicies(namespace: $namespace, networkPolicies: $policies) -} -`, + Query: ReportNetworkPolicies_Operation, Variables: &__ReportNetworkPoliciesInput{ Namespace: namespace, Policies: policies, }, } - var err error + var err_ error - var data ReportNetworkPoliciesResponse - resp := &graphql.Response{Data: &data} + var data_ ReportNetworkPoliciesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } +// The query or mutation executed by ReportProtectedServicesSnapshot. +const ReportProtectedServicesSnapshot_Operation = ` +mutation ReportProtectedServicesSnapshot ($namespace: String!, $services: [ProtectedServiceInput!]!) { + reportProtectedServicesSnapshot(namespace: $namespace, services: $services) +} +` + func ReportProtectedServicesSnapshot( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, namespace string, services []ProtectedServiceInput, ) (*ReportProtectedServicesSnapshotResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportProtectedServicesSnapshot", - Query: ` -mutation ReportProtectedServicesSnapshot ($namespace: String!, $services: [ProtectedServiceInput!]!) { - reportProtectedServicesSnapshot(namespace: $namespace, services: $services) -} -`, + Query: ReportProtectedServicesSnapshot_Operation, Variables: &__ReportProtectedServicesSnapshotInput{ Namespace: namespace, Services: services, }, } - var err error + var err_ error - var data ReportProtectedServicesSnapshotResponse - resp := &graphql.Response{Data: &data} + var data_ ReportProtectedServicesSnapshotResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } -func dummy( - ctx context.Context, - client graphql.Client, -) (*dummyResponse, error) { - req := &graphql.Request{ - OpName: "dummy", - Query: ` +// The query or mutation executed by dummy. +const dummy_Operation = ` query dummy { dummyError } -`, +` + +func dummy( + ctx_ context.Context, + client_ graphql.Client, +) (*dummyResponse, error) { + req_ := &graphql.Request{ + OpName: "dummy", + Query: dummy_Operation, } - var err error + var err_ error - var data dummyResponse - resp := &graphql.Response{Data: &data} + var data_ dummyResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } diff --git a/src/shared/otterizecloud/graphqlclient/schema.graphql b/src/shared/otterizecloud/graphqlclient/schema.graphql index 697800496..9c6a3e91e 100644 --- a/src/shared/otterizecloud/graphqlclient/schema.graphql +++ b/src/shared/otterizecloud/graphqlclient/schema.graphql @@ -316,7 +316,6 @@ enum AutomateThirdPartyNetworkPolicy { enum AutomatedThirdPartyPolicyTypes { EXTERNAL_TRAFFIC METRICS_TRAFFIC - WEBHOOK_TRAFFIC } enum AwsIamStep { @@ -783,6 +782,8 @@ enum EdgeAccessStatusReason { ALLOWED_BY_EXTERNALLY_MANAGED_NETWORK_POLICY ALLOWED_BY_METRICS_COLLECTION_TRAFFIC_NETWORK_POLICY WOULD_BE_ALLOWED_BY_METRICS_COLLECTION_TRAFFIC_NETWORK_POLICY + ALLOWED_BY_WEBHOOK_TRAFFIC_NETWORK_POLICY + WOULD_BE_ALLOWED_BY_WEBHOOK_TRAFFIC_NETWORK_POLICY } enum EdgeAccessStatusVerdict { @@ -897,6 +898,7 @@ type FeatureFlags { enableInternetIntentsSuggestions: Boolean enableIAMIntentsSuggestions: Boolean enableNetworkPoliciesInAccessGraph: Boolean + enableTrafficFromTCPResolveDestBugfixInAccessGraph: Boolean } type Finding { @@ -1246,6 +1248,7 @@ input InputFeatureFlags { enableInternetIntentsSuggestions: Boolean enableIAMIntentsSuggestions: Boolean enableNetworkPoliciesInAccessGraph: Boolean + enableTrafficFromTCPResolveDestBugfixInAccessGraph: Boolean } """ Findings filter """ @@ -1607,6 +1610,7 @@ input IntentsOperatorConfigurationInput { automateThirdPartyNetworkPolicies: AutomateThirdPartyNetworkPolicy prometheusServerConfigs: [PrometheusServerConfigInput!] automatedThirdPartyPolicyTypes: [AutomatedThirdPartyPolicyTypes!] + automateAllowWebhookTraffic: AutomateThirdPartyNetworkPolicy } type IntentsOperatorState { @@ -1738,6 +1742,7 @@ input K8sResourceLoadBalancerIngressInput { input K8sResourceServiceInput { spec: K8sResourceServiceSpecInput! status: K8sResourceServiceStatusInput + targetNamedPorts: [NamedPortInput!] } input K8sResourceServiceLoadBalancerIngressInput { @@ -1801,9 +1806,7 @@ enum K8sServiceType { } input K8sWebhookServiceInput { - otterizeName: String! - serviceName: String! - namespace: String! + identity: ServiceIdentityInput! webhookName: String! webhookType: WebhookType! } @@ -2314,6 +2317,12 @@ type Mutation { ): Boolean! } +input NamedPortInput { + name: String! + port: Int! + protocol: K8sPortProtocol! +} + type Namespace { id: ID! name: String! @@ -2401,7 +2410,7 @@ enum NetworkPolicyScope { } type NetworkPolicyWorkload { - scope: NetworkPolicyScope! + scopes: [NetworkPolicyScope!]! service: Service! } @@ -2525,6 +2534,9 @@ type Query { accessGraphServices( filter: InputAccessGraphFilter ): [Service!]! + accessGraphNamespaces( + filter: InputAccessGraphFilter + ): [Namespace!]! serviceAccessGraph( id: ID! ): ServiceAccessGraph! @@ -2553,6 +2565,9 @@ type Query { clientServiceId: ID! serverServiceId: ID! ): [NetworkPolicy!]! + serviceNetworkPolicies( + serviceId: ID! + ): [NetworkPolicy!]! """ Get edge connections count """ edgeConnectionsCount( clientId: ID! @@ -3112,6 +3127,8 @@ scalar String type TLSConfiguration { caCertificate: String certificate: String + caCertificateFingerprint: String + certificateFingerprint: String } input TLSConfigurationInput { diff --git a/src/shared/telemetries/telemetriesgql/generated.go b/src/shared/telemetries/telemetriesgql/generated.go index ec7af741a..fcbc8930d 100644 --- a/src/shared/telemetries/telemetriesgql/generated.go +++ b/src/shared/telemetries/telemetriesgql/generated.go @@ -223,64 +223,70 @@ type __SendTelemetriesInput struct { // GetTelemetries returns __SendTelemetriesInput.Telemetries, and is useful for accessing the field via an interface. func (v *__SendTelemetriesInput) GetTelemetries() []TelemetryInput { return v.Telemetries } +// The query or mutation executed by ReportErrors. +const ReportErrors_Operation = ` +mutation ReportErrors ($component: Component!, $errors: [Error!]!) { + sendErrors(component: $component, errors: $errors) +} +` + func ReportErrors( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, component *Component, errors []*Error, ) (*ReportErrorsResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "ReportErrors", - Query: ` -mutation ReportErrors ($component: Component!, $errors: [Error!]!) { - sendErrors(component: $component, errors: $errors) -} -`, + Query: ReportErrors_Operation, Variables: &__ReportErrorsInput{ Component: component, Errors: errors, }, } - var err error + var err_ error - var data ReportErrorsResponse - resp := &graphql.Response{Data: &data} + var data_ ReportErrorsResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } +// The query or mutation executed by SendTelemetries. +const SendTelemetries_Operation = ` +mutation SendTelemetries ($telemetries: [TelemetryInput!]!) { + sendTelemetries(telemetries: $telemetries) +} +` + func SendTelemetries( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, telemetries []TelemetryInput, ) (*SendTelemetriesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "SendTelemetries", - Query: ` -mutation SendTelemetries ($telemetries: [TelemetryInput!]!) { - sendTelemetries(telemetries: $telemetries) -} -`, + Query: SendTelemetries_Operation, Variables: &__SendTelemetriesInput{ Telemetries: telemetries, }, } - var err error + var err_ error - var data SendTelemetriesResponse - resp := &graphql.Response{Data: &data} + var data_ SendTelemetriesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } diff --git a/src/shared/telemetries/telemetriesgql/schema.graphql b/src/shared/telemetries/telemetriesgql/schema.graphql index 697800496..9c6a3e91e 100644 --- a/src/shared/telemetries/telemetriesgql/schema.graphql +++ b/src/shared/telemetries/telemetriesgql/schema.graphql @@ -316,7 +316,6 @@ enum AutomateThirdPartyNetworkPolicy { enum AutomatedThirdPartyPolicyTypes { EXTERNAL_TRAFFIC METRICS_TRAFFIC - WEBHOOK_TRAFFIC } enum AwsIamStep { @@ -783,6 +782,8 @@ enum EdgeAccessStatusReason { ALLOWED_BY_EXTERNALLY_MANAGED_NETWORK_POLICY ALLOWED_BY_METRICS_COLLECTION_TRAFFIC_NETWORK_POLICY WOULD_BE_ALLOWED_BY_METRICS_COLLECTION_TRAFFIC_NETWORK_POLICY + ALLOWED_BY_WEBHOOK_TRAFFIC_NETWORK_POLICY + WOULD_BE_ALLOWED_BY_WEBHOOK_TRAFFIC_NETWORK_POLICY } enum EdgeAccessStatusVerdict { @@ -897,6 +898,7 @@ type FeatureFlags { enableInternetIntentsSuggestions: Boolean enableIAMIntentsSuggestions: Boolean enableNetworkPoliciesInAccessGraph: Boolean + enableTrafficFromTCPResolveDestBugfixInAccessGraph: Boolean } type Finding { @@ -1246,6 +1248,7 @@ input InputFeatureFlags { enableInternetIntentsSuggestions: Boolean enableIAMIntentsSuggestions: Boolean enableNetworkPoliciesInAccessGraph: Boolean + enableTrafficFromTCPResolveDestBugfixInAccessGraph: Boolean } """ Findings filter """ @@ -1607,6 +1610,7 @@ input IntentsOperatorConfigurationInput { automateThirdPartyNetworkPolicies: AutomateThirdPartyNetworkPolicy prometheusServerConfigs: [PrometheusServerConfigInput!] automatedThirdPartyPolicyTypes: [AutomatedThirdPartyPolicyTypes!] + automateAllowWebhookTraffic: AutomateThirdPartyNetworkPolicy } type IntentsOperatorState { @@ -1738,6 +1742,7 @@ input K8sResourceLoadBalancerIngressInput { input K8sResourceServiceInput { spec: K8sResourceServiceSpecInput! status: K8sResourceServiceStatusInput + targetNamedPorts: [NamedPortInput!] } input K8sResourceServiceLoadBalancerIngressInput { @@ -1801,9 +1806,7 @@ enum K8sServiceType { } input K8sWebhookServiceInput { - otterizeName: String! - serviceName: String! - namespace: String! + identity: ServiceIdentityInput! webhookName: String! webhookType: WebhookType! } @@ -2314,6 +2317,12 @@ type Mutation { ): Boolean! } +input NamedPortInput { + name: String! + port: Int! + protocol: K8sPortProtocol! +} + type Namespace { id: ID! name: String! @@ -2401,7 +2410,7 @@ enum NetworkPolicyScope { } type NetworkPolicyWorkload { - scope: NetworkPolicyScope! + scopes: [NetworkPolicyScope!]! service: Service! } @@ -2525,6 +2534,9 @@ type Query { accessGraphServices( filter: InputAccessGraphFilter ): [Service!]! + accessGraphNamespaces( + filter: InputAccessGraphFilter + ): [Namespace!]! serviceAccessGraph( id: ID! ): ServiceAccessGraph! @@ -2553,6 +2565,9 @@ type Query { clientServiceId: ID! serverServiceId: ID! ): [NetworkPolicy!]! + serviceNetworkPolicies( + serviceId: ID! + ): [NetworkPolicy!]! """ Get edge connections count """ edgeConnectionsCount( clientId: ID! @@ -3112,6 +3127,8 @@ scalar String type TLSConfiguration { caCertificate: String certificate: String + caCertificateFingerprint: String + certificateFingerprint: String } input TLSConfigurationInput {