diff --git a/bundle/manifests/ibm-websphere-liberty.clusterserviceversion.yaml b/bundle/manifests/ibm-websphere-liberty.clusterserviceversion.yaml index d5c7645a..aaac2f13 100644 --- a/bundle/manifests/ibm-websphere-liberty.clusterserviceversion.yaml +++ b/bundle/manifests/ibm-websphere-liberty.clusterserviceversion.yaml @@ -869,6 +869,7 @@ spec: app.kubernetes.io/managed-by: olm app.kubernetes.io/name: websphere-liberty-operator control-plane: controller-manager + webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access: "true" spec: affinity: nodeAffinity: @@ -1033,6 +1034,13 @@ spec: - list - update - watch + - apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 9b837ea2..b8528588 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -21,6 +21,7 @@ spec: metadata: labels: control-plane: controller-manager + webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access: "true" annotations: productID: "cb1747ecb831410f88006195f024183f" productName: "WebSphere Liberty Operator" diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index 58d463a6..60b58b9c 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -7,6 +7,7 @@ resources: - ../scorecard patchesStrategicMerge: - patches/csvAnnotations.yaml + - patches/apiServerAccessPatch.yaml patches: - path: serviceBindingPatch.yaml target: diff --git a/config/manifests/patches/apiServerAccessPatch.yaml b/config/manifests/patches/apiServerAccessPatch.yaml new file mode 100644 index 00000000..7846957f --- /dev/null +++ b/config/manifests/patches/apiServerAccessPatch.yaml @@ -0,0 +1,14 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + name: ibm-websphere-liberty.v0.0.0 + namespace: placeholder +spec: + install: + spec: + deployments: + - spec: + template: + metadata: + labels: + webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access: "true" \ No newline at end of file diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 81858a0b..c26f12b0 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -73,6 +73,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/controllers/ltpa_keys_sharing.go b/controllers/ltpa_keys_sharing.go index 293d6a77..bd84d080 100644 --- a/controllers/ltpa_keys_sharing.go +++ b/controllers/ltpa_keys_sharing.go @@ -231,7 +231,7 @@ func (r *ReconcileWebSphereLiberty) generateLTPAKeys(instance *wlv1.WebSphereLib err = r.GetClient().Get(context.TODO(), types.NamespacedName{Name: generateLTPAKeysJob.Name, Namespace: generateLTPAKeysJob.Namespace}, generateLTPAKeysJob) if err != nil && kerrors.IsNotFound(err) { err = r.CreateOrUpdate(generateLTPAKeysJob, instance, func() error { - lutils.CustomizeLTPAJob(generateLTPAKeysJob, instance, ltpaSecret.Name, ltpaServiceAccountName, ltpaKeysCreationScriptConfigMap.Name) + lutils.CustomizeLTPAJob(generateLTPAKeysJob, instance, ltpaSecret.Name, ltpaServiceAccountName, ltpaKeysCreationScriptConfigMap.Name, OperatorAllowAPIServerAccessLabel) return nil }) if err != nil { diff --git a/controllers/webspherelibertyapplication_controller.go b/controllers/webspherelibertyapplication_controller.go index f48be5da..63902178 100644 --- a/controllers/webspherelibertyapplication_controller.go +++ b/controllers/webspherelibertyapplication_controller.go @@ -43,6 +43,7 @@ import ( kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" servingv1 "knative.dev/serving/pkg/apis/serving/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" @@ -54,8 +55,9 @@ import ( ) const ( - OperatorName = "websphere-liberty-operator" - OperatorShortName = "wlo" + OperatorName = "websphere-liberty-operator" + OperatorShortName = "wlo" + OperatorAllowAPIServerAccessLabel = "webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access" ) // ReconcileWebSphereLiberty reconciles a WebSphereLibertyApplication object @@ -74,6 +76,7 @@ const applicationFinalizer = "finalizer.webspherelibertyapps.liberty.websphere.i // +kubebuilder:rbac:groups=apps,resources=deployments;statefulsets,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator // +kubebuilder:rbac:groups=apps,resources=deployments/finalizers;statefulsets,verbs=update,namespace=websphere-liberty-operator // +kubebuilder:rbac:groups=core,resources=services;secrets;serviceaccounts;configmaps;persistentvolumeclaims,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator +// +kubebuilder:rbac:groups=core,resources=endpoints,verbs=get;list,namespace=websphere-liberty-operator // +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator // +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator // +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=get;list;watch;create;update;delete,namespace=websphere-liberty-operator @@ -399,6 +402,72 @@ func (r *ReconcileWebSphereLiberty) Reconcile(ctx context.Context, request ctrl. common.StatusConditionTypeReconciled, instance) } + // Kube API Server NetworkPolicy (based upon impl. by Martin Smithson) + apiServerNetworkPolicy := &networkingv1.NetworkPolicy{ObjectMeta: metav1.ObjectMeta{ + Name: instance.Name + "-egress-dns-and-apiserver-access", + Namespace: instance.Namespace, + }} + err = r.CreateOrUpdate(apiServerNetworkPolicy, instance, func() error { + apiServerNetworkPolicy.Spec.PodSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + OperatorAllowAPIServerAccessLabel: "true", + }, + } + apiServerNetworkPolicy.Spec.Egress = make([]networkingv1.NetworkPolicyEgressRule, 0) + + var dnsRule networkingv1.NetworkPolicyEgressRule + var usingPermissiveRule bool + // If allowed, add an Egress rule to access the OpenShift DNS or K8s CoreDNS. Otherwise, use a permissive cluster-wide Egress rule. + if r.IsOpenShift() { + usingPermissiveRule, dnsRule = r.getDNSEgressRule(reqLogger, "dns-default", "openshift-dns") + } else { + usingPermissiveRule, dnsRule = r.getDNSEgressRule(reqLogger, "kube-dns", "kube-system") + } + apiServerNetworkPolicy.Spec.Egress = append(apiServerNetworkPolicy.Spec.Egress, dnsRule) + + // If the DNS rule is a specific Egress rule also check if another Egress rule can be created for the API server. + // Otherwise, fallback to a permissive cluster-wide Egress rule. + if !usingPermissiveRule { + if apiServerEndpoints, err := r.getEndpoints("kubernetes", "default"); err == nil { + rule := networkingv1.NetworkPolicyEgressRule{} + // Define the port + port := networkingv1.NetworkPolicyPort{} + port.Protocol = &apiServerEndpoints.Subsets[0].Ports[0].Protocol + var portNumber intstr.IntOrString = intstr.FromInt((int)(apiServerEndpoints.Subsets[0].Ports[0].Port)) + port.Port = &portNumber + rule.Ports = append(rule.Ports, port) + + // Add the endpoint address as ipBlock entries + for _, endpoint := range apiServerEndpoints.Subsets { + for _, address := range endpoint.Addresses { + peer := networkingv1.NetworkPolicyPeer{} + ipBlock := networkingv1.IPBlock{} + ipBlock.CIDR = address.IP + "/32" + + peer.IPBlock = &ipBlock + rule.To = append(rule.To, peer) + } + } + apiServerNetworkPolicy.Spec.Egress = append(apiServerNetworkPolicy.Spec.Egress, rule) + reqLogger.Info("Found endpoints for kubernetes service in the default namespace") + } else { + // The operator couldn't create a rule for the K8s API server so add a permissive Egress rule + rule := networkingv1.NetworkPolicyEgressRule{} + apiServerNetworkPolicy.Spec.Egress = append(apiServerNetworkPolicy.Spec.Egress, rule) + reqLogger.Info("Found endpoints for kubernetes service in the default namespace") + } + } + + apiServerNetworkPolicy.Labels = ba.GetLabels() + apiServerNetworkPolicy.Annotations = oputils.MergeMaps(apiServerNetworkPolicy.Annotations, ba.GetAnnotations()) + apiServerNetworkPolicy.Spec.PolicyTypes = []networkingv1.PolicyType{networkingv1.PolicyTypeEgress} + return nil + }) + if err != nil { + reqLogger.Error(err, "Failed to reconcile API server network policy") + return r.ManageError(err, common.StatusConditionTypeReconciled, instance) + } + networkPolicy := &networkingv1.NetworkPolicy{ObjectMeta: defaultMeta} if np := instance.Spec.NetworkPolicy; np == nil || np != nil && !np.IsDisabled() { err = r.CreateOrUpdate(networkPolicy, instance, func() error { @@ -874,3 +943,40 @@ func (r *ReconcileWebSphereLiberty) deletePVC(reqLogger logr.Logger, pvcName str } } } + +func (r *ReconcileWebSphereLiberty) getEndpoints(serviceName string, namespace string) (*corev1.Endpoints, error) { + endpoints := &corev1.Endpoints{} + if err := r.GetClient().Get(context.TODO(), types.NamespacedName{Name: serviceName, Namespace: namespace}, endpoints); err != nil { + return nil, err + } else { + return endpoints, nil + } +} + +func (r *ReconcileWebSphereLiberty) getDNSEgressRule(reqLogger logr.Logger, endpointsName string, endpointsNamespace string) (bool, networkingv1.NetworkPolicyEgressRule) { + dnsRule := networkingv1.NetworkPolicyEgressRule{} + if dnsEndpoints, err := r.getEndpoints(endpointsName, endpointsNamespace); err == nil { + if len(dnsEndpoints.Subsets) > 0 { + if endpointPort := lutils.GetEndpointPortByName(&dnsEndpoints.Subsets[0].Ports, "dns"); endpointPort != nil { + dnsRule.Ports = append(dnsRule.Ports, lutils.CreateNetworkPolicyPortFromEndpointPort(endpointPort)) + } + if endpointPort := lutils.GetEndpointPortByName(&dnsEndpoints.Subsets[0].Ports, "dns-tcp"); endpointPort != nil { + dnsRule.Ports = append(dnsRule.Ports, lutils.CreateNetworkPolicyPortFromEndpointPort(endpointPort)) + } + } + peer := networkingv1.NetworkPolicyPeer{} + peer.NamespaceSelector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "kubernetes.io/metadata.name": endpointsNamespace, + }, + } + dnsRule.To = append(dnsRule.To, peer) + reqLogger.Info("Found endpoints for " + endpointsName + " service in the " + endpointsNamespace + " namespace") + return false, dnsRule + } + // use permissive rule + // egress: + // - {} + reqLogger.Info("Failed to retrieve endpoints for " + endpointsName + " service in the " + endpointsNamespace + " namespace. Using more permissive rule.") + return true, dnsRule +} diff --git a/go.mod b/go.mod index 46745406..c7c459aa 100644 --- a/go.mod +++ b/go.mod @@ -28,14 +28,14 @@ require ( github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/zapr v1.2.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.6.9 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.13.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect @@ -48,6 +48,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.9.4 // indirect + github.com/onsi/gomega v1.27.6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect diff --git a/go.sum b/go.sum index 1834c3e8..2c671980 100644 --- a/go.sum +++ b/go.sum @@ -69,6 +69,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -107,15 +108,15 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -162,8 +163,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.13.0 h1:y1C7Z3e149OJbOPDBxLYR8ITPz8dTKqQwjErKVHJC8k= github.com/google/go-containerregistry v0.13.0/go.mod h1:J9FQ+eSS4a1aC2GNZxvNpbWhgp0487v+cgiilB4FqDo= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -178,6 +179,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -209,14 +212,13 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -233,10 +235,10 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q= -github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= -github.com/onsi/gomega v1.24.2/go.mod h1:gs3J10IS7Z7r7eXRoNJIrNqU4ToQukCJhFtKrWgHWnk= +github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= +github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM= +github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/openshift/api v0.0.0-20230928134114-673ed0cfc7f1 h1:5OVTkr6byE1VpQfZcY9tXZin6Mpjkq9+QfFtrgyGXXA= @@ -274,11 +276,15 @@ 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/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -501,8 +507,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/deploy/kubectl/websphereliberty-app-operator.yaml b/internal/deploy/kubectl/websphereliberty-app-operator.yaml index 0f29b662..4e8f3dec 100644 --- a/internal/deploy/kubectl/websphereliberty-app-operator.yaml +++ b/internal/deploy/kubectl/websphereliberty-app-operator.yaml @@ -112,6 +112,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: @@ -300,6 +307,7 @@ spec: app.kubernetes.io/instance: websphere-liberty-operator app.kubernetes.io/name: websphere-liberty-operator control-plane: controller-manager + webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access: "true" spec: affinity: nodeAffinity: diff --git a/internal/deploy/kubectl/websphereliberty-app-rbac-watch-all.yaml b/internal/deploy/kubectl/websphereliberty-app-rbac-watch-all.yaml index c450836c..c4b4215a 100644 --- a/internal/deploy/kubectl/websphereliberty-app-rbac-watch-all.yaml +++ b/internal/deploy/kubectl/websphereliberty-app-rbac-watch-all.yaml @@ -104,6 +104,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/internal/deploy/kubectl/websphereliberty-app-rbac-watch-another.yaml b/internal/deploy/kubectl/websphereliberty-app-rbac-watch-another.yaml index c76a7917..30b4e9f9 100644 --- a/internal/deploy/kubectl/websphereliberty-app-rbac-watch-another.yaml +++ b/internal/deploy/kubectl/websphereliberty-app-rbac-watch-another.yaml @@ -106,6 +106,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/internal/deploy/kustomize/daily/base/websphere-liberty-deployment.yaml b/internal/deploy/kustomize/daily/base/websphere-liberty-deployment.yaml index 715f690c..bc41cb83 100644 --- a/internal/deploy/kustomize/daily/base/websphere-liberty-deployment.yaml +++ b/internal/deploy/kustomize/daily/base/websphere-liberty-deployment.yaml @@ -26,6 +26,7 @@ spec: app.kubernetes.io/instance: websphere-liberty-operator app.kubernetes.io/name: websphere-liberty-operator control-plane: websphere-liberty-controller-manager + webspherelibertyapps.liberty.websphere.ibm.com/allow-apiserver-access: "true" spec: affinity: nodeAffinity: diff --git a/internal/deploy/kustomize/daily/base/websphere-liberty-roles.yaml b/internal/deploy/kustomize/daily/base/websphere-liberty-roles.yaml index e2569f79..a92e9f17 100644 --- a/internal/deploy/kustomize/daily/base/websphere-liberty-roles.yaml +++ b/internal/deploy/kustomize/daily/base/websphere-liberty-roles.yaml @@ -115,6 +115,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/internal/deploy/kustomize/daily/overlays/watch-all-namespaces/cluster-roles.yaml b/internal/deploy/kustomize/daily/overlays/watch-all-namespaces/cluster-roles.yaml index 980cd5a4..98a19755 100644 --- a/internal/deploy/kustomize/daily/overlays/watch-all-namespaces/cluster-roles.yaml +++ b/internal/deploy/kustomize/daily/overlays/watch-all-namespaces/cluster-roles.yaml @@ -104,6 +104,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/internal/deploy/kustomize/daily/overlays/watch-another-namespace/wlo-watched-ns/watched-roles.yaml b/internal/deploy/kustomize/daily/overlays/watch-another-namespace/wlo-watched-ns/watched-roles.yaml index 9a76fe25..be60f2f9 100644 --- a/internal/deploy/kustomize/daily/overlays/watch-another-namespace/wlo-watched-ns/watched-roles.yaml +++ b/internal/deploy/kustomize/daily/overlays/watch-another-namespace/wlo-watched-ns/watched-roles.yaml @@ -106,6 +106,13 @@ rules: - list - update - watch +- apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - list - apiGroups: - "" resources: diff --git a/utils/utils.go b/utils/utils.go index 665b2b92..da3ef373 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -25,6 +25,8 @@ import ( "strconv" "strings" + networkingv1 "k8s.io/api/networking/v1" + wlv1 "github.com/WASdev/websphere-liberty-operator/api/v1" rcoutils "github.com/application-stacks/runtime-component-operator/utils" routev1 "github.com/openshift/api/route/v1" @@ -34,6 +36,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -700,9 +703,11 @@ func IsLTPAJobConfigurationOutdated(job *v1.Job, appLeaderInstance *wlv1.WebSphe return false } -func CustomizeLTPAJob(job *v1.Job, la *wlv1.WebSphereLibertyApplication, ltpaSecretName string, serviceAccountName string, ltpaScriptName string) { +func CustomizeLTPAJob(job *v1.Job, la *wlv1.WebSphereLibertyApplication, ltpaSecretName string, serviceAccountName string, ltpaScriptName string, allowAPIServerAccessLabel string) { encodingType := "aes" // the password encoding type for securityUtility (one of "xor", "aes", or "hash") job.Spec.Template.ObjectMeta.Name = "liberty" + // Enable NetworkPolicy Egress access to Kube API Server + job.Spec.Template.Labels = rcoutils.MergeMaps(job.Spec.Template.Labels, map[string]string{allowAPIServerAccessLabel: "true"}) job.Spec.Template.Spec.Containers = []corev1.Container{ { Name: job.Spec.Template.ObjectMeta.Name, @@ -769,3 +774,22 @@ func GetRequiredLabels(name string, instance string) map[string]string { requiredLabels["app.kubernetes.io/managed-by"] = "websphere-liberty-operator" return requiredLabels } + +func GetEndpointPortByName(endpointPorts *[]corev1.EndpointPort, name string) *corev1.EndpointPort { + if endpointPorts != nil { + for _, endpointPort := range *endpointPorts { + if endpointPort.Name == name { + return &endpointPort + } + } + } + return nil +} + +func CreateNetworkPolicyPortFromEndpointPort(endpointPort *corev1.EndpointPort) networkingv1.NetworkPolicyPort { + port := networkingv1.NetworkPolicyPort{} + port.Protocol = &endpointPort.Protocol + var portNumber intstr.IntOrString = intstr.FromInt((int)(endpointPort.Port)) + port.Port = &portNumber + return port +}