diff --git a/README.md b/README.md index de4582f1eef..d6393a0f36b 100644 --- a/README.md +++ b/README.md @@ -2,70 +2,111 @@ This repo is a [bespoke configuration](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#bespoke-configuration) of kustomize targets used by kubeflow. These targets are traversed by kubeflow's CLI `kfctl`. Each target is compatible with the kustomize CLI and can be processed indendently by kubectl or the kustomize command. ## Organization -Various subdirectories within the repo contain a kustomize target (base or overlay subdirectory). Currently overlays hold platform resources where platform is one of "gcp|minikube". These targets are processed by kfctl during generate and apply phases and is detailed in [Kfctl Processing](#kfctl-processing). +Various subdirectories within the repo contain a kustomize target (base or overlay subdirectory). Overlays are used for a variety of purposes such as platform resources. Both base and overlay targets are processed by kfctl during generate and apply phases and is detailed in [Kfctl Processing](#kfctl-processing). ### Kustomize targets (🎯) ``` -πŸ“¦ application βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ argo βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ common ⇲ - βŽΉβ†’πŸ—³ common/ambassador/base(🎯) - βŽΉβ†’πŸ—³ common/centraldashboard/base(🎯) - βŽΉβ†’πŸ—³ common/spartakus/base(🎯) -πŸ“¦ gcp ⇲ - βŽΉβ†’πŸ—³ gcp/cert-manager/overlays/gcp(🎯) - βŽΉβ†’πŸ—³ gcp/cloud-endpoints/overlays/gcp(🎯) - βŽΉβ†’πŸ—³ gcp/gcp-credentials-admission-webhook/overlays/gcp(🎯) - βŽΉβ†’πŸ—³ gcp/gpu-driver/overlays/gcp(🎯) - βŽΉβ†’πŸ—³ gcp/iap-ingress/overlays/gcp(🎯) -πŸ“¦ jupyter ⇲ - βŽΉβ†’πŸ—³ jupyter/jupyter-web-app/base(🎯) - βŽΉβ†’πŸ—³ jupyter/jupyter/base(🎯) - βŽΉβ†’πŸ—³ jupyter/jupyter/overlays/minikube(🎯) - βŽΉβ†’πŸ—³ jupyter/notebook-controller/base(🎯) -πŸ“¦ katib βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ kubebench βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ metacontroller βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ modeldb βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ mutating-webhook βŽΉβ†’πŸ—³ base(🎯) - βŽΉβ†’πŸ—³ mutating-webhook/overlays/add-label(🎯) -πŸ“¦ pipeline ⇲ - βŽΉβ†’πŸ—³ pipeline/api-service/base(🎯) - βŽΉβ†’πŸ—³ pipeline/minio/base(🎯) - βŽΉβ†’πŸ—³ pipeline/mysql/base(🎯) - βŽΉβ†’πŸ—³ pipeline/persistent-agent/base(🎯) - βŽΉβ†’πŸ—³ pipeline/pipelines-runner/base(🎯) - βŽΉβ†’πŸ—³ pipeline/pipelines-ui/base(🎯) - βŽΉβ†’πŸ—³ pipeline/pipelines-viewer/base(🎯) - βŽΉβ†’πŸ—³ pipeline/scheduledworkflow/base(🎯) -πŸ“¦ profiles βŽΉβ†’πŸ—³ base(🎯) - βŽΉβ†’πŸ—³ profiles/overlays/debug(🎯) - βŽΉβ†’πŸ—³ profiles/overlays/devices(🎯) -πŸ“¦ pytorch-job ⇲ - βŽΉβ†’πŸ—³ pytorch-job/pytorch-operator/base(🎯) -πŸ“¦ tensorboard βŽΉβ†’πŸ—³ base(🎯) -πŸ“¦ tf-training ⇲ - βŽΉβ†’πŸ—³ tf-training/tf-job-operator/base(🎯) +. +β”œβ”€β”€ application +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ argo +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ common +β”‚Β Β  β”œβ”€β”€ ambassador +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ centraldashboard +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  └── spartakus +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€πŸŽ―gcp +β”‚Β Β  β”œβ”€β”€ cert-manager +β”‚Β Β  β”‚Β Β  └── overlays +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―gcp +β”‚Β Β  β”œβ”€β”€ cloud-endpoints +β”‚Β Β  β”‚Β Β  └── overlays +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―gcp +β”‚Β Β  β”œβ”€πŸŽ―gcp-credentials-admission-webhook +β”‚Β Β  β”‚Β Β  └── overlays +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―gcp +β”‚Β Β  β”œβ”€β”€ gpu-driver +β”‚Β Β  β”‚Β Β  └── overlays +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―gcp +β”‚Β Β  └── iap-ingress +β”‚Β Β  └── overlays +β”‚Β Β  β””β”€πŸŽ―gcp +β”œβ”€β”€ jupyter +β”‚Β Β  β”œβ”€β”€ jupyter +β”‚Β Β  β”‚Β Β  β”œβ”€πŸŽ―base +β”‚Β Β  β”‚Β Β  └── overlays +β”‚Β Β  β”‚Β Β  └── minikube +β”‚Β Β  β”œβ”€β”€ jupyter-web-app +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  └── notebook-controller +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ katib +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ kubebench +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ metacontroller +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ modeldb +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ mutating-webhook +β”‚Β Β  β”œβ”€πŸŽ―base +β”‚Β Β  └── overlays +β”‚Β Β  └── add-label +β”œβ”€β”€ pipeline +β”‚Β Β  β”œβ”€β”€ api-service +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ minio +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ mysql +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ persistent-agent +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ pipelines-runner +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ pipelines-ui +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  β”œβ”€β”€ pipelines-viewer +β”‚Β Β  β”‚Β Β  β””β”€πŸŽ―base +β”‚Β Β  └── scheduledworkflow +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ profiles +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ pytorch-job +β”‚Β Β  └── pytorch-operator +β”‚Β Β  β””β”€πŸŽ―base +β”œβ”€β”€ tensorboard +β”‚Β Β  β””β”€πŸŽ―base +└── tf-training + └── tf-job-operator + β”œβ”€πŸŽ―base + └── overlays + β”œβ”€β”€ 🎯cluster + β”œβ”€β”€ 🎯cluster-gangscheduled + β”œβ”€β”€ 🎯namespaced + └── 🎯namespaced-gangscheduled ``` ## Kfctl Processing -Kfctl will traverse these directories to find and build kustomize targets based on the configuration file `app.yaml`. App.yaml is derived from a file in the kubeflow [config](https://github.com/kubeflow/kubeflow/tree/master/bootstrap/config) directory. Each target processed by kfctl will result in an output yaml file. The output file is generated by calling kustomize's API. The kustomize package manager in kfctl will read app.yaml and apply the packages, components and componentParams to kustomize in the following way: +Kfctl traverses directories under manifests to find and build kustomize targets based on the configuration file `app.yaml`. The contents of app.yaml is the result of running kustomize on the base and specific overlays in the kubeflow [config](https://github.com/kubeflow/kubeflow/tree/master/bootstrap/config) directory. The overlays reflect what options are chosen when calling `kfctl init...`. The kustomize package manager in kfctl will then read app.yaml and apply the packages, components and componentParams to kustomize in the following way: -- **πŸ“¦ packages** +- **packages** - are always top-level directories under the manifests repo -- **πŸ—³ components** +- **components** - are also directories but may be a subdirectory in a package. - - components may also be a top-level directory if there is a base or overlay in that directory in which case the component name is equal to the package name. - - otherwise a component is a sub-directory + - a component may also be a package if there is a base or overlay in the top level directory. + - otherwise a component is a sub-directory under the package directory. - in all cases a component's name in app.yaml must match the directory name. - components are output as `.yaml` under the kustomize subdirectory during `kfctl generate...`. - - in order to output a component, a synthetic kustomization.yaml is created under manifests that sets common parameters and labels that looks like + - in order to output a component, a kustomization.yaml is created above the base or overlay directory and inherits common parameters, namespace and labels of the base or overlay. Additionally it adds the namespace and an application label. ``` apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - - /{base|overlay/} + - /{base|overlay/} commonLabels: app.kubernetes.io/name: namespace: @@ -74,10 +115,74 @@ namespace: - **component parameters** - are applied to a component's params.env file. There must be an entry whose key matches the component parameter. The params.env file is used to generate a ConfigMap. Entries in params.env are resolved as kustomize vars or referenced in a deployment or statefulset env section in which case no var definition is needed. +Multiple overlays - -Generating yaml output for any target can be done in the following way: +Kfctl has the capability to combine more than one overlay during `kfctl generate ...`. An example is shown below where the profiles target in [manifests](https://github.com/kubeflow/manifests/tree/master/profiles) can include either debug changes in the Deployment or Device information in the Namespace (the devices overlay is not fully integrated with the Profile-controller at this point in time and is intended as an example) or **both**. -### Install kustomize +``` +profiles +β”œβ”€β”€ base +β”‚Β Β  └── kustomization.yaml +└── overlays + β”œβ”€β”€ debug + β”‚Β Β  └── kustomization.yaml + └── devices + └── kustomization.yaml +``` + +#### What are Multiple Overlays? + +Normally kustomize provides the ability to overlay a 'base' set of resources with changes that are merged into the base from resources that are located under an overlays subdirectory. For example +if the kustomize [target](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#target) is named foo there will be a foo/base and possibly one or more overlays such as foo/overlays/bar. A kustomization.yaml file is found in both foo/base and foo/overlays/bar. Running `kustomize build` in foo/base will generate resources as defined in kustomization.yaml. Running `kustomize build` in foo/overlays/bar will generate resources - some of which will overlay the resources in foo/base. + +Kustomize doesn't provide for an easy way to combine more than one overlay for example foo/overlays/bar, foo/overlays/baz. However this is an open feature request in kustomize [issues](https://github.com/kubernetes-sigs/kustomize/issues/759). The ability to combine more than one overlay is key to handling components like tf-job-operator which has several types of overlays that can 'mix-in' whether a TFJob is submitted to a namespace or cluster-wide and whether the TFJob uses gang-scheduling. + +#### Merging multiple overlays + +Since each overlay includes '../../base' as its base set of resources - combining several overlays where each includes '../../base' will cause `kustomize build` to abort, complaining that it recursed on base. The approach is to create a kustomization.yaml at the target level that includes base and the contents of each overlay's kustomization file. This requires some path corrections and some awareness of the behavior of configMapGenerator, secretMapGenerator and how they are copied from each overlay. This kustomization.yaml can be constructed manually, but is integrated within kfctl via the app.yaml file. Using tf-job-operator as an example, if its componentParams has the following +``` + componentParams: + tf-job-operator: + - name: overlay + value: cluster + - name: overlay + - value: gangscheduled +``` + +Then the result will be to combine these overlays eg 'mixin' an overlays in the kustomization.yaml file. + +#### Merging multiple overlays to generate app.yaml + +Normally when `kfctl init ...` is called it will download the kubeflow repo under `/.cache` and read one of the config files under `.cache/kubeflow//bootstrap/config`. These config files define packages, components and component parameters (among other things). Each config file is a compatible k8 resource of kind *KfDef*. The various config files are: +- kfctl_default.yaml +- kfctl_basic_auth.yaml +- kfctl_iap.yaml + +Both kfctl_basic_auth.yaml and kfctl_iap.yaml contain the contents of kfctl_default.yaml plus some additional changes specific to using basic_auth when the cluster is created and platform specific resources if the platform is **gcp**. This PR corrects this redundancy by using kustomize to combine a **gcp** overlay and/or a **basic_auth** overlay. Additionally, due to pipeline refactoring, the kustomize package manager has split the bundled pipeline component in ksonnet to a set of individual pipeline targets. This results in the following: + +``` +config +β”œβ”€β”€ base +β”‚Β Β  └── kustomization.yaml +└── overlays + β”œβ”€β”€ basic_auth + β”‚Β Β  └── kustomization.yaml + β”œβ”€β”€ gcp + β”‚Β Β  └── kustomization.yaml + β”œβ”€β”€ ksonnet + β”‚Β Β  └── kustomization.yaml + └── kustomize + └── kustomization.yaml +``` + +Based on the cli args to `kfctl init...`, the correct overlays will be merged to produce an app.yaml. +The original files have been left as is until UI integration can be completed in a separate PR + +### Using kustomize + +Generating yaml output for any target can be done using kustomize in the following way: + +#### Install kustomize `go get -u github.com/kubernetes-sigs/kustomize` diff --git a/common/centraldashboard/base/kustomization.yaml b/common/centraldashboard/base/kustomization.yaml index 25e3ef9877d..fcce83c4eca 100644 --- a/common/centraldashboard/base/kustomization.yaml +++ b/common/centraldashboard/base/kustomization.yaml @@ -7,6 +7,7 @@ resources: - service-account.yaml - service.yaml - virtual-service.yaml +namespace: kubeflow commonLabels: kustomize.component: centraldashboard images: diff --git a/hack/gen-test-target.sh b/hack/gen-test-target.sh new file mode 100755 index 00000000000..97f0daf8a91 --- /dev/null +++ b/hack/gen-test-target.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +# +# gen-test-target will generate a golang testcase using the +# kustomize test-harness that is used from kerbernetes-sigs/kustomize/pkg/target/kusttestharness_test.go +# The unittest compares the collection of resource files with what kustomize build would produce (actual vs expected) +# +source hack/utils.sh + +kebab-case-2-PascalCase() +{ + local a=$1 b='' array + IFS='-' read -r -a array <<< "$a" + for element in "${array[@]}" + do + part="${element^}" + b+=$part + done + echo $b +} + +gen-target-start() +{ + local dir=$(get-target $1) target fname + fname=/manifests${dir##*/manifests} + target=$(kebab-case-2-PascalCase $(get-target-name $1)) + + echo 'package kustomize_test' + echo '' + echo 'import (' + echo ' "testing"' + echo ')' + echo '' + echo 'func write'$target'(th *KustTestHarness) {' +} + +gen-target-end() +{ + echo '}' +} + +gen-target() +{ + local directory=$1 + gen-target-start $1 + for i in $(echo $(cat $directory/kustomization.yaml | grep '^- .*yaml$'|sed 's/^- //') $(cat $directory/kustomization.yaml | grep ' path: ' | sed 's/^.*: \(.*\)$/\1/') params.env kustomization.yaml | sed 's/ /\n/g' | sort | uniq); do + file=$i + if [[ -f $directory/$file ]]; then + case $file in + "kustomization.yaml") + gen-target-kustomization $file $directory + ;; + *.yaml) + gen-target-resource $file $directory + ;; + params.env) + gen-target-resource $file $directory + ;; + *) + ;; + esac + fi + done + gen-target-end +} + +gen-target-kustomization() +{ + local file=$1 dir=$2 fname kname + fname=/manifests${dir##*/manifests} + kname=${fname%/kustomization.yaml} + echo ' th.writeK("'$kname'", `' + cat $dir/$file + echo '`)' + +} + +gen-target-resource() +{ + local file=$1 dir=$2 fname + fname=/manifests${dir##*/manifests}/$file + + echo ' th.writeF("'$fname'", `' + cat $dir/$file + echo '`)' +} + +gen-expected-start() +{ + echo ' th.assertActualEqualsExpected(m, `' +} + +gen-expected-end() +{ + echo '`)' +} + +gen-expected() +{ + gen-expected-start + cd $1 + kustomize build + cd - >/dev/null + gen-expected-end +} + +gen-test-case() +{ + local base=$(get-target-name $1) dir=$(get-target $1) target fname + fname=/manifests${dir##*/manifests}/$(get-target-dirname $1) + target=$(kebab-case-2-PascalCase $base) + + gen-target $1 + echo '' + echo 'func Test'$target'(t *testing.T) {' + echo ' th := NewKustTestHarness(t, "'$fname'")' + echo ' write'$target'(th)' + echo ' m, err := th.makeKustTarget().MakeCustomizedResMap()' + echo ' if err != nil {' + echo ' t.Fatalf("Err: %v", err)' + echo ' }' + gen-expected $1 + echo '}' +} + +gen-test-case $1 diff --git a/hack/gen-test-targets.sh b/hack/gen-test-targets.sh new file mode 100755 index 00000000000..b68c85426a7 --- /dev/null +++ b/hack/gen-test-targets.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +# +# gen-test-targets will generate units tests under tests/ for all directories that +# have a kustomization.yaml. This script first finds all directories and then calls +# gen-test-target to generate each golang unit test. +# The script is based on kusttestharness_test.go from kubernetes-sigs/kustomize/pkg/target +# +if [[ $(basename $PWD) != "manifests" ]]; then + echo "must be at manifests root directory to run $0" + exit 1 +fi + +source hack/utils.sh +rm -f $(ls tests/*_test.go | grep -v kusttestharness_test.go) +for i in $(find * -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \; | egrep -v 'docs|tests|hack'); do + absdir=$(pwd)/$i + testname=$(get-target-name $absdir)_test.go + echo generating $testname from $absdir + ./hack/gen-test-target.sh $absdir > tests/$testname +done diff --git a/hack/gen-tree.sh b/hack/gen-tree.sh new file mode 100755 index 00000000000..73ac3fc1b3e --- /dev/null +++ b/hack/gen-tree.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + + +if [[ $(basename $PWD) != "manifests" ]]; then + echo "must be at manifests root directory to run $0" + exit 1 +fi + +source hack/utils.sh + +manifests-tree $@ diff --git a/hack/utils.sh b/hack/utils.sh new file mode 100644 index 00000000000..308051c5bcc --- /dev/null +++ b/hack/utils.sh @@ -0,0 +1,125 @@ +# +# utils.sh has common scripts used the gen-test-targets, get-test-target and gen-tree. +# + +# +# manifests-tree will produce a listing that can be included in the README.md that shows +# what directories hold kustomization.yamls. +# +tmpfile="" +cleanup() +{ + if [[ -f $tmpfile ]]; then + rm -f $tmpfile + fi +} +trap cleanup EXIT + +manifests-tree() +{ + local dir='*' + if (( $# >= 1 )); then + dir=$1 + shift + fi + tmpfile=$(mktemp -q -t tree) + for i in $(find * -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \; | egrep -v 'docs|tests|hack'); do + d=$(dirname $i) + b=$(basename $i) + echo /manifests/$d/🎯$b >> $tmpfile + done + cat $tmpfile | tree $@ -N --fromfile --noreport +} + +# +# get-target will return the 'root' of the manifest given the full path to where the kustomization.yaml is. +# For example +# +# tf-job-operator +# β”œβ”€β”€ base +# └── overlays +# β”œβ”€β”€ cluster +# β”œβ”€β”€ cluster-gangscheduled +# β”œβ”€β”€ namespaced +# └── namespaced-gangscheduled +# +# Given the path /manifests/tf-training/tf-job-operator/overlays/namespaced-gangscheduled +# gen-target will return /manifests/tf-training/tf-job-operator +# +# Given the path /manifests/tf-training/tf-job-operator/base +# gen-target will return /manifests/tf-training/tf-job-operator +# +get-target() +{ + local b=$(basename $1) + case $b in + base) + echo $(dirname $1) + ;; + *) + echo $(dirname $(dirname $1)) + ;; + esac +} + +# +# get-target will return the basename of the manifest given the full path to where the kustomization.yaml is. +# For example +# +# tf-job-operator +# β”œβ”€β”€ base +# └── overlays +# β”œβ”€β”€ cluster +# β”œβ”€β”€ cluster-gangscheduled +# β”œβ”€β”€ namespaced +# └── namespaced-gangscheduled +# +# Given the path /manifests/tf-training/tf-job-operator/overlays/namespaced-gangscheduled +# gen-target will return tf-job-operator +# +# Given the path /manifests/tf-training/tf-job-operator/base +# gen-target will return tf-job-operator +# +get-target-name() +{ + local b=$(basename $1) + case $b in + base) + echo $(basename $(dirname $1)) + ;; + *) + echo $(basename $(dirname $(dirname $1))) + ;; + esac +} + +# +# get-target-dirname will return the dirs between the root and the kustomization.yaml +# For example +# +# tf-job-operator +# β”œβ”€β”€ base +# └── overlays +# β”œβ”€β”€ cluster +# β”œβ”€β”€ cluster-gangscheduled +# β”œβ”€β”€ namespaced +# └── namespaced-gangscheduled +# +# Given the path /manifests/tf-training/tf-job-operator/overlays/namespaced-gangscheduled +# gen-target-dirname will return overlays/namespaced-gangscheduled +# +# Given the path /manifests/tf-training/tf-job-operator/base +# gen-target will return base +# +get-target-dirname() +{ + local b=$(basename $1) + case $b in + base) + echo base + ;; + *) + echo overlays/$b + ;; + esac +} diff --git a/hack/v2.zip b/hack/v2.zip new file mode 100644 index 00000000000..8c0ba80cb5f Binary files /dev/null and b/hack/v2.zip differ diff --git a/jupyter/jupyter-web-app/base/config-map.yaml b/jupyter/jupyter-web-app/base/config-map.yaml index 64066527006..54079170f6c 100644 --- a/jupyter/jupyter-web-app/base/config-map.yaml +++ b/jupyter/jupyter-web-app/base/config-map.yaml @@ -5,9 +5,9 @@ data: # Each key corresponds to a JupyterHub Spawner UI option # If a key is missing, the respective Spawner UI option will be left untouched # - # Each Spawner UI option is configured by two keys: `value` and `readOnly` - # - The `value` key contains the default value - # - The `readOnly` key determines if the option will be available to users + # Each Spawner UI option is configured by two keys: 'value' and 'readOnly' + # - The 'value' key contains the default value + # - The 'readOnly' key determines if the option will be available to users # # If the 'readOnly' key is present and set to 'true', the respective option # will be disabled for users and only set by the admin diff --git a/jupyter/jupyter-web-app/base/kustomization.yaml b/jupyter/jupyter-web-app/base/kustomization.yaml index 3ac46f6eaa0..cfa94359b38 100644 --- a/jupyter/jupyter-web-app/base/kustomization.yaml +++ b/jupyter/jupyter-web-app/base/kustomization.yaml @@ -11,6 +11,7 @@ resources: - service.yaml - virtual-service.yaml namePrefix: jupyter-web-app- +namespace: kubeflow commonLabels: app: jupyter-web-app kustomize.component: jupyter-web-app diff --git a/jupyter/jupyter/base/config-map.yaml b/jupyter/jupyter/base/config-map.yaml index eac0caea4c5..3dd8c8b284f 100644 --- a/jupyter/jupyter/base/config-map.yaml +++ b/jupyter/jupyter/base/config-map.yaml @@ -13,7 +13,7 @@ data: components. Note that this file is also responsible for importing the UI-specific Spawner - class from /spawner.py, and setting the `spawner_class` configuration + class from /spawner.py, and setting the 'spawner_class' configuration option. """ @@ -917,7 +917,7 @@ data: if self._default_config_contains('workspaceVolume'): ws_volume_readonly = form_defaults['workspaceVolume'].get('readOnly', False) - # The Workspace Volume is specified in `config.yaml` + # The Workspace Volume is specified in 'config.yaml' default_ws_volume = form_defaults['workspaceVolume']['value'] # Get and set the default values from the YAML configuration file, @@ -1126,7 +1126,7 @@ data: def _list_pvcs_in_namespace(self, namespace): """ Return a list with all non-failed PVCs in a K8s namespace. - Each list entry is a dict with `name`, `size` and `access_modes` keys. + Each list entry is a dict with 'name', 'size' and 'access_modes' keys. """ existing_pvcs = [] @@ -1243,9 +1243,9 @@ data: # Each key corresponds to a JupyterHub Spawner UI option # If a key is missing, the respective Spawner UI option will be left untouched # - # Each Spawner UI option is configured by two keys: `value` and `readOnly` - # - The `value` key contains the default value - # - The `readOnly` key determines if the option will be available to users + # Each Spawner UI option is configured by two keys: 'value' and 'readOnly' + # - The 'value' key contains the default value + # - The 'readOnly' key determines if the option will be available to users # # If the 'readOnly' key is present and set to 'true', the respective option # will be disabled for users and only set by the admin diff --git a/jupyter/jupyter/base/kustomization.yaml b/jupyter/jupyter/base/kustomization.yaml index 6aefa253769..4cfd23fe06d 100644 --- a/jupyter/jupyter/base/kustomization.yaml +++ b/jupyter/jupyter/base/kustomization.yaml @@ -7,6 +7,7 @@ resources: - service-account.yaml - service.yaml - stateful-set.yaml +namespace: kubeflow commonLabels: kustomize.component: jupyter app: jupyter diff --git a/jupyter/jupyter/overlays/minikube/stateful-set.yaml b/jupyter/jupyter/overlays/minikube/stateful-set.yaml index 78ad89cd804..672bbadb35c 100644 --- a/jupyter/jupyter/overlays/minikube/stateful-set.yaml +++ b/jupyter/jupyter/overlays/minikube/stateful-set.yaml @@ -1,4 +1,4 @@ -apiVersion: apps/v1beta1 +apiVersion: apps/v1beta2 kind: StatefulSet metadata: name: jupyter diff --git a/katib/base/kustomization.yaml b/katib/base/kustomization.yaml index 794d7d3c361..c9363b86eb0 100644 --- a/katib/base/kustomization.yaml +++ b/katib/base/kustomization.yaml @@ -1,3 +1,4 @@ +namespace: kubeflow resources: - katib-db-pvc.yaml - katib-ui-deployment.yaml diff --git a/kubebench/base/kustomization.yaml b/kubebench/base/kustomization.yaml index da266cec388..3c8a9ba7503 100644 --- a/kubebench/base/kustomization.yaml +++ b/kubebench/base/kustomization.yaml @@ -11,6 +11,7 @@ resources: - service.yaml - virtual-service.yaml - workflow.yaml +namespace: kubeflow commonLabels: kustomize.component: kubebench configMapGenerator: diff --git a/modeldb/base/kustomization.yaml b/modeldb/base/kustomization.yaml index 6dc6c4a6eda..bff6e23417d 100644 --- a/modeldb/base/kustomization.yaml +++ b/modeldb/base/kustomization.yaml @@ -1,12 +1,19 @@ namePrefix: modeldb- resources: -- cluster-role.yaml -- service-account.yaml -- cluster-role-binding.yaml -- config-map.yaml -- service.yaml -- deployment.yaml +- artifact-store-deployment.yaml +- artifact-store-service.yaml +- backend-deployment.yaml +- backend-proxy-service.yaml +- backend-service.yaml +- configmap.yaml +- mysql-backend-deployment.yaml +- mysql-service.yaml +- persistent-volume-claim.yaml +- proxy-deployment.yaml +- secret.yaml +- webapp-deplyment.yaml +- webapp-service.yaml commonLabels: kustomize.component: modeldb diff --git a/pipeline/pipelines-ui/base/kustomization.yaml b/pipeline/pipelines-ui/base/kustomization.yaml index d3e0b653588..052756b5993 100644 --- a/pipeline/pipelines-ui/base/kustomization.yaml +++ b/pipeline/pipelines-ui/base/kustomization.yaml @@ -5,7 +5,7 @@ resources: - sa.yaml - service.yaml - virtual-service.yaml - +namespace: kubeflow configMapGenerator: - name: ui-parameters env: params.env diff --git a/pipeline/pipelines-viewer/base/kustomization.yaml b/pipeline/pipelines-viewer/base/kustomization.yaml index 9d532894c01..238b09957be 100644 --- a/pipeline/pipelines-viewer/base/kustomization.yaml +++ b/pipeline/pipelines-viewer/base/kustomization.yaml @@ -1,5 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +namespace: kubeflow resources: - crd.yaml - clusterrole-binding.yaml diff --git a/tensorboard/base/kustomization.yaml b/tensorboard/base/kustomization.yaml index d26617ac892..15f51714ace 100644 --- a/tensorboard/base/kustomization.yaml +++ b/tensorboard/base/kustomization.yaml @@ -1,5 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +namespace: kubeflow resources: - deployment.yaml - service.yaml diff --git a/tests/Makefile b/tests/Makefile new file mode 100755 index 00000000000..5cc419d1d77 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,35 @@ +# Copyright 2017 The Kubernetes Authors. +# +# 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. +# +GOLANG_VERSION ?= 1.12 +GOPATH ?= $(HOME)/go +EXCLUDE ?= gcp-credentials-admission-webhook_test.go +# use {} for more than one file +#EXCLUDE ?= {x_test.go,y_test.go,z_test.go} +export GO111MODULE = on +export GO = go + +all: test + +/tmp/v2: + @[ ! -d /tmp/v2 ] && unzip -q -d /tmp ../hack/v2.zip + +generate: clean /tmp/v2 + @cd .. && hack/gen-test-targets.sh && rm tests/$(EXCLUDE) + +test: generate + @GO111MODULE=on $(GO) test -v . + +clean: + @rm -f $$(ls *_test.go | egrep -v 'kusttestharness_test.go|go.mod|go.sum') && rm -rf /tmp/v2 diff --git a/tests/go.mod b/tests/go.mod new file mode 100644 index 00000000000..e29a2cb26a8 --- /dev/null +++ b/tests/go.mod @@ -0,0 +1,19 @@ +module github.com/kubeflow/manifests + +go 1.12 + +require ( + k8s.io/api/v2 v2.0.0 + k8s.io/apiextensions-apiserver/v2 v2.0.0 + k8s.io/apimachinery/v2 v2.0.0 + k8s.io/client-go/v2 v2.0.0 + sigs.k8s.io/kustomize/v2 v2.0.0-00010101000000-000000000000 +) + +replace ( + k8s.io/api/v2 => /tmp/v2/k8s.io/api + k8s.io/apiextensions-apiserver/v2 => /tmp/v2/k8s.io/apiextensions-apiserver + k8s.io/apimachinery/v2 => /tmp/v2/k8s.io/apimachinery + k8s.io/client-go/v2 => /tmp/v2/k8s.io/client-go + sigs.k8s.io/kustomize/v2 => /tmp/v2/sigs.k8s.io/kustomize +) diff --git a/tests/go.sum b/tests/go.sum new file mode 100644 index 00000000000..0209d025637 --- /dev/null +++ b/tests/go.sum @@ -0,0 +1,160 @@ +bitbucket.org/ww/goautoneg v0.0.0-20120707110453-75cd24fc2f2c/go.mod h1:1vhO7Mn/FZMgOgDVGLy5X1mE6rq1HbkBdkF/yj8zkcg= +cloud.google.com/go v0.0.0-20160913182117-3b1ae45394a2/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v11.1.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/davecgh/go-spew v0.0.0-20170626231645-782f4967f2dc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docker/docker v0.0.0-20180612054059-a9fbbdc8dd87/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/elazarl/go-bindata-assetfs v0.0.0-20150624150248-3dcc96556217/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.0+incompatible h1:YKhDcF/NL19iSAQcyCATL1MkFXCzxfdaTiuJKr18Ank= +github.com/emicklei/go-restful v2.9.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful-swagger12 v0.0.0-20170208215640-dcef7f557305/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ= +github.com/emicklei/go-restful/v2 v2.0.0-20180531035034-3658237ded10/go.mod h1:gwwVizmZk4uIMBv4nhnVXCsM2JBhvPqyHlJxjL8t1+o= +github.com/evanphx/json-patch v0.0.0-20180908160633-36442dbdb585/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v3.0.0+incompatible h1:l91aby7TzBXBdmF8heZqjskeH9f3g7ZOL8/sSe+vTlU= +github.com/evanphx/json-patch v3.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/jsonpointer v0.0.0-20180322222829-3a0015ad55fa/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0 h1:KVRzjXpMzgdM4GEMDmDTnGcY5yBwGWreJwmmk4k35yU= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonreference v0.0.0-20180322222742-3fb327e6747d/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0 h1:oP2OUNdG1l2r5kYhrfVMXO54gWmzcfAwP/GFuHpNTkE= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.17.2/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q= +github.com/go-openapi/spec v0.0.0-20180415031709-bcff419492ee/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.17.2 h1:eb2NbuCnoe8cWAxhtK6CfMWUYmiFEZJ9Hx3Z2WRwJ5M= +github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/swag v0.0.0-20180405201759-811b1089cde9/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.17.2 h1:K/ycE/XTUDFltNHSO32cGRUhrVGJD64o8WgAIZNyc3k= +github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= +github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.0.0-20180330165814-781450b3c4fc/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20180830092908-498ae206fc3c/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20170330212424-2500245aa611/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/golang-lru v0.0.0-20160207214719-a0d98a5f2880/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.0.0-20141017032234-72f9bd7c4e0c/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPUhEF5KNCkrUyqTSA5zWUl8sQ2bfGBE= +github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/mailru/easyjson v0.0.0-20170624190925-2f5df55504eb/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180606163543-3fdea8d05856/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/mapstructure v0.0.0-20170307201123-53818660ed49/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pborman/uuid v0.0.0-20150603214016-ca53cad383ca/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.0.0-20170531130054-e7e903064f5e/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20170427095455-13ba4ddd0caa/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20170519190837-65c1f6f8f0fc/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/sirupsen/logrus v0.0.0-20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spf13/cobra v0.0.0-20180319062004-c439c4fa0937/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/testify v0.0.0-20180319223459-c679ae2cc0cb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v0.0.0-20171019201919-bdcc60b419d1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= +github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180808211826-de0752318171/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180124060956-0ed95abb35c4/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/oauth2 v0.0.0-20170412232759-a6bd8cefa181/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20171031081856-95c657629925/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.0.0-20170810154203-b19bf474d317/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0-20150622162204-20b71e5b60d7/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +k8s.io/apiserver v0.0.0-20190228174905-79427f02047f/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w= +k8s.io/klog v0.0.0-20181108234604-8139d8cb77af h1:s6rm8OxBbyDNSRkpyAd5OL4icUdBICVw9+mFADa+t5E= +k8s.io/klog v0.0.0-20181108234604-8139d8cb77af/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5 h1:MH8SvyTlIiLt8b1oHy4Dtp1zPpLGp6lTOjvfzPTkoQE= +k8s.io/kube-openapi v0.0.0-20181109181836-c59034cc13d5/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/tests/kusttestharness_test.go b/tests/kusttestharness_test.go new file mode 100644 index 00000000000..18b1095e079 --- /dev/null +++ b/tests/kusttestharness_test.go @@ -0,0 +1,231 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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 kustomize_test + +// A collection of utilities used in target tests. + +import ( + "fmt" + "path/filepath" + "strings" + "testing" + "log" + "sigs.k8s.io/kustomize/v2/pkg/fs" + "sigs.k8s.io/kustomize/v2/pkg/ifc" + "sigs.k8s.io/kustomize/v2/pkg/loader" + + "sigs.k8s.io/kustomize/v2/k8sdeps/kunstruct" + "sigs.k8s.io/kustomize/v2/k8sdeps/transformer" + "sigs.k8s.io/kustomize/v2/pkg/constants" + "sigs.k8s.io/kustomize/v2/pkg/resmap" + "sigs.k8s.io/kustomize/v2/pkg/resource" + . "sigs.k8s.io/kustomize/v2/pkg/target" + "sigs.k8s.io/kustomize/v2/pkg/transformers/config/defaultconfig" + "sigs.k8s.io/kustomize/v2/pkg/types" +) + +// FakeLoader encapsulates the delegate Loader and the fake file system. +type FakeLoader struct { + fs fs.FileSystem + delegate ifc.Loader +} + +// NewFakeLoader returns a Loader that uses a fake filesystem. +// The argument should be an absolute file path. +func NewFakeLoader(initialDir string) FakeLoader { + // Create fake filesystem and inject it into initial Loader. + fSys := fs.MakeFakeFS() + fSys.Mkdir(initialDir) + ldr, err := loader.NewLoader(initialDir, fSys) + if err != nil { + log.Fatalf("Unable to make loader: %v", err) + } + return FakeLoader{fs: fSys, delegate: ldr} +} + +// AddFile adds a fake file to the file system. +func (f FakeLoader) AddFile(fullFilePath string, content []byte) error { + return f.fs.WriteFile(fullFilePath, content) +} + +// AddDirectory adds a fake directory to the file system. +func (f FakeLoader) AddDirectory(fullDirPath string) error { + return f.fs.Mkdir(fullDirPath) +} + +// Root returns root. +func (f FakeLoader) Root() string { + return f.delegate.Root() +} + +// New creates a new loader from a new root. +func (f FakeLoader) New(newRoot string) (ifc.Loader, error) { + l, err := f.delegate.New(newRoot) + if err != nil { + return nil, err + } + return FakeLoader{fs: f.fs, delegate: l}, nil +} + +// Load performs load from a given location. +func (f FakeLoader) Load(location string) ([]byte, error) { + return f.delegate.Load(location) +} + +// Cleanup does nothing +func (f FakeLoader) Cleanup() error { + return nil +} + +type KustTestHarness struct { + t *testing.T + rf *resmap.Factory + ldr FakeLoader +} + +func NewKustTestHarness(t *testing.T, path string) *KustTestHarness { + return &KustTestHarness{ + t: t, + rf: resmap.NewFactory(resource.NewFactory( + kunstruct.NewKunstructuredFactoryImpl())), + ldr: NewFakeLoader(path)} +} + +func (th *KustTestHarness) makeKustTarget() *KustTarget { + kt, err := NewKustTarget( + th.ldr, th.rf, transformer.NewFactoryImpl()) + if err != nil { + th.t.Fatalf("Unexpected construction error %v", err) + } + return kt +} + +func (th *KustTestHarness) writeF(dir string, content string) { + err := th.ldr.AddFile(dir, []byte(content)) + if err != nil { + th.t.Fatalf("failed write to %s; %v", dir, err) + } +} + +func (th *KustTestHarness) writeK(dir string, content string) { + th.writeF(filepath.Join(dir, constants.KustomizationFileNames[0]), ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +`+content) +} + +func (th *KustTestHarness) fromMap(m map[string]interface{}) *resource.Resource { + return th.rf.RF().FromMap(m) +} + +func (th *KustTestHarness) fromMapAndOption(m map[string]interface{}, args *types.GeneratorArgs, option *types.GeneratorOptions) *resource.Resource { + return th.rf.RF().FromMapAndOption(m, args, option) +} + +func (th *KustTestHarness) writeDefaultConfigs(fName string) { + m := defaultconfig.GetDefaultFieldSpecsAsMap() + var content []byte + for _, tCfg := range m { + content = append(content, []byte(tCfg)...) + } + err := th.ldr.AddFile(fName, content) + if err != nil { + th.t.Fatalf("unable to add file %s", fName) + } +} + +func tabToSpace(input string) string { + var result []string + for _, i := range input { + if i == 9 { + result = append(result, " ") + } else { + result = append(result, string(i)) + } + } + return strings.Join(result, "") +} + +func convertToArray(x string) ([]string, int) { + a := strings.Split(strings.TrimSuffix(x, "\n"), "\n") + maxLen := 0 + for i, v := range a { + z := tabToSpace(v) + if len(z) > maxLen { + maxLen = len(z) + } + a[i] = z + } + return a, maxLen +} + +func hint(a, b string) string { + if a == b { + return " " + } + return "X" +} + +func (th *KustTestHarness) assertActualEqualsExpected( + m resmap.ResMap, expected string) { + if m == nil { + th.t.Fatalf("Map should not be nil.") + } + // Ignore leading linefeed in expected value + // to ease readability of tests. + if len(expected) > 0 && expected[0] == 10 { + expected = expected[1:] + } + actual, err := m.EncodeAsYaml() + if err != nil { + th.t.Fatalf("Unexpected err: %v", err) + } + if string(actual) != expected { + th.reportDiffAndFail(actual, expected) + } +} + +// Pretty printing of file differences. +func (th *KustTestHarness) reportDiffAndFail(actual []byte, expected string) { + sE, maxLen := convertToArray(expected) + sA, _ := convertToArray(string(actual)) + fmt.Println("===== ACTUAL BEGIN ========================================") + fmt.Print(string(actual)) + fmt.Println("===== ACTUAL END ==========================================") + format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4) + limit := 0 + if len(sE) < len(sA) { + limit = len(sE) + } else { + limit = len(sA) + } + fmt.Printf(format, " ", "EXPECTED", "ACTUAL") + fmt.Printf(format, " ", "--------", "------") + for i := 0; i < limit; i++ { + fmt.Printf(format, hint(sE[i], sA[i]), sE[i], sA[i]) + } + if len(sE) < len(sA) { + for i := len(sE); i < len(sA); i++ { + fmt.Printf(format, "X", "", sA[i]) + } + } else { + for i := len(sA); i < len(sE); i++ { + fmt.Printf(format, "X", sE[i], "") + } + } + th.t.Fatalf("Expected not equal to actual") +} diff --git a/tf-training/tf-job-operator/base/kustomization.yaml b/tf-training/tf-job-operator/base/kustomization.yaml index 92d67dbaacf..1a4b38942e9 100644 --- a/tf-training/tf-job-operator/base/kustomization.yaml +++ b/tf-training/tf-job-operator/base/kustomization.yaml @@ -1,5 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization +namespace: kubeflow resources: - cluster-role-binding.yaml - cluster-role.yaml