/* * Copyright © 2020 Atomist, Inc. * * 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. */ import * as k8s from "@pulumi/kubernetes"; import * as pulumi from "@pulumi/pulumi"; import { specResourceName } from "./spec"; /** Arguments to network policy functions. */ export interface NetworkPolicyArgs { /** Kubernetes provider */ provider: k8s.Provider; /** * From rule for ingress. If not provided, a from rule that fits * the standard ingress-nginx deployment is used. */ from?: k8s.types.input.networking.v1.NetworkPolicyPeer; /** Optional name of resource to create. */ name?: string; /** Namespace to create resource in, defaults to "default". */ namespace?: string; /** * Options to use when creating the resources. The Kubernetes * provider will be automatically set as the provider. */ options?: pulumi.CustomResourceOptions; /** Pod selector to override default. */ podSelector?: k8s.types.input.networking.v1.NetworkPolicySpec["podSelector"]; } /** * Create a network policy that allows ingress from an ingress * controller. */ export function networkPolicyAllowFromIngressController( args: NetworkPolicyArgs, ): k8s.networking.v1.NetworkPolicy { const peer = args.from || { namespaceSelector: { matchLabels: { "app.kubernetes.io/name": "ingress-nginx", }, }, podSelector: { matchLabels: { "app.kubernetes.io/component": "controller", "app.kubernetes.io/name": "ingress-nginx", }, }, }; const podSelector = args.podSelector || {}; return createNetworkPolicy({ name: args.name || "allow-from-ingress", namespace: args.namespace, options: args.options, provider: args.provider, spec: { ingress: [ { from: [peer], }, ], podSelector, }, }); } /** * Create a network policy that allows ingress to an ingress * controller. */ export function networkPolicyAllowToIngressController( args: NetworkPolicyArgs, ): k8s.networking.v1.NetworkPolicy { const peer = args.from || { ipBlock: { cidr: "0.0.0.0/0", }, }; const podSelector = args.podSelector || { matchLabels: { "app.kubernetes.io/component": "controller", "app.kubernetes.io/name": "ingress-nginx", }, }; return createNetworkPolicy({ name: args.name || "allow-to-ingress", namespace: args.namespace, options: args.options, provider: args.provider, spec: { ingress: [ { from: [peer], }, ], podSelector, }, }); } /** * Create a network policy that allows ingress from pods within the * same namespaces but denies ingress from pods in other namespaces. */ export function networkPolicyDenyFromOtherNamespaces( args: NetworkPolicyArgs, ): k8s.networking.v1.NetworkPolicy { const peer = args.from || { podSelector: {} }; const podSelector = args.podSelector || {}; return createNetworkPolicy({ name: args.name || "deny-from-other-namespaces", namespace: args.namespace, options: args.options, provider: args.provider, spec: { ingress: [ { from: [peer], }, ], podSelector, }, }); } /** Arguments to [[createNetworkPolicy]]. */ interface CreateNetworkPolicyArgs extends Required>, Pick { /** * Network policy spec property. By default `podSelector` is set * to `{}`, i.e., matching all pods. This will be overriden by any * value provided in the spec. */ spec: k8s.types.input.networking.v1.NetworkPolicySpec; } /** * Create a network policy. */ function createNetworkPolicy( args: CreateNetworkPolicyArgs, ): k8s.networking.v1.NetworkPolicy { const spec = { apiVersion: "networking.k8s.io/v1" as const, kind: "NetworkPolicy" as const, metadata: { name: args.name, namespace: args.namespace || "default", }, spec: { ...args.spec, podSelector: args.spec?.podSelector || {}, }, }; const resource = specResourceName(spec); if (!resource) { throw new Error( `Provided network policy spec is not complete: ${JSON.stringify( args.spec, )}`, ); } const options = { ...args.options, provider: args.provider }; return new k8s.networking.v1.NetworkPolicy(resource, spec, options); }