diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4354e73..e105434 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,7 @@ env: REGISTRY_NAME: k8scc01covidacr TRIVY_VERSION: "v0.43.1" SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + HADOLINT_VERSION: "2.12.0" jobs: build: @@ -32,6 +33,12 @@ jobs: steps: - uses: actions/checkout@master + - name: Run Hadolint + run: | + sudo curl -L https://github.com/hadolint/hadolint/releases/download/v${{ env.HADOLINT_VERSION }}/hadolint-Linux-x86_64 --output hadolint + sudo chmod +x hadolint + ./hadolint ./Dockerfile --no-fail + # Container build - run: | docker build -f Dockerfile -t localhost:5000/profiles-controller:${{ github.sha }} . @@ -46,16 +53,6 @@ jobs: curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin ${{ env.TRIVY_VERSION }} trivy image localhost:5000/profiles-controller:${{ github.sha }} --exit-code 1 --timeout=20m --security-checks vuln --severity CRITICAL - # Run Dockle - - name: Run dockle - uses: goodwithtech/dockle-action@main - with: - image: localhost:5000/profiles-controller:${{ github.sha }} - format: 'list' - exit-code: '1' - exit-level: 'fatal' - ignore: 'DKL-DI-0006' - - name: Slack Notification if: failure() && github.event_name=='schedule' uses: act10ns/slack@v1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f730474..5029f55 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,11 +14,13 @@ on: push: branches: - profiles-controller-aaw2.0 + pull_request: # Environment variables available to all jobs and steps in this workflow env: REGISTRY_NAME: k8scc01covidacr TRIVY_VERSION: "v0.43.1" + HADOLINT_VERSION: "2.12.0" jobs: build: runs-on: ubuntu-latest @@ -37,6 +39,12 @@ jobs: username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} + - name: Run Hadolint + run: | + sudo curl -L https://github.com/hadolint/hadolint/releases/download/v${{ env.HADOLINT_VERSION }}/hadolint-Linux-x86_64 --output hadolint + sudo chmod +x hadolint + ./hadolint ./Dockerfile --no-fail + # Container build and push to a Azure Container registry (ACR) - name: Build image run: | @@ -51,16 +59,6 @@ jobs: printf ${{ secrets.CVE_ALLOWLIST }} > .trivyignore curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin ${{ env.TRIVY_VERSION }} trivy image localhost:5000/profiles-controller-aaw2:${{ github.sha }} --exit-code 0 --timeout=20m --security-checks vuln --severity CRITICAL - - # Run Dockle - - name: Run dockle - uses: goodwithtech/dockle-action@main - with: - image: localhost:5000/profiles-controller-aaw2:${{ github.sha }} - format: 'list' - exit-code: '1' - exit-level: 'fatal' - ignore: 'DKL-DI-0006' # Push if passed scanning - name: Push image to registry diff --git a/cmd/network.go b/cmd/network.go index 0ce50e9..ec64291 100644 --- a/cmd/network.go +++ b/cmd/network.go @@ -166,8 +166,21 @@ func generateNetworkPolicies(profile *kubeflowv1.Profile) []*networkingv1.Networ protocolTCP := corev1.ProtocolTCP portNotebook := intstr.FromString("notebook-port") + portSQL := intstr.FromInt(1433) + portOracle := intstr.FromInt(1522) + portHTTPS := intstr.FromInt(443) + + // Define the notebook PodSelector + notebookPodSelector := metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "notebook-name", + Operator: metav1.LabelSelectorOpExists, + }, + }, + } - // Allow kubeflow to notebooks + // Allow Kubeflow system to access notebooks policies = append(policies, &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "notebooks-allow-system-to-notebook", @@ -177,14 +190,7 @@ func generateNetworkPolicies(profile *kubeflowv1.Profile) []*networkingv1.Networ }, }, Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "notebook-name", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, + PodSelector: notebookPodSelector, PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeIngress}, Ingress: []networkingv1.NetworkPolicyIngressRule{ { @@ -209,7 +215,6 @@ func generateNetworkPolicies(profile *kubeflowv1.Profile) []*networkingv1.Networ }) // Allow egress to 443 from notebooks - portHTTPS := intstr.FromInt(443) policies = append(policies, &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "notebooks-allow-https-egress", @@ -219,14 +224,7 @@ func generateNetworkPolicies(profile *kubeflowv1.Profile) []*networkingv1.Networ }, }, Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "notebook-name", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, + PodSelector: notebookPodSelector, PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress}, Egress: []networkingv1.NetworkPolicyEgressRule{ { @@ -248,7 +246,7 @@ func generateNetworkPolicies(profile *kubeflowv1.Profile) []*networkingv1.Networ }, }) - // allow ingress from kubeflow + // Allow ingress from Kubeflow gateway policies = append(policies, &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "allow-ingress-kubeflow-gateway", @@ -275,9 +273,64 @@ func generateNetworkPolicies(profile *kubeflowv1.Profile) []*networkingv1.Networ }, }) +// Allow egress to SQL Server from notebooks +policies = append(policies, &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allow-sql-egress", + Namespace: profile.Name, + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: notebookPodSelector, + PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress}, + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Protocol: &protocolTCP, + Port: &portSQL, + }, + }, + To: []networkingv1.NetworkPolicyPeer{ + { + NamespaceSelector: &metav1.LabelSelector{}, // Allow to all namespaces + }, + }, + }, + }, + }, +}) + +// Allow egress to Oracle from notebooks +policies = append(policies, &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allow-oracle-egress", + Namespace: profile.Name, + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: notebookPodSelector, + PolicyTypes: []networkingv1.PolicyType{networkingv1.PolicyTypeEgress}, + Egress: []networkingv1.NetworkPolicyEgressRule{ + { + Ports: []networkingv1.NetworkPolicyPort{ + { + Protocol: &protocolTCP, + Port: &portOracle, + }, + }, + To: []networkingv1.NetworkPolicyPeer{ + { + NamespaceSelector: &metav1.LabelSelector{}, // Allow to all namespaces + }, + }, + }, + }, + }, +}) + return policies } + func init() { rootCmd.AddCommand(networkCmd) }