Showing preview only (4,031K chars total). Download the full file or copy to clipboard to get everything.
Repository: kubeflow/kfctl
Branch: master
Commit: b53bbfd2bbfc
Files: 288
Total size: 3.8 MB
Directory structure:
gitextract_q8wlw781/
├── .github/
│ ├── issue_label_bot.yaml
│ └── workflows/
│ ├── kfctl_go_unittests.yaml
│ └── triage_issues.yaml
├── .gitignore
├── Dockerfile
├── LICENSE
├── Makefile
├── OWNERS
├── README.md
├── build/
│ ├── Dockerfile
│ └── Dockerfile.ubi
├── cmd/
│ ├── kfctl/
│ │ ├── .gitignore
│ │ ├── OWNERS
│ │ ├── README.md
│ │ ├── cmd/
│ │ │ ├── alpha.go
│ │ │ ├── apply.go
│ │ │ ├── build.go
│ │ │ ├── completion.go
│ │ │ ├── delete.go
│ │ │ ├── generate.go
│ │ │ ├── init.go
│ │ │ ├── mirror.go
│ │ │ ├── mirror_build.go
│ │ │ ├── mirror_overwrite.go
│ │ │ ├── root.go
│ │ │ ├── set-image-name.go
│ │ │ ├── set-image-name_test.go
│ │ │ ├── show.go
│ │ │ └── version.go
│ │ └── main.go
│ ├── manager/
│ │ └── main.go
│ └── plugins/
│ └── dockerfordesktop/
│ └── dockerfordesktop.go
├── config/
│ ├── doc.go
│ ├── types.go
│ └── zz_generated.deepcopy.go
├── deploy/
│ ├── cluster_role_binding.yaml
│ ├── crds/
│ │ ├── kfdef.apps.kubeflow.org_kfdefs_crd.yaml
│ │ └── kustomization.yaml
│ ├── kustomization.yaml
│ ├── olm-catalog/
│ │ └── kubeflow/
│ │ ├── 0.1.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v0.1.0.clusterserviceversion.yaml
│ │ ├── 1.0.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v1.0.0.clusterserviceversion.yaml
│ │ ├── 1.1.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v1.1.0.clusterserviceversion.yaml
│ │ ├── 1.2.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v1.2.0.clusterserviceversion.yaml
│ │ └── kubeflow.package.yaml
│ ├── operator.yaml
│ ├── params.yaml
│ ├── role.yaml
│ └── service_account.yaml
├── go.mod
├── go.sum
├── hack/
│ ├── boilerplate.go.txt
│ └── cp_update.sh
├── kustomization.yaml
├── kustomize/
│ ├── base/
│ │ └── kustomization.yaml
│ └── include/
│ └── quota/
│ ├── kfdef_quota.yaml
│ └── kustomization.yaml
├── operator.md
├── pkg/
│ ├── apis/
│ │ ├── apis.go
│ │ ├── apps/
│ │ │ ├── addtoscheme_kfdef_v1.go
│ │ │ ├── apis.go
│ │ │ ├── group.go
│ │ │ ├── group_test.go
│ │ │ ├── imagemirror/
│ │ │ │ └── v1alpha1/
│ │ │ │ └── replication_types.go
│ │ │ ├── kfconfig/
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── types.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ ├── kfdef/
│ │ │ │ ├── kfdef.go
│ │ │ │ ├── testdata/
│ │ │ │ │ └── doc.go
│ │ │ │ ├── v1/
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── application_types.go
│ │ │ │ │ ├── application_types_test.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── register.go
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── doc.go
│ │ │ │ │ │ └── kfctl_plugin_test.yaml
│ │ │ │ │ └── zz_generated.deepcopy.go
│ │ │ │ ├── v1alpha1/
│ │ │ │ │ ├── application_types.go
│ │ │ │ │ ├── application_types_test.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── register.go
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── doc.go
│ │ │ │ │ │ └── kfctl_plugin_test.yaml
│ │ │ │ │ ├── v1alpha1_suite_test.go
│ │ │ │ │ └── zz_generated.deepcopy.go
│ │ │ │ └── v1beta1/
│ │ │ │ ├── README.md
│ │ │ │ ├── application_types.go
│ │ │ │ ├── application_types_test.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── testdata/
│ │ │ │ │ ├── doc.go
│ │ │ │ │ └── kfctl_plugin_test.yaml
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ ├── kfupgrade/
│ │ │ │ ├── kfupgrade.go
│ │ │ │ └── v1alpha1/
│ │ │ │ ├── application_types.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ └── plugins/
│ │ │ ├── aws/
│ │ │ │ ├── aws.go
│ │ │ │ └── v1alpha1/
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── types.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ ├── gcp/
│ │ │ │ ├── gcp.go
│ │ │ │ └── v1alpha1/
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── types.go
│ │ │ │ ├── types_test.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ └── plugins.go
│ │ └── kferrors.go
│ ├── controller/
│ │ ├── controller.go
│ │ └── kfdef/
│ │ ├── const.go
│ │ └── kfdef_controller.go
│ ├── kfapp/
│ │ ├── aws/
│ │ │ ├── OWNERS
│ │ │ ├── aws.go
│ │ │ ├── eks.go
│ │ │ ├── eks_test.go
│ │ │ ├── identity.go
│ │ │ └── k8sClient.go
│ │ ├── coordinator/
│ │ │ ├── coordinator.go
│ │ │ ├── coordinator_test.go
│ │ │ └── fake/
│ │ │ └── fake.go
│ │ ├── dockerfordesktop/
│ │ │ └── dockerfordesktop.go
│ │ ├── existing_arrikto/
│ │ │ ├── existing.go
│ │ │ └── existing_test.go
│ │ ├── gcp/
│ │ │ ├── fake/
│ │ │ │ └── fake.go
│ │ │ ├── gcp.go
│ │ │ ├── gcp_test.go
│ │ │ └── testdata/
│ │ │ ├── doc.go
│ │ │ └── kfctl_gcp.yaml
│ │ ├── kfapp.go
│ │ ├── kfdef.go
│ │ ├── kustomize/
│ │ │ ├── kustomize.go
│ │ │ ├── kustomize_test.go
│ │ │ └── testdata/
│ │ │ ├── doc.go
│ │ │ ├── kustomizeExample/
│ │ │ │ ├── metadata/
│ │ │ │ │ ├── base/
│ │ │ │ │ │ ├── grpc-params.env
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ ├── metadata-envoy-deployment.yaml
│ │ │ │ │ │ ├── metadata-envoy-service.yaml
│ │ │ │ │ │ ├── metadata-service.yaml
│ │ │ │ │ │ ├── metadata-ui-deployment.yaml
│ │ │ │ │ │ ├── metadata-ui-role.yaml
│ │ │ │ │ │ ├── metadata-ui-rolebinding.yaml
│ │ │ │ │ │ ├── metadata-ui-sa.yaml
│ │ │ │ │ │ ├── metadata-ui-service.yaml
│ │ │ │ │ │ └── params.env
│ │ │ │ │ ├── expected/
│ │ │ │ │ │ └── kustomization.yaml
│ │ │ │ │ └── overlays/
│ │ │ │ │ ├── application/
│ │ │ │ │ │ ├── application.yaml
│ │ │ │ │ │ └── kustomization.yaml
│ │ │ │ │ ├── db/
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-db-deployment.yaml
│ │ │ │ │ │ ├── metadata-db-pvc.yaml
│ │ │ │ │ │ ├── metadata-db-service.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ ├── params.env
│ │ │ │ │ │ └── secrets.env
│ │ │ │ │ ├── external-mysql/
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ ├── params.env
│ │ │ │ │ │ └── secrets.env
│ │ │ │ │ ├── google-cloudsql/
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ └── params.env
│ │ │ │ │ ├── ibm-storage-config/
│ │ │ │ │ │ └── kustomization.yaml
│ │ │ │ │ └── istio/
│ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ ├── params.yaml
│ │ │ │ │ ├── virtual-service-metadata-grpc.yaml
│ │ │ │ │ └── virtual-service.yaml
│ │ │ │ └── pytorch-operator/
│ │ │ │ ├── base/
│ │ │ │ │ ├── cluster-role-binding.yaml
│ │ │ │ │ ├── cluster-role.yaml
│ │ │ │ │ ├── config-map.yaml
│ │ │ │ │ ├── deployment.yaml
│ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ ├── params.env
│ │ │ │ │ ├── service-account.yaml
│ │ │ │ │ └── service.yaml
│ │ │ │ ├── expected/
│ │ │ │ │ └── kustomization.yaml
│ │ │ │ └── overlays/
│ │ │ │ └── application/
│ │ │ │ ├── application.yaml
│ │ │ │ └── kustomization.yaml
│ │ │ └── operator/
│ │ │ ├── base/
│ │ │ │ ├── kustomization.yaml
│ │ │ │ └── service.yaml
│ │ │ ├── expected/
│ │ │ │ └── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── minikube/
│ │ └── minikube.go
│ ├── kfconfig/
│ │ ├── awsplugin/
│ │ │ ├── OWNERS
│ │ │ ├── doc.go
│ │ │ ├── register.go
│ │ │ ├── types.go
│ │ │ └── zz_generated.deepcopy.go
│ │ ├── doc.go
│ │ ├── gcpplugin/
│ │ │ ├── doc.go
│ │ │ ├── register.go
│ │ │ ├── types.go
│ │ │ ├── types_test.go
│ │ │ └── zz_generated.deepcopy.go
│ │ ├── loaders/
│ │ │ ├── loaders.go
│ │ │ ├── loaders_test.go
│ │ │ ├── testdata/
│ │ │ │ ├── doc.go
│ │ │ │ ├── kfconfig_v1.yaml
│ │ │ │ ├── kfconfig_v1alpha1.yaml
│ │ │ │ ├── kfconfig_v1beta1.yaml
│ │ │ │ ├── kfctl_gcp_basic_auth.0.7.0.yaml
│ │ │ │ ├── v1.yaml
│ │ │ │ ├── v1alpha1.yaml
│ │ │ │ └── v1beta1.yaml
│ │ │ ├── utils.go
│ │ │ ├── v1.go
│ │ │ ├── v1_test.go
│ │ │ ├── v1alpha1.go
│ │ │ ├── v1alpha1_test.go
│ │ │ ├── v1beta1.go
│ │ │ └── v1beta1_test.go
│ │ ├── register.go
│ │ ├── testdata/
│ │ │ ├── doc.go
│ │ │ └── kfctl_plugin_test.yaml
│ │ ├── types.go
│ │ ├── types_test.go
│ │ └── zz_generated.deepcopy.go
│ ├── kfupgrade/
│ │ ├── kfupgrade.go
│ │ └── kfupgrade_test.go
│ ├── mirror/
│ │ ├── mirror_image.go
│ │ ├── mirror_image_test.go
│ │ └── testdata/
│ │ ├── base-pkg/
│ │ │ └── kustomization.yaml
│ │ ├── expected-cloudbuild.yaml
│ │ ├── expected-kustomization.yaml
│ │ ├── expected-pipeline.yaml
│ │ └── kustomize/
│ │ └── kustomization.yaml
│ └── utils/
│ ├── awsutil.go
│ ├── diff.go
│ ├── gcputils.go
│ ├── iamutils.go
│ ├── iamutils_test.go
│ ├── k8sAuth.go
│ ├── k8utils.go
│ ├── k8utils_test.go
│ ├── kindsorter.go
│ └── logging.go
├── prow_config.yaml
├── py/
│ └── kubeflow/
│ ├── __init__.py
│ └── kfctl/
│ ├── __init__.py
│ └── testing/
│ ├── __init__.py
│ ├── ci/
│ │ ├── __init__.py
│ │ ├── kfctl_e2e_workflow.py
│ │ ├── kfctl_go_build_test.py
│ │ ├── kfctl_go_deploy_test.py
│ │ ├── kfctl_upgrade_e2e_workflow.py
│ │ └── update_jupyter_web_app.py
│ ├── pytests/
│ │ ├── conftest.py
│ │ ├── endpoint_ready_test.py
│ │ ├── jupyter_test.py
│ │ ├── kf_is_ready_test.py
│ │ ├── kfam_test.py
│ │ ├── kfctl_create_cluster_test.py
│ │ ├── kfctl_delete_cluster_test.py
│ │ ├── kfctl_delete_test.py
│ │ ├── kfctl_delete_wrong_cluster.py
│ │ ├── kfctl_deploy_kubeflow_test.py
│ │ ├── kfctl_go_test.py
│ │ ├── kfctl_second_apply.py
│ │ ├── kfctl_upgrade_test.py
│ │ ├── pytorch_job_deploy.py
│ │ └── testdata/
│ │ ├── jupyter_test.yaml
│ │ └── pytorch_job.yaml
│ ├── test_deploy.py
│ ├── test_deploy_test.py
│ └── util/
│ ├── __init__.py
│ ├── application_util.py
│ ├── application_util_test.py
│ ├── aws_util.py
│ ├── deploy_utils.py
│ ├── gcp_util.py
│ ├── kfctl_go_test_utils.py
│ ├── run_with_retry.py
│ └── vm_util.py
└── third_party/
├── README.md
├── check-license.sh
├── concatenate_license.py
├── dep.txt
├── dep_repo.manual.csv
├── license.txt
└── license_info.csv
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/issue_label_bot.yaml
================================================
# for https://mlbot.net
label-alias:
bug: 'kind/bug'
feature_request: 'kind/feature'
feature: 'kind/feature'
question: 'kind/question'
================================================
FILE: .github/workflows/kfctl_go_unittests.yaml
================================================
name: Unit Test
on:
- push
- pull_request
jobs:
build:
name: Test
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v2
- name: Unit Test
run: |
go test ./... -v 2>&1
================================================
FILE: .github/workflows/triage_issues.yaml
================================================
# Define a GitHub action workflow to determine whether issues
# should be added or removed from the Needs Triage Kanban board.
name: Check Triage Status of Issue
on:
issues:
types: [opened, closed, reopened, transferred, labeled, unlabeled]
# Issue is created, Issue is closed, Issue added or removed from projects, Labels added/removed
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Update Kanban
uses: kubeflow/code-intelligence/Issue_Triage/action@master
with:
# Letting input NEEDS_TRIAGE_PROJECT_CARD_ID use the default value
ISSUE_NUMBER: ${{ github.event.issue.number }}
GITHUB_PERSONAL_ACCESS_TOKEN: ${{ secrets.triage_projects_github_token }}
================================================
FILE: .gitignore
================================================
# pkg and bin directories currently contain build artifacts
# only so we exclude them.
bin/
vendor/
.vscode/
# Compiled python files.
*.pyc
# Emacs temporary files
*~
# Other temporary files
.DS_Store
# temporary files from emacs flymd-mode
flymd.*
# vim .swp files
*~
*.swp
*.swo
# Files created by Gogland IDE
.idea/
# Exclude wheel files for now.
# The only wheel file is the TF wheel one which is quite large.
# We don't want to check that into source control because it could be
# quite large.
*.whl
# Bazel files
**/bazel-*
# Examples egg
examples/tf_sample/tf_sample.egg-info/
examples/.ipynb_checkpoints/
**/.ipynb_checkpoints
# env.sh generated by kfctl.sh
**/env.sh
!testing/test-infra/vendor
# This is required for testing but we don't
# want to check it in right now.
components/gcp-click-to-deploy/src/user_config/**
# This is generated by bootstrap
**/reg_tmp
scripts/gke/build/**
================================================
FILE: Dockerfile
================================================
#**********************************************************************
# Builder
# Create a go runtime suitable for building and testing kfctl
ARG GOLANG_VERSION=1.13.7
FROM golang:$GOLANG_VERSION as builder
ARG BRANCH=master
ARG REPO=https://github.com/kubeflow/kubeflow
RUN apt-get update
RUN apt-get install -y git unzip jq vim
# junit report is used to conver go test output to junit for reporting
RUN go get -u github.com/jstemmer/go-junit-report
# We need gcloud to get gke credentials.
RUN if [ "$(uname -m)" = "x86_64" ]; then \
cd /tmp && \
wget -nv https://dl.google.com/dl/cloudsdk/release/install_google_cloud_sdk.bash && \
chmod +x install_google_cloud_sdk.bash && \
./install_google_cloud_sdk.bash --disable-prompts --install-dir=/opt/; \
fi
ENV PATH /go/bin:/usr/local/go/bin:/opt/google-cloud-sdk/bin:${PATH}
# use go modules
ENV GO111MODULE=on
ENV GOPATH=/go
# Workaround for https://github.com/kubernetes/gengo/issues/146
ENV GOROOT=/usr/local/go
# Create kfctl folder
RUN mkdir -p ${GOPATH}/src/github.com/kubeflow/kfctl
WORKDIR ${GOPATH}/src/github.com/kubeflow
RUN mkdir kubeflow
RUN echo REPO=${REPO} branch=${BRANCH}
RUN git clone ${REPO} --depth=1 --branch ${BRANCH} --single-branch kubeflow
WORKDIR ${GOPATH}/src/github.com/kubeflow/kfctl
# Download dependencies first to optimize Docker caching.
COPY go.mod .
COPY go.sum .
RUN go mod download
# Copy in the source
COPY . .
#**********************************************************************
#
# kfctl_base
#
FROM builder as kfctl_base
RUN make build-kfctl && \
if [ "$(uname -m)" = "aarch64" ]; then \
cp bin/arm64/kfctl bin/kfctl; \
fi
#**********************************************************************
#
# Final image base
#
FROM alpine:3.10.1 as barebones_base
RUN mkdir -p /opt/kubeflow
WORKDIR /opt/kubeflow
#**********************************************************************
#
# kfctl
#
FROM barebones_base as kfctl
COPY --from=kfctl_base /go/src/github.com/kubeflow/kfctl/bin/kfctl /usr/local/bin
COPY --from=kfctl_base /go/src/github.com/kubeflow/kfctl/third_party /third_party
COPY --from=kfctl_base /go/pkg/mod /third_party/vendor
CMD ["/bin/bash", "-c", "trap : TERM INT; sleep infinity & wait"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
================================================
FILE: Makefile
================================================
# 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.
#
GCLOUD_PROJECT ?= kubeflow-images-public
GOLANG_VERSION ?= 1.13.7
GOPATH ?= $(HOME)/go
# To build without the cache set the environment variable
# export DOCKER_BUILD_OPTS=--no-cache
KFCTL_IMG ?= gcr.io/$(GCLOUD_PROJECT)/kfctl
TAG ?= $(eval TAG := $(shell git describe --tags --long --always))$(TAG)
REPO ?= $(shell echo $$(cd ../kubeflow && git config --get remote.origin.url) | sed 's/git@\(.*\):\(.*\).git$$/https:\/\/\1\/\2/')
BRANCH ?= $(shell cd ../kubeflow && git branch | grep '^*' | awk '{print $$2}')
KFCTL_TARGET ?= kfctl
MOUNT_KUBE ?= -v $(HOME)/.kube:/root/.kube
MOUNT_GCP ?= -v $(HOME)/.config:/root/.config
# set to -V
VERBOSE ?=
PLUGINS_ENVIRONMENT ?= $(GOPATH)/src/github.com/kubeflow/kfctl/bin
export GO111MODULE = on
export GO = go
ARCH ?= $(shell ${GO} env|grep GOOS|cut -d'=' -f2|tr -d '"')
OPERATOR_IMG ?= kubeflow-operator
IMAGE_BUILDER ?= docker
DOCKERFILE ?= Dockerfile
OPERATOR_BINARY_NAME ?= $(shell basename ${PWD})
# Location of junit file
JUNIT_FILE ?= /tmp/report.xml
%.so:
cd cmd/plugins/$* && \
${GO} build -i -gcflags '-N -l' -o ../../../bin/$*.so -buildmode=plugin $*.go
%.init:
@echo kfctl init test/$* $(VERBOSE) --platform $* --project $(GCLOUD_PROJECT) --version master && \
PLUGINS_ENVIRONMENT=$(PLUGINS_ENVIRONMENT) kfctl init $(PWD)/test/$* $(VERBOSE) --platform $* --project $(GCLOUD_PROJECT) --version master
%.init-no-platform:
@echo kfctl init test/$* $(VERBOSE) --version master && \
kfctl init $(PWD)/test/$* $(VERBOSE) --version master
%.generate:
@echo kfctl generate all $(VERBOSE) '(--platform '$*')' && \
cd test/$* && \
PLUGINS_ENVIRONMENT=$(PLUGINS_ENVIRONMENT) kfctl generate all $(VERBOSE) --mount-local --email gcp-deploy@$(GCLOUD_PROJECT).iam.gserviceaccount.com
%.md:
all: build
auth:
gcloud auth configure-docker
# Run go fmt against code
fmt:
@${GO} fmt ./config ./cmd/... ./pkg/...
# Run go vet against code
vet:
@${GO} vet ./config ./cmd/... ./pkg/...
generate:
@${GO} generate ./config ./pkg/apis/apps/kfdef/... ./pkg/utils/... ./pkg/kfapp/minikube ./pkg/kfapp/gcp/... ./cmd/kfctl/...
${GOPATH}/bin/deepcopy-gen:
GO111MODULE=on ${GO} get k8s.io/code-generator/cmd/deepcopy-gen
config/zz_generated.deepcopy.go: config/types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/config -O zz_generated.deepcopy \
-p config
pkg/apis/apps/kfdef/v1alpha1/zz_generated.deepcopy.go: pkg/apis/apps/kfdef/v1alpha1/application_types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/... -O zz_generated.deepcopy \
-p pkg/apis/apps/kfdef/v1alpha1/
pkg/apis/apps/kfdef/v1beta1/zz_generated.deepcopy.go: pkg/apis/apps/kfdef/v1beta1/application_types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/... -O zz_generated.deepcopy \
-p pkg/apis/apps/kfdef/v1beta1/
pkg/apis/apps/kfdef/v1/zz_generated.deepcopy.go: pkg/apis/apps/kfdef/v1/application_types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/... -O zz_generated.deepcopy \
-p pkg/apis/apps/kfdef/v1/
pkg/apis/apps/plugins/gcp/v1alpha1/zz_generated.deepcopy.go: pkg/apis/apps/plugins/gcp/v1alpha1/types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp/... -O zz_generated.deepcopy \
-p pkg/apis/apps/plugins/gcp/v1alpha1/
pkg/apis/apps/plugins/aws/v1alpha1/zz_generated.deepcopy.go: pkg/apis/apps/plugins/aws/v1alpha1/types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/aws/... -O zz_generated.deepcopy \
-p pkg/apis/apps/plugins/aws/v1alpha1/
pkg/kfconfig/zz_generated.deepcopy.go: pkg/kfconfig/types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/kfconfig/... -O zz_generated.deepcopy \
-p pkg/kfconfig/
pkg/kfconfig/awsplugin/zz_generated.deepcopy.go: pkg/kfconfig/awsplugin/types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/kfconfig/awsplugin/... -O zz_generated.deepcopy \
-p pkg/kfconfig/awsplugin/
pkg/kfconfig/gcpplugin/zz_generated.deepcopy.go: pkg/kfconfig/gcpplugin/types.go
${GOPATH}/bin/deepcopy-gen -h hack/boilerplate.go.txt -i github.com/kubeflow/kfctl/v3/pkg/kfconfig/gcpplugin/... -O zz_generated.deepcopy\
-p pkg/kfconfig/gcpplugin/
deepcopy: ${GOPATH}/bin/deepcopy-gen config/zz_generated.deepcopy.go \
pkg/apis/apps/kfdef/v1alpha1/zz_generated.deepcopy.go \
pkg/apis/apps/kfdef/v1beta1/zz_generated.deepcopy.go \
pkg/apis/apps/kfdef/v1/zz_generated.deepcopy.go \
pkg/apis/apps/plugins/gcp/v1alpha1/zz_generated.deepcopy.go \
pkg/apis/apps/plugins/aws/v1alpha1/zz_generated.deepcopy.go \
pkg/kfconfig/zz_generated.deepcopy.go \
pkg/kfconfig/awsplugin/zz_generated.deepcopy.go \
pkg/kfconfig/gcpplugin/zz_generated.deepcopy.go
build: build-kfctl
build-kfctl: deepcopy generate fmt vet
# TODO(swiftdiaries): figure out import conflict errors for windows
#CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ${GO} build -gcflags '-N -l' -ldflags "-X main.VERSION=$(TAG)" -o bin/windows/kfctl.exe cmd/kfctl/main.go
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 ${GO} build -gcflags '-N -l' -ldflags "-X main.VERSION=${TAG}" -o bin/darwin/kfctl cmd/kfctl/main.go
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 ${GO} build -gcflags '-N -l' -ldflags "-X main.VERSION=$(TAG)" -o bin/linux/kfctl cmd/kfctl/main.go
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 ${GO} build -gcflags '-N -l' -ldflags "-X main.VERSION=$(TAG)" -o bin/arm64/kfctl cmd/kfctl/main.go
CGO_ENABLED=0 GOOS=linux GOARCH=ppc64le ${GO} build -gcflags '-N -l' -ldflags "-X main.VERSION=$(TAG)" -o bin/ppc64le/kfctl cmd/kfctl/main.go
cp bin/$(ARCH)/kfctl bin/kfctl
# Fast rebuilds useful for development.
# Does not regenerate code; assumes you already ran build-kfctl once.
build-kfctl-fast: fmt vet
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 ${GO} build -gcflags '-N -l' -ldflags "-X main.VERSION=$(TAG)" -o bin/linux/kfctl cmd/kfctl/main.go
# Release tarballs suitable for upload to GitHub release pages
build-kfctl-tgz: build-kfctl
chmod a+rx ./bin/kfctl
rm -f bin/*.tgz
cd bin/linux && tar -cvzf kfctl_$(TAG)_linux.tar.gz ./kfctl
cd bin/darwin && tar -cvzf kfctl_${TAG}_darwin.tar.gz ./kfctl
cd bin/arm64 && tar -cvzf kfctl_${TAG}_arm64.tar.gz ./kfctl
cd bin/ppc64le && tar -cvzf kfctl_${TAG}_ppc64le.tar.gz ./kfctl
build-and-push-operator: build-operator push-operator
build-push-update-operator: build-operator push-operator update-operator-image
# Build operator image
build-operator:
go mod vendor
# Fix duplicated logrus library (Sirupsen/logrus and sirupsen/logrus) bug
# due to the two different logrus versions that kfctl is using.
pushd vendor/github.com/Sirupsen/logrus/ && \
echo '\
// +build linux aix\n\
package logrus\n\
import "golang.org/x/sys/unix"\n\
func isTerminal(fd int) bool {\n\
_, err := unix.IoctlGetTermios(fd, unix.TCGETS)\n\
return err == nil\n\
} ' > terminal_check_unix.go && \
popd
ifneq ($(DOCKERFILE), Dockerfile)
pushd build &&\
cp Dockerfile Dockerfile.bckp &&\
cp ${DOCKERFILE} Dockerfile &&\
popd
endif
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 ${GO} build -a -o build/_output/bin/$(OPERATOR_BINARY_NAME) cmd/manager/main.go
${IMAGE_BUILDER} build build -t ${OPERATOR_IMG}
ifneq ($(DOCKERFILE), Dockerfile)
pushd build &&\
cp Dockerfile.bckp Dockerfile &&\
popd
endif
# push operator image and update deployment files.
push-operator:
${IMAGE_BUILDER} push ${OPERATOR_IMG}
update-operator-image:
# Use perl instead of sed to avoid OSX/Linux compatibility issue:
# https://stackoverflow.com/questions/34533893/sed-command-creating-unwanted-duplicates-of-file-with-e-extension
perl -pi -e 's@image: .*@image: '"${OPERATOR_IMG}"'@' ./deploy/operator.yaml
# push the releases to a GitHub page
push-to-github-release: build-kfctl-tgz
github-release upload \
--user kubeflow \
--repo kubeflow \
--tag $(TAG) \
--name "kfctl_$(TAG)_linux.tar.gz" \
--file bin/linux/kfctl_$(TAG)_linux.tar.gz
github-release upload \
--user kubeflow \
--repo kubeflow \
--tag $(TAG) \
--name "kfctl_$(TAG)_darwin.tar.gz" \
--file bin/darwin/kfctl_$(TAG)_darwin.tar.gz
github-release upload \
--user kubeflow \
--repo kubeflow \
--tag $(TAG) \
--name "kfctl_$(TAG)_arm64.tar.gz" \
--file bin/arm64/kfctl_$(TAG)_arm64.tar.gz
github-release upload \
--user kubeflow \
--repo kubeflow \
--tag $(TAG) \
--name "kfctl_$(TAG)_ppc64le.tar.gz" \
--file bin/ppc64le/kfctl_$(TAG)_ppc64le.tar.gz
build-kfctl-container:
DOCKER_BUILDKIT=1 docker build \
--build-arg REPO="$(REPO)" \
--build-arg BRANCH=$(BRANCH) \
--build-arg GOLANG_VERSION=$(GOLANG_VERSION) \
--build-arg VERSION=$(TAG) \
--target=$(KFCTL_TARGET) \
--tag $(KFCTL_IMG)/builder:$(TAG) .
@echo Built $(KFCTL_IMG)/builder:$(TAG)
mkdir -p bin
docker create \
--name=temp_kfctl_container \
$(KFCTL_IMG)/builder:$(TAG)
docker cp temp_kfctl_container:/usr/local/bin/kfctl ./bin/kfctl
docker rm temp_kfctl_container
@echo Exported kfctl binary to bin/kfctl
# build containers using GCLOUD_PROJECT
build-gcb:
gcloud --project=$(GCLOUD_PROJECT)\
builds submit \
--machine-type=n1-highcpu-32 \
--substitutions=TAG_NAME=$(TAG)
--config=cloudbuild.yaml .
# Build but don't attach the latest tag. This allows manual testing/inspection of the image
# first.
push: build
docker push $(BOOTSTRAPPER_IMG):$(TAG)
@echo Pushed $(BOOTSTRAPPER_IMG):$(TAG)
push-latest: push
gcloud container images add-tag --quiet $(BOOTSTRAPPER_IMG):$(TAG) $(BOOTSTRAPPER_IMG):latest --verbosity=info
echo created $(BOOTSTRAPPER_IMG):latest
push-kfctl-container: build-kfctl-container
docker push $(KFCTL_IMG):$(TAG)
@echo Pushed $(KFCTL_IMG):$(TAG)
push-kfctl-container-latest: push-kfctl-container
gcloud container images add-tag --quiet $(KFCTL_IMG):$(TAG) $(KFCTL_IMG):latest --verbosity=info
@echo created $(KFCTL_IMG):latest
install: build-kfctl dockerfordesktop.so
@echo copying bin/kfctl to /usr/local/bin
@cp bin/kfctl /usr/local/bin
run-kfctl-container: build-kfctl-container
docker run $(MOUNT_KUBE) $(MOUNT_GCP) --entrypoint /bin/sh -it $(KFCTL_IMG):$(TAG)
#***************************************************************************************************
# Build a docker container that can be used to build kfctl
#
# The rules in this section are used to build the docker image that provides
# a suitable go build environment for kfctl
build-builder-container:
docker build \
--build-arg GOLANG_VERSION=$(GOLANG_VERSION) \
--target=builder \
--tag $(KFCTL_IMG):$(TAG) .
@echo Built $(KFCTL_IMG):$(TAG)
# build containers using GCLOUD_PROJECT
build-builder-container-gcb:
gcloud --project=$(GCLOUD_PROJECT) \
builds submit \
--machine-type=n1-highcpu-32 \
--substitutions=TAG_NAME=$(TAG),_TARGET=builder \
--config=cloudbuild.yaml .
#***************************************************************************************************
clean:
rm -rf test && mkdir test
doc:
doctoc ./cmd/kfctl/README.md README.md k8sSpec/README.md developer_guide.md
#**************************************************************************************************
# checks licenses
check-licenses:
./third_party/check-license.sh
# rules to run unittests
#
test: build-kfctl check-licenses
go test ./... -v
# Unit test invoked by Github Action
go-unittests-junit:
echo Running tests ... junit_file=$(JUNIT_FILE)
mkdir -p $(JUNIT_DIR)
go test ./... -v 2>&1 | go-junit-report > $(JUNIT_FILE) --set-exit-code
#***************************************************************************************************
test-init: clean install dockerfordesktop.init minikube.init gcp.init none.init-no-platform
test-generate: test-init dockerfordesktop.generate minikube.generate gcp.generate none.generate
test-apply: test-generate dockerfordesktop.apply minikube.apply gcp.apply none.apply
================================================
FILE: OWNERS
================================================
approvers:
- adrian555
- animeshsingh
- crobby
- Jeffwan
- PatrickXYS
- vpavlin
- yanniszark
reviewers:
- adrian555
- pdmack
- tomcli
================================================
FILE: README.md
================================================
# kfctl
_kfctl_ is the control plane for deploying and managing Kubeflow. The primary mode of deployment is to use [kfctl as a CLI](https://github.com/kubeflow/kfctl/tree/master/cmd/kfctl) with KFDef configurations for different Kubernetes flavours to deploy and manage Kubeflow. Please also look at the docs on [Kubeflow website](https://www.kubeflow.org/docs/started/getting-started/) for deployments options for different cloud providers
Additionally, we have also introduced [Kubeflow Operator](./operator.md) in incubation mode, which apart from deploying Kubeflow, will perform additional functionalities around monitoring the deployment for consistency etc.
================================================
FILE: build/Dockerfile
================================================
ARG binary_name=kfctl
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest AS build
ENV OPERATOR=/usr/local/bin/${binary_name} \
USER_UID=1001 \
USER_NAME=kfctl \
HOMEDIR=/homedir
# install operator binary
COPY _output/bin/${binary_name} ${OPERATOR}
COPY bin /usr/local/bin
RUN /usr/local/bin/user_setup
RUN /usr/local/bin/entrypoint
FROM gcr.io/distroless/base-debian10
ENV OPERATOR=/usr/local/bin/${binary_name} \
USER_UID=1001 \
USER_NAME=kfctl \
HOMEDIR=/homedir
COPY --from=build /usr/local/bin/${binary_name} ${OPERATOR}
COPY --from=build /etc/passwd /etc/passwd
COPY --from=build ${HOMEDIR} ${HOME}
ENTRYPOINT ["${OPERATOR}"]
USER ${USER_UID}
================================================
FILE: build/Dockerfile.ubi
================================================
ARG binary_name=kfctl
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
ENV OPERATOR=/usr/local/bin/${binary_name}\
HOME=/opt/${binary_name}
RUN mkdir -p ${HOME} &&\
chown 1001:0 ${HOME} &&\
chmod ug+rwx ${HOME}
WORKDIR ${HOME}
COPY _output/bin/${binary_name} ${OPERATOR}
ENTRYPOINT ["${OPERATOR}"]
USER 1001
================================================
FILE: cmd/kfctl/.gitignore
================================================
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Kubernetes Generated files - skip generated files, except for vendored files
!vendor/**/zz_generated.*
# editor and IDE paraphernalia
.idea
*.swp
*.swo
*~
================================================
FILE: cmd/kfctl/OWNERS
================================================
approvers:
- jlewi
- yanniszark
================================================
FILE: cmd/kfctl/README.md
================================================
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [kfctl golang client](#kfctl-golang-client)
- [Overview](#overview)
- [Requirements](#requirements)
- [API and Packaging](#api-and-packaging)
- [KfApp Interface](#kfapp-interface)
- [Usage](#usage)
- [Subcommands](#subcommands)
- [**init**](#init)
- [**generate**](#generate)
- [**apply**](#apply)
- [**delete**](#delete)
- [Extending kfctl](#extending-kfctl)
- [Building the sample plugin](#building-the-sample-plugin)
- [Testing](#testing)
- [Testing kfctl (tests plugin functionality, `kfctl init`, `kfctl generate`)](#testing-kfctl-tests-plugin-functionality-kfctl-init-kfctl-generate)
- [Testing `kfctl init` for all platforms](#testing-kfctl-init-for-all-platforms)
- [Testing `kfctl generate` for all platforms](#testing-kfctl-generate-for-all-platforms)
- [gcp-click-to-deploy (no changes)](#gcp-click-to-deploy-no-changes)
- [golang modules and versioned packages](#golang-modules-and-versioned-packages)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# kfctl golang client
## Overview
The new `kfctl` client replaces `kfctl.sh` and is implemented in golang.
**Note**: This README.md will be updated on an ongoing basis to reflect features, bug fixes.
## Requirements
- Create a common API for the UI (gcp-click-to-deploy) and `kfctl` (`KfApp`).
- Separate different platform implementations of the [KfApp Interface](#kfapp-interface).
- Separate different package manager implementations of the [KfApp Interface](#kfapp-interface).
- Allow new platforms to be added to kfctl without rebuilding or reshipping kfctl (see [Extending kfctl](#extending-kfctl) below).
- Do not change existing `REST` entrypoints or the `KsService` interface in `ksServer.go` at this time.
- Package `KfApp` interface and related types for ease of use by kfctl and (later) gcp-click-to-deploy.
## API and Packaging
### KfApp Interface
The `KfApp` golang Interface is defined below:
```golang
type ResourceEnum string
const (
ALL ResourceEnum = "all"
K8S ResourceEnum = "k8s"
PLATFORM ResourceEnum = "platform"
)
//
// KfApp is used by commands under bootstrap/cmd/{bootstrap,kfctl}. KfApp provides a common
// API for different platforms implementations like gcp and minikube.
// KfApp is also implemented by different package managers (ksonnet, kustomize).
//
type KfApp interface {
Apply(resources ResourceEnum, options map[string]interface{}) error
Delete(resources ResourceEnum, options map[string]interface{}) error
Generate(resources ResourceEnum, options map[string]interface{}) error
Init(options map[string]interface{}) error
}
```
kfctl will statically include platforms that implement the KfApp interface.
These include:
- platform: **minikube**
- bootstrap/v3/pkg/client/minikube/minikube.go
- platform: **gcp**
- bootstrap/v3/pkg/client/gcp/gcp.go
kfctl also statically links package managers that are used by the platforms.
This includes:
- package manager: **kustomize**
- bootstrap/v3/pkg/client/kustomize/kustomize.go
kfctl can dynamically load platforms and package managers that are not statically linked, as
described below in [Extending kfctl](#extending-kfctl).
## Usage
```
A client CLI to create kubeflow applications for specific platforms or 'on-prem'
to an existing k8s cluster.
Usage:
kfctl [command]
Available Commands:
apply Deploy a generated kubeflow application.
completion Generate shell completions
delete Delete a kubeflow application.
generate Generate a kubeflow application where resources is one of 'platform|k8s|all'.
help Help about any command
init Create a kubeflow application under <[path/]name>
show Show a generated kubeflow application.
version Print the version of kfctl.
Flags:
-h, --help help for kfctl
Use "kfctl [command] --help" for more information about a command.
```
Typical use-case, non-platform specific.
```sh
kfctl init ~/myapp && \
cd ~/myapp && \
kfctl generate all && \
kfctl apply all
```
## Subcommands
### **init**
(kubeflow/bootstrap/cmd/kfctl/cmd/init.go)
```
Create a kubeflow application under <[path/]name>. The <[path/]name> argument can either be a full path
or a <name>. If just <name>, a directory <name> will be created in the current directory.
Usage:
kfctl init <[path/]name> [flags]
Flags:
--config string Static config file to use. Can be either a local path or a URL.
For example:
--config=https://raw.githubusercontent.com/kubeflow/kubeflow/master/bootstrap/config/kfctl_platform_existing.yaml
--config=kfctl_platform_gcp.yaml
--disable_usage_report disable_usage_report disable anonymous usage reporting.
-h, --help help for init
-n, --namespace string namespace where kubeflow will be deployed (default "kubeflow")
--package-manager string 'kustomize[@version]' (default "kustomize")
-p, --platform string one of 'aws|gcp|minikube'
--project string name of the gcp project if --platform gcp
-r, --repo string local github kubeflow repo
--skip-init-gcp-project Set if you want to skip project initialization. Only meaningful if --platform gcp. Default to false
--use_basic_auth use_basic_auth use basic auth service instead of IAP.
--use_istio use_istio use istio for auth and traffic routing. (default true)
-V, --verbose verbose output default is false
-v, --version string desired version of Kubeflow or master if not specified. Version can be master (eg --version master) or a git tag (eg --version=v0.5.0), or a PR (eg --version pull/<id>). (default "master")
```
### **generate**
(kubeflow/bootstrap/cmd/kfctl/cmd/generate.go)
```
Generate a kubeflow application where resources is one of 'platform|k8s|all'.
platform: non kubernetes resources (eg --platform gcp)
k8s: kubernetes resources
all: both platform and k8s
The default is 'all' for any selected platform.
Usage:
kfctl generate [all(=default)|k8s|platform] [flags]
Flags:
--email string email if '--platform gcp'
-h, --help help for generate
--hostname string hostname if '--platform gcp'
--ipName string ipName if '--platform gcp'
--mount-local mount-local if '--platform minikube'
-V, --verbose verbose output default is false
--zone string zone if '--platform gcp' (default "us-east1-d")
```
### **apply**
(kubeflow/bootstrap/cmd/kfctl/cmd/apply.go)
```
Deploy a generated kubeflow application.
Usage:
kfctl apply [all(=default)|k8s|platform] [flags]
Flags:
-h, --help help for apply
-V, --verbose verbose output default is false
$ ☞
$ ☞
$ ☞
$ ☞
$ ☞ kfctl help apply
Deploy a generated kubeflow application.
Usage:
kfctl apply [all(=default)|k8s|platform] [flags]
Flags:
-h, --help help for apply
-V, --verbose verbose output default is false
```
### **delete**
(kubeflow/bootstrap/cmd/kfctl/cmd/delete.go)
```
Delete a kubeflow application.
Usage:
kfctl delete [all(=default)|k8s|platform] [flags]
Flags:
-h, --help help for delete
-V, --verbose verbose output default is false
```
### **set-image-name**
(kubeflow/bootstrap/cmd/kfctl/cmd/set-image-name.go)
```text
Sets custom image names for kubeflow components.
Replaces the image name in kubeflow manifests with the specified prefix, to support custom image registries.
It assumes that all components specify images in kustomization.yaml, base or overlay. Expected prefix format is
<registry>[:port][/component]*
The filter flag sets the custom image name only for images with matching prefix.
The flatten flag discards both registry and name components except for the last one, to support registries with a flat hierarchical path.
Usage:
kfctl set-image-name <prefix> [flags]
Flags:
-f, --filter string Only set name for images with matching prefix
--flatten Set to true for registries not supporting hierarchical paths with more than two components
-h, --help help for set-image-name
-V, --verbose Enable verbose output
```
---
## Extending kfctl
`kfctl` can be extended to work with new platforms or package managers without requiring recompilation.
An example is under bootstrap/cmd/plugins/dockerfordesktop/dockerfordesktop.go. A particular platform
provides a shared library (.so) under the env var `PLUGINS_ENVIRONMENT`
that kfctl would load and execute. The shared library needs to define
```
func GetKfApp(options map[string]interface{}) kftypes.KfApp
```
where the return type implements the [KfApp Interface](#kfapp-interface).
In this sample, running
```
kfctl init ~/dockerfordesktop --platform docker-for-desktop
```
will result in kfctl loading $PLUGINS_ENVIRONMENT/dockerfordesktop.so and calling its methods that
implement the KfApp Interface.
### Building the sample plugin
```
make build-dockerfordesktop-plugin
```
## Testing
### Testing kfctl (tests plugin functionality, `kfctl init`, `kfctl generate`)
```
make test-kfctl
```
### Testing `kfctl init` for all platforms
```
make test-init
```
### Testing `kfctl generate` for all platforms
```
make test-generate
```
## gcp-click-to-deploy (no changes)
References to Ksonnet types have been removed
## golang modules and versioned packages
kustomize leverages golang modules by declaring a 'v3' version in go.mod
================================================
FILE: cmd/kfctl/cmd/alpha.go
================================================
package cmd
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var alphaCfg = viper.New()
// alphaCmd represents the commands that are in alpha
var alphaCmd = &cobra.Command{
Use: "alpha",
Short: "Alpha kfctl features.",
Long: `Alpha kfctl features.`,
}
func init() {
rootCmd.AddCommand(alphaCmd)
}
================================================
FILE: cmd/kfctl/cmd/apply.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
ep "github.com/jlewi/cloud-endpoints-controller/pkg"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/kfapp/coordinator"
"github.com/kubeflow/kfctl/v3/pkg/kfupgrade"
"github.com/kubeflow/kfctl/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var applyCfg = viper.New()
var kfApp kftypes.KfApp
var err error
var kubeContext = ""
// KFDef example configs to be printed out from apply --help
const (
awsConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_aws.v1.2.0.yaml"
gcpConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v1.0-branch/kfdef/kfctl_gcp_iap.v1.0.0.yaml"
istioDexConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_istio_dex.v1.2.0.yaml"
k8sConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v1.2-branch/kfdef/kfctl_k8s_istio.v1.2.0.yaml"
)
// applyCmd represents the apply command
var applyCmd = &cobra.Command{
Use: "apply -f ${CONFIG}",
Short: "deploys a kubeflow application.",
Long: `'kfctl apply' builds and deploys a kubeflow application from a KFDef config.` + "\n" +
`To install run -> ` + ColorPrint("kfctl apply -f ${CONFIG}") + "\n" +
`For more information, run 'kfctl apply -h' or read the docs at www.kubeflow.org.`,
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.InfoLevel)
if applyCfg.GetBool(string(kftypes.VERBOSE)) != true {
log.SetLevel(log.WarnLevel)
}
// Load config from exisiting app.yaml
if configFilePath == "" {
return fmt.Errorf("Must pass in -f configFile")
}
kind, err := utils.GetObjectKindFromUri(configFilePath)
if err != nil {
return fmt.Errorf("Cannot determine the object kind: %v", err)
}
switch kind {
case string(kftypes.KFDEF):
kfApp, err = coordinator.NewLoadKfAppFromURI(configFilePath)
if err != nil {
return fmt.Errorf("failed to build kfApp from URI %s: %v", configFilePath, err)
}
if err := kfApp.Apply(kftypes.ALL); err != nil {
return fmt.Errorf("failed to apply: %s", err)
}
log.Info("Applied the configuration Successfully!")
return nil
case string(kftypes.KFUPGRADE):
log.Warnf("Support for kind %s is deprecated and will be removed in subsequent versions", kftypes.KFUPGRADE)
kfUpgrade, err := kfupgrade.NewKfUpgrade(configFilePath)
if err != nil {
return fmt.Errorf("couldn't load KfUpgrade: %v", err)
}
err = kfUpgrade.Apply()
if err != nil {
return fmt.Errorf("couldn't apply KfUpgrade: %v", err)
}
return nil
case ep.Kind:
return ep.Process(configFilePath, kubeContext)
default:
return fmt.Errorf("Unsupported object kind: %v", kind)
}
},
}
func init() {
rootCmd.AddCommand(applyCmd)
applyCfg.SetConfigName("app")
applyCfg.SetConfigType("yaml")
// Config file option
applyCmd.PersistentFlags().StringVarP(&configFilePath, string(kftypes.FILE), "f", "",
`Static config file to use. Can be either a local path:
export CONFIG=./kfctl_gcp_iap.yaml
or a URL:
export CONFIG=`+gcpConfig+`
export CONFIG=`+istioDexConfig+`
export CONFIG=`+awsConfig+`
export CONFIG=`+k8sConfig+`
kfctl apply -V --file=${CONFIG}`)
// verbose output
applyCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
applyCmd.Flags().StringVar(&kubeContext, "context", "", "Optional kubernetes context to use when applying resources. Currently not used by KFDef resources.")
bindErr := applyCfg.BindPFlag(string(kftypes.VERBOSE), applyCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
}
================================================
FILE: cmd/kfctl/cmd/build.go
================================================
// Copyright © 2019 NAME HERE <EMAIL ADDRESS>
//
// 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 cmd
import (
"fmt"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/kfapp/coordinator"
"github.com/kubeflow/kfctl/v3/pkg/kfupgrade"
"github.com/kubeflow/kfctl/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var configFilePath string
var buildCfg = viper.New()
// buildCmd represents the build command
var buildCmd = &cobra.Command{
Use: "build",
Short: "Builds a KF App from a config file",
Long: `Builds a KF App from a config file`,
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.InfoLevel)
if buildCfg.GetBool(string(kftypes.VERBOSE)) != true {
log.SetLevel(log.WarnLevel)
}
kind, err := utils.GetObjectKindFromUri(configFilePath)
if err != nil {
return fmt.Errorf("Cannot determine the object kind: %v", err)
}
var kfApp kftypes.KfApp
switch kind {
case string(kftypes.KFDEF):
kfApp, err = coordinator.NewLoadKfAppFromURI(configFilePath)
if err != nil {
return fmt.Errorf("failed to build kfApp from URI %s: %v", configFilePath, err)
}
case string(kftypes.KFUPGRADE):
log.Warnf("Support for kind %s is deprecated and will be removed in subsequent versions", kftypes.KFUPGRADE)
kfApp, err := kfupgrade.NewKfUpgrade(configFilePath)
if err != nil {
return fmt.Errorf("couldn't load KfUpgrade: %v", err)
}
if err := kfApp.Generate(); err != nil {
return fmt.Errorf("couldn't generate KfApp: %v", err)
}
default:
return fmt.Errorf("Unsupported object kind: %v", kind)
}
if buildCfg.GetBool(string(kftypes.DUMP)) == true {
kfApp.Dump(kftypes.ALL)
}
return nil
},
}
func init() {
rootCmd.AddCommand(buildCmd)
buildCfg.SetConfigName("app")
buildCfg.SetConfigType("yaml")
// Config file option
buildCmd.PersistentFlags().StringVarP(&configFilePath, string(kftypes.FILE), "f", "",
`Static config file to use. Can be either a local path:
export CONFIG=./kfctl_gcp_iap.yaml
or a URL:
export CONFIG=`+gcpConfig+`
export CONFIG=`+istioDexConfig+`
export CONFIG=`+awsConfig+`
export CONFIG=`+k8sConfig+`
kfctl build -V --file=${CONFIG}`)
// verbose output
buildCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
bindErr := buildCfg.BindPFlag(string(kftypes.VERBOSE), buildCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
// dump flag
buildCmd.Flags().BoolP(string(kftypes.DUMP), "d", false,
string(kftypes.DUMP)+" manifests to stdout, default is false")
bindErr = buildCfg.BindPFlag(string(kftypes.DUMP), buildCmd.Flags().Lookup(string(kftypes.DUMP)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
}
================================================
FILE: cmd/kfctl/cmd/completion.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"github.com/spf13/cobra"
"os"
)
var completionCmd = &cobra.Command{
Use: "completion [shell]",
Args: cobra.OnlyValidArgs,
ValidArgs: []string{"bash", "zsh"},
Short: "Generate shell completions",
Long: `To load completion run
. <(kfctl completion)
To configure your bash shell to load completions for each session add to your bashrc
# ~/.bashrc or ~/.profile
. <(kfctl completion)
If you want to use zsh instead, do the following:
$ kfctl completion zsh > _kfctl
Then move _kfctl into $fpath and run compinit.
`,
Run: func(cmd *cobra.Command, args []string) {
shell := "bash"
if len(args) > 0 {
shell = args[0]
}
switch shell {
case "zsh":
rootCmd.GenZshCompletion(os.Stdout)
default:
rootCmd.GenBashCompletion(os.Stdout)
}
},
}
func init() {
rootCmd.AddCommand(completionCmd)
}
================================================
FILE: cmd/kfctl/cmd/delete.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
"strings"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/kfapp/coordinator"
kfloaders "github.com/kubeflow/kfctl/v3/pkg/kfconfig/loaders"
kfutils "github.com/kubeflow/kfctl/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var deleteCfg = viper.New()
// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
Args: cobra.NoArgs,
Use: "delete",
Short: "Delete a kubeflow application.",
Long: `Delete a kubeflow application.`,
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.InfoLevel)
if deleteCfg.GetBool(string(kftypes.VERBOSE)) != true {
log.SetLevel(log.WarnLevel)
}
// Load config from exisiting app.yaml
if configFilePath == "" {
return fmt.Errorf("Must pass in -f configFile")
}
// Writes annotations to pass information to kfapps.
forceDeleteAnn := strings.Join([]string{kfutils.KfDefAnnotation, kfutils.ForceDelete}, "/")
annValue := "false"
if deleteCfg.GetBool(string(kftypes.FORCE_DELETION)) == true {
annValue = "true"
}
setAnnotations(configFilePath, map[string]string{
forceDeleteAnn: annValue,
})
kfApp, err = coordinator.NewLoadKfAppFromURI(configFilePath)
if err != nil || kfApp == nil {
return fmt.Errorf("error loading kfapp: %v", err)
}
deleteErr := kfApp.Delete(kftypes.ALL)
if deleteErr != nil {
return fmt.Errorf("couldn't delete KfApp: %v", deleteErr)
}
return nil
},
}
func init() {
rootCmd.AddCommand(deleteCmd)
deleteCfg.SetConfigName("app")
deleteCfg.SetConfigType("yaml")
deleteCmd.PersistentFlags().StringVarP(&configFilePath, string(kftypes.FILE), "f", "",
"The local config file of KfDef.")
// verbose output
deleteCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
bindErr := deleteCfg.BindPFlag(string(kftypes.VERBOSE), deleteCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
// force deletion, runs best-effort deletion and skips non-fatal checks.
deleteCmd.Flags().Bool(string(kftypes.FORCE_DELETION), false,
string(kftypes.FORCE_DELETION)+" output default is false")
bindErr = deleteCfg.BindPFlag(string(kftypes.FORCE_DELETION), deleteCmd.Flags().Lookup(string(kftypes.FORCE_DELETION)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.FORCE_DELETION), bindErr)
return
}
deleteCmd.Flags().Bool(string(kftypes.DELETE_STORAGE), false,
"Set if you want to delete app's storage cluster used for mlpipeline.")
bindErr = deleteCfg.BindPFlag(string(kftypes.DELETE_STORAGE), deleteCmd.Flags().Lookup(string(kftypes.DELETE_STORAGE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.DELETE_STORAGE), bindErr)
return
}
}
func setAnnotations(configPath string, annotations map[string]string) error {
config, err := kfloaders.LoadConfigFromURI(configPath)
if err != nil {
return err
}
anns := config.GetAnnotations()
if anns == nil {
anns = map[string]string{}
}
for ann, val := range annotations {
anns[ann] = val
}
config.SetAnnotations(anns)
return kfloaders.WriteConfigToFile(*config)
}
================================================
FILE: cmd/kfctl/cmd/generate.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
"github.com/spf13/cobra"
)
var generateDeprecationMessage = ColorPrint("'kfctl generate' has been replaced by 'kfctl build'") + "\n" +
`Please switch to new semantics.
To build a KFAPP run -> ` + ColorPrint("kfctl build -f ${CONFIG}") + "\n" +
`Then to install -> ` + ColorPrint("kfctl apply") + "\n" +
`For more information, run 'kfctl build -h' or read the docs at www.kubeflow.org.`
// generateCmd represents the generate command
var generateCmd = &cobra.Command{
Use: "generate",
Short: generateDeprecationMessage,
Long: generateDeprecationMessage,
RunE: func(cmd *cobra.Command, args []string) error {
return fmt.Errorf(generateDeprecationMessage)
},
}
func init() {
rootCmd.AddCommand(generateCmd)
}
================================================
FILE: cmd/kfctl/cmd/init.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
"github.com/fatih/color"
"github.com/spf13/cobra"
)
// ColorPrint Sprintf with yellow color
var ColorPrint = color.New(color.FgYellow).SprintFunc()
var initDeprecationMessage = ColorPrint("'kfctl init' has been removed.") + "\n" +
`Please switch to new semantics.
To install run -> ` + ColorPrint("kfctl apply -f ${CONFIG}") + "\n" +
`For more information, run 'kfctl apply -h' or read the docs at www.kubeflow.org.`
// initCmd represents the init command
var initCmd = &cobra.Command{
Use: "init",
Short: initDeprecationMessage,
Long: initDeprecationMessage,
RunE: func(cmd *cobra.Command, args []string) error {
return fmt.Errorf(initDeprecationMessage)
},
}
func init() {
rootCmd.AddCommand(initCmd)
}
================================================
FILE: cmd/kfctl/cmd/mirror.go
================================================
package cmd
import (
"github.com/spf13/cobra"
)
// alphaCmd represents the commands that are in alpha
var mirrorCmd = &cobra.Command{
Use: "mirror",
Short: "kfctl alpha mirror",
Long: `kfctl alpha mirror: `,
}
func init() {
alphaCmd.AddCommand(mirrorCmd)
}
================================================
FILE: cmd/kfctl/cmd/mirror_build.go
================================================
package cmd
import (
"fmt"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
mirrortypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/imagemirror/v1alpha1"
"github.com/kubeflow/kfctl/v3/pkg/mirror"
"github.com/kubeflow/kfctl/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"io/ioutil"
"os"
"sigs.k8s.io/yaml"
)
var outputFileName string
var directory string
var gcb bool
func init() {
replicateBuildCmd.Flags().StringVarP(&outputFileName, "output", "o", "",
`Name of the output pipeline file
kfctl alpha mirror build -o <name>`)
replicateBuildCmd.Flags().StringVarP(&directory, "directory", "d", "kustomize",
`The directory to search for kustomization files listing images to mirror
kfctl alpha mirror build -d <directory>`)
replicateBuildCmd.Flags().BoolVar(&gcb, "gcb", false, `Generate cloud build config`)
// verbose output
replicateBuildCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
bindErr := replicateBuildCfg.BindPFlag(string(kftypes.VERBOSE), replicateBuildCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
mirrorCmd.AddCommand(replicateBuildCmd)
}
var replicateBuildCfg = viper.New()
var replicateBuildCmd = &cobra.Command{
Use: "build <local_config_file_path> -o <pipeline_file>",
Short: "Generate tekton pipeline file which will replicate images to target registry.",
Long: `Generate tekton pipeline file which replicate images to target registry.
Image replication rules are defined in config file.
`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.WarnLevel)
if replicateBuildCfg.GetBool(string(kftypes.VERBOSE)) {
log.SetLevel(log.InfoLevel)
}
configFile := args[0]
isRemoteFile, err := utils.IsRemoteFile(configFile)
if err != nil {
return err
}
if isRemoteFile {
return fmt.Errorf("config file path should be non-empty local file.")
}
if outputFileName == "" {
return fmt.Errorf("You must specify an output file with -o")
}
if _, err := os.Stat(configFile); err != nil {
return err
}
confBytes, err := ioutil.ReadFile(configFile)
if err != nil {
return nil
}
replication := mirrortypes.Replication{}
if err := yaml.Unmarshal(confBytes, &replication); err != nil {
return err
}
for _, pattern := range replication.Spec.Patterns {
log.Infof("Context: %v; destination registry: %v", replication.Spec.Context, pattern.Dest)
if replication.Spec.Context == "" || pattern.Dest == "" {
return fmt.Errorf("Config: context and dest registry cannot be empty")
}
}
return mirror.GenerateMirroringPipeline(directory, replication.Spec, outputFileName, gcb)
},
}
================================================
FILE: cmd/kfctl/cmd/mirror_overwrite.go
================================================
package cmd
import (
"fmt"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/mirror"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var inputFileName string
func init() {
replicateOverwriteCmd.Flags().StringVarP(&inputFileName, "input", "i", "",
`Name of the input pipeline file
kfctl alpha mirror overwrite -o <name>`)
// verbose output
replicateOverwriteCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
bindErr := replicateOverwriteCfg.BindPFlag(string(kftypes.VERBOSE), replicateOverwriteCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
mirrorCmd.AddCommand(replicateOverwriteCmd)
}
var replicateOverwriteCfg = viper.New()
var replicateOverwriteCmd = &cobra.Command{
Use: "overwrite <registry>",
Short: "",
Long: `Read input tekton pipeline file with images replication info,
update images in kustomization.yaml: image:tag -> newImage:tag
`,
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.WarnLevel)
if replicateOverwriteCfg.GetBool(string(kftypes.VERBOSE)) {
log.SetLevel(log.InfoLevel)
}
if inputFileName == "" {
return fmt.Errorf("Please specify input tekton pipeline file by -i")
}
return mirror.UpdateKustomize(inputFileName)
},
}
================================================
FILE: cmd/kfctl/cmd/root.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/spf13/cobra"
"os"
)
func processResourceArg(args []string) (kftypes.ResourceEnum, error) {
if len(args) > 1 {
return kftypes.ALL, fmt.Errorf("unknown extra args %v", args[1:])
}
resources := kftypes.ALL
if len(args) == 1 {
switch kftypes.ResourceEnum(args[0]) {
case kftypes.ALL:
case kftypes.K8S:
resources = kftypes.K8S
case kftypes.PLATFORM:
resources = kftypes.PLATFORM
default:
return kftypes.ALL, fmt.Errorf("unknown argument %v", args[0])
}
}
return resources, nil
}
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "kfctl",
Short: "A client CLI to create kubeflow applications",
Long: `A client CLI to create kubeflow applications for specific platforms or 'on-prem'
to an existing k8s cluster.`,
}
var (
// VERSION is set during build
VERSION string
)
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(version string) {
VERSION = version
if err := rootCmd.Execute(); err != nil {
fmt.Printf("kfctl exited with error: %+v", err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
}
// initConfig creates a Viper config file and set's it's name and type
func initConfig() {
}
================================================
FILE: cmd/kfctl/cmd/set-image-name.go
================================================
package cmd
import (
"fmt"
"os"
"path"
"path/filepath"
"regexp"
"sigs.k8s.io/kustomize/v3/pkg/image"
"strings"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/kfapp/kustomize"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)
var filter string
var flatten bool
func init() {
setImageNameCmd.Flags().StringVarP(&filter, "filter", "f", "", "Only set name for images with matching prefix")
setImageNameCmd.Flags().BoolVar(&flatten, "flatten", false, "Set to true for registries not supporting hierarchical paths with more than two components")
setImageNameCfg.SetConfigName("app")
setImageNameCfg.SetConfigType("yaml")
// verbose output
setImageNameCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
bindErr := setImageNameCfg.BindPFlag(string(kftypes.VERBOSE), setImageNameCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
alphaCmd.AddCommand(setImageNameCmd)
}
var setImageNameCfg = viper.New()
var setImageNameCmd = &cobra.Command{
Use: "set-image-name <prefix>",
Short: "Custom image names for kubeflow components",
Long: `Sets custom image names for kubeflow components.
Replaces the image name in kubeflow manifests with the specified prefix, to support custom image registries.
Changes are printed to stdout in the form of <old>=<new>, which can then be used to mirror the images.
It assumes that all components specify images in kustomization.yaml, base or overlay. Expected prefix format is
<registry>[:port][/component]*
The filter flag sets the custom image name only for images with matching prefix.
The flatten flag discards both registry and name components except for the last one, to support registries with a flat hierarchical path.
`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.WarnLevel)
if setImageNameCfg.GetBool(string(kftypes.VERBOSE)) {
log.SetLevel(log.InfoLevel)
}
log.Debugf("Using prefix %s (filter %s, flatten %t)\n", args[0], filter, flatten)
newNameComponents, err := parsePrefix(args[0])
if err != nil {
return err
}
return filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
log.Debugf("Looking for kustomization.yaml in %q\n", path)
absPath, err := filepath.Abs(path)
if err != nil {
return err
}
kustomizationFilePath := filepath.Join(absPath, "kustomization.yaml")
if _, err := os.Stat(kustomizationFilePath); err == nil {
kustomization := kustomize.GetKustomization(absPath)
for i, image := range kustomization.Images {
if !strings.HasPrefix(image.Name, filter) {
log.Infof("No filter match for %s, skipping\n", image.Name)
continue
}
newName := setImageName(image.Name, newNameComponents)
log.Infof("Replacing image name from %s to %s", image.Name, newName)
kustomization.Images[i].NewName = newName
fmt.Printf("%s=%s\n", imageToString(image), imageToString(kustomization.Images[i]))
}
if err := os.Remove(kustomizationFilePath); err != nil {
return err
}
data, err := yaml.Marshal(kustomization)
if err != nil {
return err
}
file, err := os.OpenFile(kustomizationFilePath, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
defer file.Close()
if _, err := file.Write(data); err != nil {
return err
}
}
return nil
}
return nil
})
},
}
func parsePrefix(prefix string) (map[string]string, error) {
prefixParser := regexp.MustCompile(`^(?P<host>(\w[\w-0-9]+\.)+\w+)(:(?P<port>\d+))?(/(?P<components>([\w-_/]*)))?$`)
match := prefixParser.FindStringSubmatch(prefix)
if len(match) == 0 {
return nil, fmt.Errorf("Unsupported prefix %s", prefix)
}
result := make(map[string]string)
for i, name := range prefixParser.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
return result, nil
}
func parseImageName(name string) map[string]string {
imageParser := regexp.MustCompile(`^((?P<host>(\w[\w-0-9]+\.)+\w+)(:(?P<port>\d+))?/)?((?P<components>([\w-_]+/)*([\w-_]+))/)?(?P<image>[\w-_]*)(:(?P<tag>.*))?$`)
match := imageParser.FindStringSubmatch(name)
if len(match) == 0 {
return nil
}
result := make(map[string]string)
for i, name := range imageParser.SubexpNames() {
if i != 0 && name != "" {
result[name] = match[i]
}
}
return result
}
func setImageName(oldName string, newNameComponents map[string]string) string {
oldNameComponents := parseImageName(oldName)
domainSlice := []string{newNameComponents["host"]}
if newNameComponents["port"] != "" {
domainSlice = append(domainSlice, newNameComponents["port"])
}
domain := strings.Join(domainSlice, ":")
imageSlice := []string{oldNameComponents["image"]}
if oldNameComponents["tag"] != "" {
imageSlice = append(imageSlice, oldNameComponents["tag"])
}
image := strings.Join(imageSlice, ":")
resultSlice := []string{domain, newNameComponents["components"]}
if !flatten {
resultSlice = append(resultSlice, oldNameComponents["components"])
}
resultSlice = append(resultSlice, image)
return path.Join(resultSlice...)
}
func imageToString(image image.Image) string {
res := image.Name
if image.NewName != "" {
res = image.NewName
}
if image.Digest != "" {
res = res + "@" + image.Digest
} else if image.NewTag != "" {
res = res + ":" + image.NewTag
} else {
res = res + ":latest"
}
return res
}
================================================
FILE: cmd/kfctl/cmd/set-image-name_test.go
================================================
package cmd
import (
"reflect"
"sigs.k8s.io/kustomize/v3/pkg/image"
"testing"
)
func Test_imageToString(t *testing.T) {
tests := []struct {
name string
image image.Image
want string
}{
{
name: "docker-newtag",
image: image.Image{
Name: "mysql",
NewTag: "15.0",
},
want: "mysql:15.0",
},
{
name: "docker-digest",
image: image.Image{
Name: "mysql",
Digest: "sha256:5645412634544",
},
want: "mysql@sha256:5645412634544",
},
{
name: "gcr-newname-tag",
image: image.Image{
Name: "gcr.io/kubeflow/katib",
NewName: "gcr.io/myproject/katib",
NewTag: "15.0",
},
want: "gcr.io/myproject/katib:15.0",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := imageToString(test.image)
if got != test.want {
t.Fatalf("Got: %s. Want %s.", got, test.want)
}
})
}
}
func Test_parseImageName(t *testing.T) {
tests := []struct {
name string
input string
want map[string]string
}{
{name: "invalid random", input: "random text", want: nil},
{name: "invalid", input: "gcr.io", want: nil},
{name: "image", input: "mysql", want: map[string]string{"components": "", "host": "", "port": "", "image": "mysql", "tag": ""}},
{name: "image:tag", input: "mysql:latest", want: map[string]string{"components": "", "host": "", "port": "", "image": "mysql", "tag": "latest"}},
{name: "repository/image:tag", input: "argoproj/argoui:v2.3.0", want: map[string]string{"components": "argoproj", "host": "", "port": "", "image": "argoui", "tag": "v2.3.0"}},
{
name: "registry/repository/image:tag",
input: "gcr.io/kubeflow-images-public/admission-webhook:v20190520-v0-139-gcee39dbc-dirty-0d8f4c",
want: map[string]string{
"components": "kubeflow-images-public", "host": "gcr.io", "port": "", "image": "admission-webhook", "tag": "v20190520-v0-139-gcee39dbc-dirty-0d8f4c",
},
},
{
name: "registry/nested/repository/image",
input: "gcr.io/kubeflow-images-public/kubernetes-sigs/application",
want: map[string]string{
"components": "kubeflow-images-public/kubernetes-sigs", "host": "gcr.io", "port": "", "image": "application", "tag": "",
},
},
{
name: "registry/nested/repository/image:tag",
input: "gcr.io/stackdriver-prometheus/stackdriver-prometheus:release-0.4.2",
want: map[string]string{
"components": "stackdriver-prometheus", "host": "gcr.io", "port": "", "image": "stackdriver-prometheus", "tag": "release-0.4.2",
},
},
{
name: "registry:port/nested/repository/image:tag",
input: "gcr.io:443/test/kubeflow-images-public/admission-webhook:v20190520-v0-139-gcee39dbc-dirty-0d8f4c",
want: map[string]string{
"components": "test/kubeflow-images-public", "host": "gcr.io", "port": "443", "image": "admission-webhook", "tag": "v20190520-v0-139-gcee39dbc-dirty-0d8f4c",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := parseImageName(tt.input); !reflect.DeepEqual(got, tt.want) {
t.Errorf("parseImageName() = %v, want %v", got, tt.want)
}
})
}
}
func Test_parsePrefix(t *testing.T) {
tests := []struct {
name string
prefix string
want map[string]string
wantErr bool
}{
{name: "host", prefix: "test.io", wantErr: false, want: map[string]string{"host": "test.io", "port": "", "components": ""}},
{name: "host with port", prefix: "test.io:7999", wantErr: false, want: map[string]string{"host": "test.io", "port": "7999", "components": ""}},
{name: "host and simple hierarchical path", prefix: "test.io/my-repository", wantErr: false, want: map[string]string{"host": "test.io", "port": "", "components": "my-repository"}},
{name: "host and complex hierarchical path", prefix: "test.io/my-repository/my-subcatecory", wantErr: false, want: map[string]string{"host": "test.io", "port": "", "components": "my-repository/my-subcatecory"}},
{name: "fully qualified image name", prefix: "test.io/my-repository/image:tag", wantErr: true, want: nil},
{name: "random", prefix: "random text", wantErr: true, want: nil},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parsePrefix(tt.prefix)
if (err != nil) != tt.wantErr {
t.Errorf("parsePrefix() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("parsePrefix() = %v, want %v", got, tt.want)
}
})
}
}
func Test_setImageName(t *testing.T) {
type args struct {
oldName string
newNameComponents map[string]string
}
tests := []struct {
name string
args args
flatten bool
want string
}{
{
name: "replace registry",
args: args{oldName: "gcr.io/kubeflow-images-public/ingress-setup:latest", newNameComponents: map[string]string{"host": "test.io"}},
flatten: false,
want: "test.io/kubeflow-images-public/ingress-setup:latest",
},
{
name: "add registry",
args: args{oldName: "mysql:latest", newNameComponents: map[string]string{"host": "test.io"}},
flatten: false,
want: "test.io/mysql:latest",
},
{
name: "replace registry/repository",
args: args{oldName: "gcr.io/kubeflow-images-public/ingress-setup:latest", newNameComponents: map[string]string{"host": "test.io", "components": "myrepository"}},
want: "test.io/myrepository/kubeflow-images-public/ingress-setup:latest",
},
{
name: "replace registry/repository/subpath",
args: args{oldName: "gcr.io/kubeflow-images-public/katib/vizier-core:v0.1.2-alpha-156-g4ab3dbd", newNameComponents: map[string]string{"host": "test.io", "components": "myrepository"}},
want: "test.io/myrepository/kubeflow-images-public/katib/vizier-core:v0.1.2-alpha-156-g4ab3dbd",
},
{
name: "replace registry - flatten",
args: args{oldName: "gcr.io/kubeflow-images-public/ingress-setup:latest", newNameComponents: map[string]string{"host": "test.io"}},
flatten: true,
want: "test.io/ingress-setup:latest",
},
{
name: "replace registry/repository - flatten",
args: args{oldName: "gcr.io/kubeflow-images-public/ingress-setup:latest", newNameComponents: map[string]string{"host": "test.io", "components": "myrepository"}},
flatten: true,
want: "test.io/myrepository/ingress-setup:latest",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
flatten = tt.flatten
if got := setImageName(tt.args.oldName, tt.args.newNameComponents); got != tt.want {
t.Errorf("setImageName() = %v, want %v", got, tt.want)
}
})
}
}
================================================
FILE: cmd/kfctl/cmd/show.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/kfapp/coordinator"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var showCfg = viper.New()
// showCmd represents the show command
var showCmd = &cobra.Command{
Use: "show [all(=default)|k8s|platform]",
Short: "Show a generated kubeflow application.",
Long: `Show a generated kubeflow application.`,
RunE: func(cmd *cobra.Command, args []string) error {
log.SetLevel(log.InfoLevel)
if showCfg.GetBool(string(kftypes.VERBOSE)) != true {
log.SetLevel(log.WarnLevel)
}
resource, resourceErr := processResourceArg(args)
if resourceErr != nil {
return fmt.Errorf("invalid resource: %v", resourceErr)
}
kfApp, kfAppErr := coordinator.NewLoadKfAppFromURI(configFilePath)
if kfAppErr != nil {
return fmt.Errorf("couldn't load KfApp: %v", kfAppErr)
}
show, ok := kfApp.(kftypes.KfShow)
if ok && show != nil {
showErr := show.Show(resource)
if showErr != nil {
return fmt.Errorf("couldn't show KfApp: %v", showErr)
}
}
return nil
},
}
func init() {
alphaCmd.AddCommand(showCmd)
showCfg.SetConfigName("app")
showCfg.SetConfigType("yaml")
// verbose output
showCmd.Flags().BoolP(string(kftypes.VERBOSE), "V", false,
string(kftypes.VERBOSE)+" output default is false")
bindErr := showCfg.BindPFlag(string(kftypes.VERBOSE), showCmd.Flags().Lookup(string(kftypes.VERBOSE)))
if bindErr != nil {
log.Errorf("Couldn't set flag --%v: %v", string(kftypes.VERBOSE), bindErr)
return
}
}
================================================
FILE: cmd/kfctl/cmd/version.go
================================================
// Copyright 2018 The Kubeflow 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 cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// versionCmd represents the version command
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version of kfctl.",
Long: `Print the version of kfctl.`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(rootCmd.Use + " " + VERSION)
}}
func init() {
rootCmd.AddCommand(versionCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// versionCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
func versionfunc(cmd *cobra.Command, args []string) {
fmt.Println("v20181207-4e7f4ed-198-gaeea303e-dirty-03e65e")
}
================================================
FILE: cmd/kfctl/main.go
================================================
// Copyright 2018 The Kubeflow 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 main
import (
"github.com/kubeflow/kfctl/v3/cmd/kfctl/cmd"
"github.com/onrik/logrus/filename"
log "github.com/sirupsen/logrus"
)
var (
// VERSION is set during build
VERSION = "0.0.1"
)
func init() {
// Add filename as one of the fields of the structured log message.
filenameHook := filename.NewHook()
filenameHook.Field = "filename"
log.AddHook(filenameHook)
}
func main() {
cmd.Execute(VERSION)
}
================================================
FILE: cmd/manager/main.go
================================================
package main
import (
"context"
"flag"
"fmt"
"os"
"runtime"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/rest"
apis "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
"github.com/kubeflow/kfctl/v3/pkg/controller"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics"
"github.com/operator-framework/operator-sdk/pkg/leader"
"github.com/operator-framework/operator-sdk/pkg/log/zap"
"github.com/operator-framework/operator-sdk/pkg/metrics"
"github.com/operator-framework/operator-sdk/pkg/restmapper"
sdkVersion "github.com/operator-framework/operator-sdk/version"
log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
)
// Kubeflow operator version
var (
Version string = "1.2.0"
)
// Change below variables to serve metrics on different host or port.
var (
metricsHost = "0.0.0.0"
metricsPort int32 = 8383
operatorMetricsPort int32 = 8686
)
func printVersion() {
log.Infof("Go Version: %s", runtime.Version())
log.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
log.Infof("Version of operator-sdk: %v", sdkVersion.Version)
log.Infof("Kubeflow version: %v", Version)
}
func main() {
// Add the zap logger flag set to the CLI. The flag set must
// be added before calling pflag.Parse().
pflag.CommandLine.AddFlagSet(zap.FlagSet())
// Add flags registered by imported packages (e.g. glog and
// controller-runtime)
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
printVersion()
namespace, err := k8sutil.GetWatchNamespace()
if err != nil {
log.Errorf("Failed to get watch namespace. Error %v.", err)
os.Exit(1)
}
// Get a config to talk to the apiserver
cfg, err := config.GetConfig()
if err != nil {
log.Errorf("Error: %v.", err)
os.Exit(1)
}
ctx := context.TODO()
// Become the leader before proceeding
err = leader.Become(ctx, "kfctl-lock")
if err != nil {
log.Errorf("Error: %v.", err)
os.Exit(1)
}
// Create a new Cmd to provide shared dependencies and start components
mgr, err := manager.New(cfg, manager.Options{
// Watch all namespace
Namespace: "",
MapperProvider: restmapper.NewDynamicRESTMapper,
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
})
if err != nil {
log.Errorf("Error: %v.", err)
os.Exit(1)
}
log.Info("Registering Components.")
// Setup Scheme for all resources
if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
log.Errorf("Error: %v.", err)
os.Exit(1)
}
// Setup all Controllers
if err := controller.AddToManager(mgr); err != nil {
log.Errorf("Error: %v.", err)
os.Exit(1)
}
if err = serveCRMetrics(cfg); err != nil {
log.Errorf("Could not generate and serve custom resource metrics. Error: %v.", err.Error())
}
// Add to the below struct any other metrics ports you want to expose.
servicePorts := []v1.ServicePort{
{Port: metricsPort, Name: metrics.OperatorPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: metricsPort}},
{Port: operatorMetricsPort, Name: metrics.CRPortName, Protocol: v1.ProtocolTCP, TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: operatorMetricsPort}},
}
// Create Service object to expose the metrics port(s).
service, err := metrics.CreateMetricsService(ctx, cfg, servicePorts)
if err != nil {
log.Errorf("Could not create metrics Service. Error: %v.", err.Error())
}
// CreateServiceMonitors will automatically create the prometheus-operator ServiceMonitor resources
// necessary to configure Prometheus to scrape metrics from this operator.
services := []*v1.Service{service}
_, err = metrics.CreateServiceMonitors(cfg, namespace, services)
if err != nil {
log.Errorf("Could not create ServiceMonitor object. Error: %v.", err.Error())
// If this operator is deployed to a cluster without the prometheus-operator running, it will return
// ErrServiceMonitorNotPresent, which can be used to safely skip ServiceMonitor creation.
if err == metrics.ErrServiceMonitorNotPresent {
log.Errorf("Install prometheus-operator in your cluster to create ServiceMonitor objects. Error: %v.", err.Error())
}
}
log.Infof("Starting the Cmd.")
// Start the Cmd
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
log.Errorf("Manager exited non-zero. Error: %v.", err)
os.Exit(1)
}
}
// serveCRMetrics gets the Operator/CustomResource GVKs and generates metrics based on those types.
// It serves those metrics on "http://metricsHost:operatorMetricsPort".
func serveCRMetrics(cfg *rest.Config) error {
// Below function returns filtered operator/CustomResource specific GVKs.
// For more control override the below GVK list with your own custom logic.
filteredGVK, err := k8sutil.GetGVKsFromAddToScheme(apis.AddToScheme)
if err != nil {
return err
}
// Get the namespace the operator is currently deployed in.
operatorNs, err := k8sutil.GetOperatorNamespace()
if err != nil {
return err
}
// To generate metrics in other namespaces, add the values below.
ns := []string{operatorNs}
// Generate and serve custom resource specific metrics.
err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort)
if err != nil {
return err
}
return nil
}
================================================
FILE: cmd/plugins/dockerfordesktop/dockerfordesktop.go
================================================
package main
import (
kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps"
cltypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1"
"github.com/kubeflow/kfctl/v3/pkg/kfapp/dockerfordesktop"
)
func GetKfApp(client *cltypes.KfDef) kftypes.KfApp {
return dockerfordesktop.GetKfApp(client)
}
================================================
FILE: config/doc.go
================================================
// Copyright 2018 The Kubeflow 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 config contains API Schema definitions
// +k8s:deepcopy-gen=package
package config
================================================
FILE: config/types.go
================================================
/*
Copyright The Kubeflow 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 config
type NameValue struct {
Name string `json:"name,omitempty"`
Value string `json:"value,omitempty"`
InitRequired bool `json:"initRequired,omitempty"`
}
type Parameters map[string][]NameValue
// Default components configuration definitions.
type ComponentConfig struct {
// Name of repository.
Repo string `json:"repo,omitempty"`
// List of default components.
// +patchStrategy=merge
Components []string `json:"components,omitempty" patchStrategy:"merge"`
// List of default packages.
// +patchStrategy=merge
Packages []string `json:"packages,omitempty" patchStrategy:"merge"`
// Parameters to be set to components using ks param set.
// +patchStrategy=merge,retainKeys
ComponentParams Parameters `json:"componentParams,omitempty" patchStrategy:"merge,retainKeys"`
// Platform type.
Platform string `json:"platform,omitempty"`
}
// StorageOption store user choice of permanent storage
type StorageOption struct {
// Whether to create persistent storage for storing all Kubeflow Pipeline artifacts or not.
CreatePipelinePersistentStorage bool
}
================================================
FILE: config/zz_generated.deepcopy.go
================================================
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package config
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentConfig) DeepCopyInto(out *ComponentConfig) {
*out = *in
if in.Components != nil {
in, out := &in.Components, &out.Components
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Packages != nil {
in, out := &in.Packages, &out.Packages
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ComponentParams != nil {
in, out := &in.ComponentParams, &out.ComponentParams
*out = make(Parameters, len(*in))
for key, val := range *in {
var outVal []NameValue
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]NameValue, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentConfig.
func (in *ComponentConfig) DeepCopy() *ComponentConfig {
if in == nil {
return nil
}
out := new(ComponentConfig)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NameValue) DeepCopyInto(out *NameValue) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NameValue.
func (in *NameValue) DeepCopy() *NameValue {
if in == nil {
return nil
}
out := new(NameValue)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in Parameters) DeepCopyInto(out *Parameters) {
{
in := &in
*out = make(Parameters, len(*in))
for key, val := range *in {
var outVal []NameValue
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]NameValue, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
}
return
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Parameters.
func (in Parameters) DeepCopy() Parameters {
if in == nil {
return nil
}
out := new(Parameters)
in.DeepCopyInto(out)
return *out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StorageOption) DeepCopyInto(out *StorageOption) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageOption.
func (in *StorageOption) DeepCopy() *StorageOption {
if in == nil {
return nil
}
out := new(StorageOption)
in.DeepCopyInto(out)
return out
}
================================================
FILE: deploy/cluster_role_binding.yaml
================================================
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubeflow-operator
subjects:
- kind: ServiceAccount
name: kubeflow-operator
namespace: $(namespace) # Replace it with operator's namespace
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
================================================
FILE: deploy/crds/kfdef.apps.kubeflow.org_kfdefs_crd.yaml
================================================
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: kfdefs.kfdef.apps.kubeflow.org
spec:
group: kfdef.apps.kubeflow.org
names:
kind: KfDef
listKind: KfDefList
plural: kfdefs
singular: kfdef
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: KfDef is the Schema for the kfdefs API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: KfDefSpec defines the desired state of KfDef
type: object
status:
description: KfDefStatus defines the observed state of KfDef
type: object
type: object
version: v1
versions:
- name: v1
served: true
storage: true
================================================
FILE: deploy/crds/kustomization.yaml
================================================
resources:
- kfdef.apps.kubeflow.org_kfdefs_crd.yaml
================================================
FILE: deploy/kustomization.yaml
================================================
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./crds
- ./service_account.yaml
- ./role.yaml
- ./cluster_role_binding.yaml
- ./operator.yaml
vars:
- fieldref:
fieldPath: metadata.namespace
name: namespace
objref:
apiVersion: apps/v1
kind: Deployment
name: kubeflow-operator
configurations:
- ./params.yaml
namespace: operators
================================================
FILE: deploy/olm-catalog/kubeflow/0.1.0/kfdef.apps.kubeflow.org.crd.yaml
================================================
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: kfdefs.kfdef.apps.kubeflow.org
labels:
component: kubeflow-operator
spec:
group: kfdef.apps.kubeflow.org
names:
kind: KfDef
listKind: KfDefList
plural: kfdefs
singular: kfdef
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: KfDef is the Schema for the kfdefs API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: KfDefSpec defines the desired state of KfDef
type: object
status:
description: KfDefStatus defines the observed state of KfDef
type: object
type: object
version: v1
versions:
- name: v1
served: true
storage: true
================================================
FILE: deploy/olm-catalog/kubeflow/0.1.0/kubeflow.v0.1.0.clusterserviceversion.yaml
================================================
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
annotations:
alm-examples: '[{"apiVersion":"kfdef.apps.kubeflow.org/v1","kind":"KfDef","metadata":{"name":"kubeflow-deployment","namespace":"kubeflow"},"spec":{"applications":[{"kustomizeConfig":{"parameters":[{"name":"namespace","value":"istio-system"}],"repoRef":{"name":"manifests","path":"istio/istio-crds"}},"name":"istio-crds"},{"kustomizeConfig":{"parameters":[{"name":"namespace","value":"istio-system"}],"repoRef":{"name":"manifests","path":"istio/istio-install"}},"name":"istio-install"},{"kustomizeConfig":{"parameters":[{"name":"clusterRbacConfig","value":"OFF"}],"repoRef":{"name":"manifests","path":"istio/istio"}},"name":"istio"},{"kustomizeConfig":{"repoRef":{"name":"manifests","path":"application/application-crds"}},"name":"application-crds"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"application/application"}},"name":"application"},{"kustomizeConfig":{"parameters":[{"name":"namespace","value":"cert-manager"}],"repoRef":{"name":"manifests","path":"cert-manager/cert-manager-crds"}},"name":"cert-manager-crds"},{"kustomizeConfig":{"parameters":[{"name":"namespace","value":"kube-system"}],"repoRef":{"name":"manifests","path":"cert-manager/cert-manager-kube-system-resources"}},"name":"cert-manager-kube-system-resources"},{"kustomizeConfig":{"overlays":["self-signed","application"],"parameters":[{"name":"namespace","value":"cert-manager"}],"repoRef":{"name":"manifests","path":"cert-manager/cert-manager"}},"name":"cert-manager"},{"kustomizeConfig":{"repoRef":{"name":"manifests","path":"metacontroller"}},"name":"metacontroller"},{"kustomizeConfig":{"overlays":["istio","application"],"parameters":[{"name":"containerRuntimeExecutor","value":"pns"}],"repoRef":{"name":"manifests","path":"argo"}},"name":"argo"},{"kustomizeConfig":{"repoRef":{"name":"manifests","path":"kubeflow-roles"}},"name":"kubeflow-roles"},{"kustomizeConfig":{"overlays":["istio","application"],"repoRef":{"name":"manifests","path":"common/centraldashboard"}},"name":"centraldashboard"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"admission-webhook/bootstrap"}},"name":"bootstrap"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"admission-webhook/webhook"}},"name":"webhook"},{"kustomizeConfig":{"overlays":["istio","application"],"repoRef":{"name":"manifests","path":"jupyter/jupyter-web-app"}},"name":"jupyter-web-app"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"spark/spark-operator"}},"name":"spark-operator"},{"kustomizeConfig":{"overlays":["istio","application","ibm-storage-config","db"],"repoRef":{"name":"manifests","path":"metadata"}},"name":"metadata"},{"kustomizeConfig":{"overlays":["istio","application"],"repoRef":{"name":"manifests","path":"jupyter/notebook-controller"}},"name":"notebook-controller"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pytorch-job/pytorch-job-crds"}},"name":"pytorch-job-crds"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pytorch-job/pytorch-operator"}},"name":"pytorch-operator"},{"kustomizeConfig":{"overlays":["application"],"parameters":[{"name":"namespace","value":"knative-serving"}],"repoRef":{"name":"manifests","path":"knative/knative-serving-crds"}},"name":"knative-crds"},{"kustomizeConfig":{"overlays":["application"],"parameters":[{"name":"namespace","value":"knative-serving"}],"repoRef":{"name":"manifests","path":"knative/knative-serving-install"}},"name":"knative-install"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"kfserving/kfserving-crds"}},"name":"kfserving-crds"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"kfserving/kfserving-install"}},"name":"kfserving-install"},{"kustomizeConfig":{"overlays":["application"],"parameters":[{"name":"usageId","value":"<randomly-generated-id>"},{"name":"reportUsage","value":"true"}],"repoRef":{"name":"manifests","path":"common/spartakus"}},"name":"spartakus"},{"kustomizeConfig":{"overlays":["istio"],"repoRef":{"name":"manifests","path":"tensorboard"}},"name":"tensorboard"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"tf-training/tf-job-crds"}},"name":"tf-job-crds"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"tf-training/tf-job-operator"}},"name":"tf-job-operator"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"katib/katib-crds"}},"name":"katib-crds"},{"kustomizeConfig":{"overlays":["application","istio","ibm-storage-config"],"repoRef":{"name":"manifests","path":"katib/katib-controller"}},"name":"katib-controller"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pipeline/api-service"}},"name":"api-service"},{"kustomizeConfig":{"overlays":["application"],"parameters":[{"name":"minioPvcName","value":"minio-pv-claim"}],"repoRef":{"name":"manifests","path":"pipeline/minio"}},"name":"minio"},{"kustomizeConfig":{"overlays":["application"],"parameters":[{"name":"mysqlPvcName","value":"mysql-pv-claim"}],"repoRef":{"name":"manifests","path":"pipeline/mysql"}},"name":"mysql"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pipeline/persistent-agent"}},"name":"persistent-agent"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pipeline/pipelines-runner"}},"name":"pipelines-runner"},{"kustomizeConfig":{"overlays":["istio","application"],"repoRef":{"name":"manifests","path":"pipeline/pipelines-ui"}},"name":"pipelines-ui"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pipeline/pipelines-viewer"}},"name":"pipelines-viewer"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pipeline/scheduledworkflow"}},"name":"scheduledworkflow"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"pipeline/pipeline-visualization-service"}},"name":"pipeline-visualization-service"},{"kustomizeConfig":{"overlays":["application","istio"],"parameters":[{"name":"admin","value":"example@kubeflow.org"}],"repoRef":{"name":"manifests","path":"profiles"}},"name":"profiles"},{"kustomizeConfig":{"overlays":["application"],"repoRef":{"name":"manifests","path":"seldon/seldon-core-operator"}},"name":"seldon-core-operator"}],"repos":[{"name":"manifests","uri":"https://github.com/kubeflow/manifests/archive/v0.7-branch.tar.gz"}],"version":"v0.7.1"}}]'
capabilities: Basic Install
categories: "AI/Machine Learning"
description: "Kubeflow Operator for deployment and management of Kubeflow"
support: Kubeflow
repository: https://github.com/kubeflow/kfctl
createdAt: '2020-02-05T00:00:00Z'
containerImage: aipipeline/kubeflow-operator:v0.1.0
certified: 'False'
name: kubeflow.v0.1.0
namespace: placeholder
spec:
apiservicedefinitions: {}
customresourcedefinitions:
owned:
- description: KfDef is the Schema for the applications API
kind: KfDef
name: kfdefs.kfdef.apps.kubeflow.org
version: v1
displayName: Kubeflow
group: kfdef.apps.kubeflow.org
description: "Kubeflow Operator for deployment and management of Kubeflow components. Applicable for Kubeflow versions 0.7. Check [Kubeflow Operator documentation](https://github.com/kubeflow/kfctl/blob/master/operator.md) for more details."
displayName: Kubeflow
icon:
- base64data: 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
gitextract_q8wlw781/
├── .github/
│ ├── issue_label_bot.yaml
│ └── workflows/
│ ├── kfctl_go_unittests.yaml
│ └── triage_issues.yaml
├── .gitignore
├── Dockerfile
├── LICENSE
├── Makefile
├── OWNERS
├── README.md
├── build/
│ ├── Dockerfile
│ └── Dockerfile.ubi
├── cmd/
│ ├── kfctl/
│ │ ├── .gitignore
│ │ ├── OWNERS
│ │ ├── README.md
│ │ ├── cmd/
│ │ │ ├── alpha.go
│ │ │ ├── apply.go
│ │ │ ├── build.go
│ │ │ ├── completion.go
│ │ │ ├── delete.go
│ │ │ ├── generate.go
│ │ │ ├── init.go
│ │ │ ├── mirror.go
│ │ │ ├── mirror_build.go
│ │ │ ├── mirror_overwrite.go
│ │ │ ├── root.go
│ │ │ ├── set-image-name.go
│ │ │ ├── set-image-name_test.go
│ │ │ ├── show.go
│ │ │ └── version.go
│ │ └── main.go
│ ├── manager/
│ │ └── main.go
│ └── plugins/
│ └── dockerfordesktop/
│ └── dockerfordesktop.go
├── config/
│ ├── doc.go
│ ├── types.go
│ └── zz_generated.deepcopy.go
├── deploy/
│ ├── cluster_role_binding.yaml
│ ├── crds/
│ │ ├── kfdef.apps.kubeflow.org_kfdefs_crd.yaml
│ │ └── kustomization.yaml
│ ├── kustomization.yaml
│ ├── olm-catalog/
│ │ └── kubeflow/
│ │ ├── 0.1.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v0.1.0.clusterserviceversion.yaml
│ │ ├── 1.0.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v1.0.0.clusterserviceversion.yaml
│ │ ├── 1.1.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v1.1.0.clusterserviceversion.yaml
│ │ ├── 1.2.0/
│ │ │ ├── kfdef.apps.kubeflow.org.crd.yaml
│ │ │ └── kubeflow.v1.2.0.clusterserviceversion.yaml
│ │ └── kubeflow.package.yaml
│ ├── operator.yaml
│ ├── params.yaml
│ ├── role.yaml
│ └── service_account.yaml
├── go.mod
├── go.sum
├── hack/
│ ├── boilerplate.go.txt
│ └── cp_update.sh
├── kustomization.yaml
├── kustomize/
│ ├── base/
│ │ └── kustomization.yaml
│ └── include/
│ └── quota/
│ ├── kfdef_quota.yaml
│ └── kustomization.yaml
├── operator.md
├── pkg/
│ ├── apis/
│ │ ├── apis.go
│ │ ├── apps/
│ │ │ ├── addtoscheme_kfdef_v1.go
│ │ │ ├── apis.go
│ │ │ ├── group.go
│ │ │ ├── group_test.go
│ │ │ ├── imagemirror/
│ │ │ │ └── v1alpha1/
│ │ │ │ └── replication_types.go
│ │ │ ├── kfconfig/
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── types.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ ├── kfdef/
│ │ │ │ ├── kfdef.go
│ │ │ │ ├── testdata/
│ │ │ │ │ └── doc.go
│ │ │ │ ├── v1/
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── application_types.go
│ │ │ │ │ ├── application_types_test.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── register.go
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── doc.go
│ │ │ │ │ │ └── kfctl_plugin_test.yaml
│ │ │ │ │ └── zz_generated.deepcopy.go
│ │ │ │ ├── v1alpha1/
│ │ │ │ │ ├── application_types.go
│ │ │ │ │ ├── application_types_test.go
│ │ │ │ │ ├── doc.go
│ │ │ │ │ ├── register.go
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── doc.go
│ │ │ │ │ │ └── kfctl_plugin_test.yaml
│ │ │ │ │ ├── v1alpha1_suite_test.go
│ │ │ │ │ └── zz_generated.deepcopy.go
│ │ │ │ └── v1beta1/
│ │ │ │ ├── README.md
│ │ │ │ ├── application_types.go
│ │ │ │ ├── application_types_test.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── testdata/
│ │ │ │ │ ├── doc.go
│ │ │ │ │ └── kfctl_plugin_test.yaml
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ ├── kfupgrade/
│ │ │ │ ├── kfupgrade.go
│ │ │ │ └── v1alpha1/
│ │ │ │ ├── application_types.go
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ └── plugins/
│ │ │ ├── aws/
│ │ │ │ ├── aws.go
│ │ │ │ └── v1alpha1/
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── types.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ ├── gcp/
│ │ │ │ ├── gcp.go
│ │ │ │ └── v1alpha1/
│ │ │ │ ├── doc.go
│ │ │ │ ├── register.go
│ │ │ │ ├── types.go
│ │ │ │ ├── types_test.go
│ │ │ │ └── zz_generated.deepcopy.go
│ │ │ └── plugins.go
│ │ └── kferrors.go
│ ├── controller/
│ │ ├── controller.go
│ │ └── kfdef/
│ │ ├── const.go
│ │ └── kfdef_controller.go
│ ├── kfapp/
│ │ ├── aws/
│ │ │ ├── OWNERS
│ │ │ ├── aws.go
│ │ │ ├── eks.go
│ │ │ ├── eks_test.go
│ │ │ ├── identity.go
│ │ │ └── k8sClient.go
│ │ ├── coordinator/
│ │ │ ├── coordinator.go
│ │ │ ├── coordinator_test.go
│ │ │ └── fake/
│ │ │ └── fake.go
│ │ ├── dockerfordesktop/
│ │ │ └── dockerfordesktop.go
│ │ ├── existing_arrikto/
│ │ │ ├── existing.go
│ │ │ └── existing_test.go
│ │ ├── gcp/
│ │ │ ├── fake/
│ │ │ │ └── fake.go
│ │ │ ├── gcp.go
│ │ │ ├── gcp_test.go
│ │ │ └── testdata/
│ │ │ ├── doc.go
│ │ │ └── kfctl_gcp.yaml
│ │ ├── kfapp.go
│ │ ├── kfdef.go
│ │ ├── kustomize/
│ │ │ ├── kustomize.go
│ │ │ ├── kustomize_test.go
│ │ │ └── testdata/
│ │ │ ├── doc.go
│ │ │ ├── kustomizeExample/
│ │ │ │ ├── metadata/
│ │ │ │ │ ├── base/
│ │ │ │ │ │ ├── grpc-params.env
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ ├── metadata-envoy-deployment.yaml
│ │ │ │ │ │ ├── metadata-envoy-service.yaml
│ │ │ │ │ │ ├── metadata-service.yaml
│ │ │ │ │ │ ├── metadata-ui-deployment.yaml
│ │ │ │ │ │ ├── metadata-ui-role.yaml
│ │ │ │ │ │ ├── metadata-ui-rolebinding.yaml
│ │ │ │ │ │ ├── metadata-ui-sa.yaml
│ │ │ │ │ │ ├── metadata-ui-service.yaml
│ │ │ │ │ │ └── params.env
│ │ │ │ │ ├── expected/
│ │ │ │ │ │ └── kustomization.yaml
│ │ │ │ │ └── overlays/
│ │ │ │ │ ├── application/
│ │ │ │ │ │ ├── application.yaml
│ │ │ │ │ │ └── kustomization.yaml
│ │ │ │ │ ├── db/
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-db-deployment.yaml
│ │ │ │ │ │ ├── metadata-db-pvc.yaml
│ │ │ │ │ │ ├── metadata-db-service.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ ├── params.env
│ │ │ │ │ │ └── secrets.env
│ │ │ │ │ ├── external-mysql/
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ ├── params.env
│ │ │ │ │ │ └── secrets.env
│ │ │ │ │ ├── google-cloudsql/
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ │ ├── metadata-deployment.yaml
│ │ │ │ │ │ └── params.env
│ │ │ │ │ ├── ibm-storage-config/
│ │ │ │ │ │ └── kustomization.yaml
│ │ │ │ │ └── istio/
│ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ ├── params.yaml
│ │ │ │ │ ├── virtual-service-metadata-grpc.yaml
│ │ │ │ │ └── virtual-service.yaml
│ │ │ │ └── pytorch-operator/
│ │ │ │ ├── base/
│ │ │ │ │ ├── cluster-role-binding.yaml
│ │ │ │ │ ├── cluster-role.yaml
│ │ │ │ │ ├── config-map.yaml
│ │ │ │ │ ├── deployment.yaml
│ │ │ │ │ ├── kustomization.yaml
│ │ │ │ │ ├── params.env
│ │ │ │ │ ├── service-account.yaml
│ │ │ │ │ └── service.yaml
│ │ │ │ ├── expected/
│ │ │ │ │ └── kustomization.yaml
│ │ │ │ └── overlays/
│ │ │ │ └── application/
│ │ │ │ ├── application.yaml
│ │ │ │ └── kustomization.yaml
│ │ │ └── operator/
│ │ │ ├── base/
│ │ │ │ ├── kustomization.yaml
│ │ │ │ └── service.yaml
│ │ │ ├── expected/
│ │ │ │ └── service.yaml
│ │ │ └── kustomization.yaml
│ │ └── minikube/
│ │ └── minikube.go
│ ├── kfconfig/
│ │ ├── awsplugin/
│ │ │ ├── OWNERS
│ │ │ ├── doc.go
│ │ │ ├── register.go
│ │ │ ├── types.go
│ │ │ └── zz_generated.deepcopy.go
│ │ ├── doc.go
│ │ ├── gcpplugin/
│ │ │ ├── doc.go
│ │ │ ├── register.go
│ │ │ ├── types.go
│ │ │ ├── types_test.go
│ │ │ └── zz_generated.deepcopy.go
│ │ ├── loaders/
│ │ │ ├── loaders.go
│ │ │ ├── loaders_test.go
│ │ │ ├── testdata/
│ │ │ │ ├── doc.go
│ │ │ │ ├── kfconfig_v1.yaml
│ │ │ │ ├── kfconfig_v1alpha1.yaml
│ │ │ │ ├── kfconfig_v1beta1.yaml
│ │ │ │ ├── kfctl_gcp_basic_auth.0.7.0.yaml
│ │ │ │ ├── v1.yaml
│ │ │ │ ├── v1alpha1.yaml
│ │ │ │ └── v1beta1.yaml
│ │ │ ├── utils.go
│ │ │ ├── v1.go
│ │ │ ├── v1_test.go
│ │ │ ├── v1alpha1.go
│ │ │ ├── v1alpha1_test.go
│ │ │ ├── v1beta1.go
│ │ │ └── v1beta1_test.go
│ │ ├── register.go
│ │ ├── testdata/
│ │ │ ├── doc.go
│ │ │ └── kfctl_plugin_test.yaml
│ │ ├── types.go
│ │ ├── types_test.go
│ │ └── zz_generated.deepcopy.go
│ ├── kfupgrade/
│ │ ├── kfupgrade.go
│ │ └── kfupgrade_test.go
│ ├── mirror/
│ │ ├── mirror_image.go
│ │ ├── mirror_image_test.go
│ │ └── testdata/
│ │ ├── base-pkg/
│ │ │ └── kustomization.yaml
│ │ ├── expected-cloudbuild.yaml
│ │ ├── expected-kustomization.yaml
│ │ ├── expected-pipeline.yaml
│ │ └── kustomize/
│ │ └── kustomization.yaml
│ └── utils/
│ ├── awsutil.go
│ ├── diff.go
│ ├── gcputils.go
│ ├── iamutils.go
│ ├── iamutils_test.go
│ ├── k8sAuth.go
│ ├── k8utils.go
│ ├── k8utils_test.go
│ ├── kindsorter.go
│ └── logging.go
├── prow_config.yaml
├── py/
│ └── kubeflow/
│ ├── __init__.py
│ └── kfctl/
│ ├── __init__.py
│ └── testing/
│ ├── __init__.py
│ ├── ci/
│ │ ├── __init__.py
│ │ ├── kfctl_e2e_workflow.py
│ │ ├── kfctl_go_build_test.py
│ │ ├── kfctl_go_deploy_test.py
│ │ ├── kfctl_upgrade_e2e_workflow.py
│ │ └── update_jupyter_web_app.py
│ ├── pytests/
│ │ ├── conftest.py
│ │ ├── endpoint_ready_test.py
│ │ ├── jupyter_test.py
│ │ ├── kf_is_ready_test.py
│ │ ├── kfam_test.py
│ │ ├── kfctl_create_cluster_test.py
│ │ ├── kfctl_delete_cluster_test.py
│ │ ├── kfctl_delete_test.py
│ │ ├── kfctl_delete_wrong_cluster.py
│ │ ├── kfctl_deploy_kubeflow_test.py
│ │ ├── kfctl_go_test.py
│ │ ├── kfctl_second_apply.py
│ │ ├── kfctl_upgrade_test.py
│ │ ├── pytorch_job_deploy.py
│ │ └── testdata/
│ │ ├── jupyter_test.yaml
│ │ └── pytorch_job.yaml
│ ├── test_deploy.py
│ ├── test_deploy_test.py
│ └── util/
│ ├── __init__.py
│ ├── application_util.py
│ ├── application_util_test.py
│ ├── aws_util.py
│ ├── deploy_utils.py
│ ├── gcp_util.py
│ ├── kfctl_go_test_utils.py
│ ├── run_with_retry.py
│ └── vm_util.py
└── third_party/
├── README.md
├── check-license.sh
├── concatenate_license.py
├── dep.txt
├── dep_repo.manual.csv
├── license.txt
└── license_info.csv
SYMBOL INDEX (1342 symbols across 136 files)
FILE: cmd/kfctl/cmd/alpha.go
function init (line 17) | func init() {
FILE: cmd/kfctl/cmd/apply.go
constant awsConfig (line 38) | awsConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v...
constant gcpConfig (line 39) | gcpConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v...
constant istioDexConfig (line 40) | istioDexConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v...
constant k8sConfig (line 41) | k8sConfig = "https://raw.githubusercontent.com/kubeflow/manifests/v...
function init (line 97) | func init() {
FILE: cmd/kfctl/cmd/build.go
function init (line 76) | func init() {
FILE: cmd/kfctl/cmd/completion.go
function init (line 56) | func init() {
FILE: cmd/kfctl/cmd/delete.go
function init (line 71) | func init() {
function setAnnotations (line 107) | func setAnnotations(configPath string, annotations map[string]string) er...
FILE: cmd/kfctl/cmd/generate.go
function init (line 39) | func init() {
FILE: cmd/kfctl/cmd/init.go
function init (line 41) | func init() {
FILE: cmd/kfctl/cmd/mirror.go
function init (line 14) | func init() {
FILE: cmd/kfctl/cmd/mirror_build.go
function init (line 21) | func init() {
FILE: cmd/kfctl/cmd/mirror_overwrite.go
function init (line 14) | func init() {
FILE: cmd/kfctl/cmd/root.go
function processResourceArg (line 24) | func processResourceArg(args []string) (kftypes.ResourceEnum, error) {
function Execute (line 58) | func Execute(version string) {
function init (line 67) | func init() {
function initConfig (line 72) | func initConfig() {
FILE: cmd/kfctl/cmd/set-image-name.go
function init (line 23) | func init() {
function parsePrefix (line 124) | func parsePrefix(prefix string) (map[string]string, error) {
function parseImageName (line 142) | func parseImageName(name string) map[string]string {
function setImageName (line 161) | func setImageName(oldName string, newNameComponents map[string]string) s...
function imageToString (line 187) | func imageToString(image image.Image) string {
FILE: cmd/kfctl/cmd/set-image-name_test.go
function Test_imageToString (line 9) | func Test_imageToString(t *testing.T) {
function Test_parseImageName (line 53) | func Test_parseImageName(t *testing.T) {
function Test_parsePrefix (line 102) | func Test_parsePrefix(t *testing.T) {
function Test_setImageName (line 130) | func Test_setImageName(t *testing.T) {
FILE: cmd/kfctl/cmd/show.go
function init (line 58) | func init() {
FILE: cmd/kfctl/cmd/version.go
function init (line 32) | func init() {
function versionfunc (line 46) | func versionfunc(cmd *cobra.Command, args []string) {
FILE: cmd/kfctl/main.go
function init (line 28) | func init() {
function main (line 35) | func main() {
FILE: cmd/manager/main.go
function printVersion (line 45) | func printVersion() {
function main (line 52) | func main() {
function serveCRMetrics (line 151) | func serveCRMetrics(cfg *rest.Config) error {
FILE: cmd/plugins/dockerfordesktop/dockerfordesktop.go
function GetKfApp (line 9) | func GetKfApp(client *cltypes.KfDef) kftypes.KfApp {
FILE: config/types.go
type NameValue (line 19) | type NameValue struct
type Parameters (line 25) | type Parameters
type ComponentConfig (line 28) | type ComponentConfig struct
type StorageOption (line 45) | type StorageOption struct
FILE: config/zz_generated.deepcopy.go
method DeepCopyInto (line 24) | func (in *ComponentConfig) DeepCopyInto(out *ComponentConfig) {
method DeepCopy (line 55) | func (in *ComponentConfig) DeepCopy() *ComponentConfig {
method DeepCopyInto (line 65) | func (in *NameValue) DeepCopyInto(out *NameValue) {
method DeepCopy (line 71) | func (in *NameValue) DeepCopy() *NameValue {
method DeepCopyInto (line 81) | func (in Parameters) DeepCopyInto(out *Parameters) {
method DeepCopy (line 101) | func (in Parameters) DeepCopy() Parameters {
method DeepCopyInto (line 111) | func (in *StorageOption) DeepCopyInto(out *StorageOption) {
method DeepCopy (line 117) | func (in *StorageOption) DeepCopy() *StorageOption {
FILE: pkg/apis/apis.go
function AddToScheme (line 29) | func AddToScheme(s *runtime.Scheme) error {
FILE: pkg/apis/apps/addtoscheme_kfdef_v1.go
function init (line 7) | func init() {
FILE: pkg/apis/apps/apis.go
function AddToScheme (line 29) | func AddToScheme(s *runtime.Scheme) error {
FILE: pkg/apis/apps/group.go
constant DefaultNamespace (line 44) | DefaultNamespace = "kubeflow"
constant DefaultVersion (line 46) | DefaultVersion = "master"
constant KfConfigFile (line 47) | KfConfigFile = "app.yaml"
constant KustomizationFile (line 48) | KustomizationFile = "kustomization.yaml"
constant KustomizationParamFile (line 49) | KustomizationParamFile = "params.env"
constant DefaultCacheDir (line 50) | DefaultCacheDir = ".cache"
constant KubeflowRepoName (line 51) | KubeflowRepoName = "kubeflow"
constant ManifestsRepoName (line 52) | ManifestsRepoName = "manifests"
constant KubeflowRepo (line 53) | KubeflowRepo = "kubeflow"
constant ManifestsRepo (line 54) | ManifestsRepo = "manifests"
constant DefaultConfigDir (line 55) | DefaultConfigDir = "bootstrap/config"
constant DefaultZone (line 56) | DefaultZone = "us-east1-d"
constant DefaultGkeApiVer (line 57) | DefaultGkeApiVer = "v1beta1"
constant DefaultAppLabel (line 58) | DefaultAppLabel = "app.kubernetes.io/name"
constant DefaultAppVersion (line 59) | DefaultAppVersion = "app.kubernetes.io/version"
constant DefaultAppType (line 60) | DefaultAppType = "kubeflow"
constant KUBEFLOW_USERNAME (line 61) | KUBEFLOW_USERNAME = "KUBEFLOW_USERNAME"
constant KUBEFLOW_PASSWORD (line 62) | KUBEFLOW_PASSWORD = "KUBEFLOW_PASSWORD"
constant DefaultSwaggerFile (line 63) | DefaultSwaggerFile = "bootstrap/k8sSpec/v1.11.7/api/openapi-spec/swa...
constant YamlSeparator (line 64) | YamlSeparator = "(?m)^---[ \t]*$"
constant Dns1123LabelFmt (line 65) | Dns1123LabelFmt = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
constant ProfileNameMaxLen (line 66) | ProfileNameMaxLen = 30
type SupportedResourceType (line 69) | type SupportedResourceType
constant KFDEF (line 72) | KFDEF SupportedResourceType = "KfDef"
constant KFUPGRADE (line 73) | KFUPGRADE SupportedResourceType = "KfUpgrade"
type ResourceEnum (line 76) | type ResourceEnum
constant ALL (line 79) | ALL ResourceEnum = "all"
constant K8S (line 80) | K8S ResourceEnum = "k8s"
constant PLATFORM (line 81) | PLATFORM ResourceEnum = "platform"
type CliOption (line 84) | type CliOption
constant EMAIL (line 87) | EMAIL CliOption = "email"
constant IPNAME (line 88) | IPNAME CliOption = "ipName"
constant HOSTNAME (line 89) | HOSTNAME CliOption = "hostname"
constant MOUNT_LOCAL (line 90) | MOUNT_LOCAL CliOption = "mount-local"
constant SKIP_INIT_GCP_PROJECT (line 91) | SKIP_INIT_GCP_PROJECT CliOption = "skip-init-gcp-project"
constant VERBOSE (line 92) | VERBOSE CliOption = "verbose"
constant NAMESPACE (line 93) | NAMESPACE CliOption = "namespace"
constant VERSION (line 94) | VERSION CliOption = "version"
constant REPO (line 95) | REPO CliOption = "repo"
constant PROJECT (line 96) | PROJECT CliOption = "project"
constant APPNAME (line 97) | APPNAME CliOption = "appname"
constant DATA (line 98) | DATA CliOption = "Data"
constant ZONE (line 99) | ZONE CliOption = "zone"
constant DELETE_STORAGE (line 100) | DELETE_STORAGE CliOption = "delete-storage"
constant DISABLE_USAGE_REPORT (line 101) | DISABLE_USAGE_REPORT CliOption = "disable-usage-report"
constant PACKAGE_MANAGER (line 102) | PACKAGE_MANAGER CliOption = "package-manager"
constant FILE (line 103) | FILE CliOption = "file"
constant FORCE_DELETION (line 104) | FORCE_DELETION CliOption = "force-deletion"
constant DUMP (line 105) | DUMP CliOption = "dump"
type KfApp (line 113) | type KfApp interface
type Platform (line 126) | type Platform interface
type KfShow (line 133) | type KfShow interface
function QuoteItems (line 138) | func QuoteItems(items []string) []string {
function RemoveItem (line 148) | func RemoveItem(defaults []string, name string) []string {
constant AWS (line 160) | AWS = "aws"
constant GCP (line 161) | GCP = "gcp"
constant MINIKUBE (line 162) | MINIKUBE = "minikube"
constant EXISTING_ARRIKTO (line 163) | EXISTING_ARRIKTO = "existing_arrikto"
constant KSONNET (line 168) | KSONNET = "ksonnet"
constant KUSTOMIZE (line 169) | KUSTOMIZE = "kustomize"
function LoadKfApp (line 173) | func LoadKfApp(name string, kfdef *kfdefs.KfDef) (KfApp, error) {
function DownloadToCache (line 200) | func DownloadToCache(appDir string, repo string, version string) (string...
function KubeConfigPath (line 274) | func KubeConfigPath() string {
function GetConfig (line 292) | func GetConfig() *rest.Config {
function GetServerVersion (line 309) | func GetServerVersion(c *clientset.Clientset) string {
function GetKubeConfig (line 320) | func GetKubeConfig() *clientcmdapi.Config {
function GetClientset (line 330) | func GetClientset(config *rest.Config) *clientset.Clientset {
function GetApiExtClientset (line 339) | func GetApiExtClientset(config *rest.Config) apiext.ApiextensionsV1beta1...
function EmailToDefaultName (line 351) | func EmailToDefaultName(email string) string {
function Capture (line 376) | func Capture() func() (string, error) {
FILE: pkg/apis/apps/group_test.go
function TestEmailToDefaultName (line 7) | func TestEmailToDefaultName(t *testing.T) {
FILE: pkg/apis/apps/imagemirror/v1alpha1/replication_types.go
type Replication (line 21) | type Replication struct
type ReplicationSpec (line 28) | type ReplicationSpec struct
type Pattern (line 34) | type Pattern struct
type SrcImages (line 39) | type SrcImages struct
FILE: pkg/apis/apps/kfconfig/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 58) | func init() {
FILE: pkg/apis/apps/kfconfig/types.go
constant DefaultCacheDir (line 22) | DefaultCacheDir = ".cache"
type KfConfig (line 29) | type KfConfig struct
method GetRepoCache (line 210) | func (c *KfConfig) GetRepoCache(repoName string) (Cache, bool) {
method GetPluginSpec (line 219) | func (c *KfConfig) GetPluginSpec(pluginKind PluginKindType, s interfac...
method SetPluginSpec (line 254) | func (c *KfConfig) SetPluginSpec(pluginKind PluginKindType, spec inter...
method SetCondition (line 308) | func (c *KfConfig) SetCondition(condType ConditionType,
method GetCondition (line 336) | func (c *KfConfig) GetCondition(condType ConditionType) (*Condition, e...
method IsPluginFinished (line 348) | func (c *KfConfig) IsPluginFinished(pluginKind PluginKindType) bool {
method SetPluginFinished (line 361) | func (c *KfConfig) SetPluginFinished(pluginKind PluginKindType, msg st...
method IsPluginFailed (line 372) | func (c *KfConfig) IsPluginFailed(pluginKind PluginKindType) bool {
method SetPluginFailed (line 385) | func (c *KfConfig) SetPluginFailed(pluginKind PluginKindType, msg stri...
method SyncCache (line 427) | func (c *KfConfig) SyncCache() error {
method GetSecret (line 520) | func (c *KfConfig) GetSecret(name string) (string, error) {
method GetSecretSource (line 541) | func (c *KfConfig) GetSecretSource(name string) (*SecretSource, error) {
method GetApplicationParameter (line 551) | func (c *KfConfig) GetApplicationParameter(appName string, paramName s...
method SetApplicationParameter (line 565) | func (c *KfConfig) SetApplicationParameter(appName string, paramName s...
method SetSecret (line 593) | func (c *KfConfig) SetSecret(newSecret Secret) {
type KfConfigSpec (line 38) | type KfConfigSpec struct
type Application (line 70) | type Application struct
type KustomizeConfig (line 75) | type KustomizeConfig struct
type RepoRef (line 81) | type RepoRef struct
type NameValue (line 86) | type NameValue struct
type Plugin (line 91) | type Plugin struct
type Secret (line 100) | type Secret struct
type SecretSource (line 105) | type SecretSource struct
type LiteralSource (line 111) | type LiteralSource struct
type HashedSource (line 115) | type HashedSource struct
type EnvSource (line 119) | type EnvSource struct
type SecretRef (line 124) | type SecretRef struct
type Repo (line 131) | type Repo struct
type Status (line 140) | type Status struct
type Condition (line 145) | type Condition struct
type Cache (line 160) | type Cache struct
type PluginKindType (line 165) | type PluginKindType
constant pluginNotFoundErrPrefix (line 170) | pluginNotFoundErrPrefix = "Missing plugin"
constant conditionNotFoundErrPrefix (line 174) | conditionNotFoundErrPrefix = "Missing condition"
constant AWS_PLUGIN_KIND (line 179) | AWS_PLUGIN_KIND PluginKindType = "KfAwsPlugin"
constant GCP_PLUGIN_KIND (line 180) | GCP_PLUGIN_KIND PluginKindType = "KfGcpPlugin"
constant MINIKUBE_PLUGIN_KIND (line 181) | MINIKUBE_PLUGIN_KIND PluginKindType = "KfMinikubePlugin"
constant EXISTING_ARRIKTO_PLUGIN_KIND (line 182) | EXISTING_ARRIKTO_PLUGIN_KIND PluginKindType = "KfExistingArriktoPlugin"
type ConditionType (line 185) | type ConditionType
constant Available (line 189) | Available ConditionType = "Available"
constant Degraded (line 192) | Degraded ConditionType = "Degraded"
constant Pending (line 195) | Pending ConditionType = "Pending"
function GetPluginSucceededCondition (line 201) | func GetPluginSucceededCondition(pluginKind PluginKindType) ConditionType {
function GetPluginFailedCondition (line 204) | func GetPluginFailedCondition(pluginKind PluginKindType) ConditionType {
function IsPluginNotFound (line 604) | func IsPluginNotFound(e error) bool {
function IsConditionNotFound (line 612) | func IsConditionNotFound(e error) bool {
type SecretNotFound (line 621) | type SecretNotFound struct
method Error (line 625) | func (e *SecretNotFound) Error() string {
function NewSecretNotFound (line 629) | func NewSecretNotFound(n string) *SecretNotFound {
function IsSecretNotFound (line 635) | func IsSecretNotFound(e error) bool {
type AppNotFound (line 643) | type AppNotFound struct
method Error (line 647) | func (e *AppNotFound) Error() string {
function IsAppNotFound (line 651) | func IsAppNotFound(e error) bool {
function getParameter (line 659) | func getParameter(parameters []NameValue, paramName string) (string, boo...
function setParameter (line 669) | func setParameter(parameters []NameValue, paramName string, value string...
FILE: pkg/apis/apps/kfconfig/zz_generated.deepcopy.go
method DeepCopyInto (line 28) | func (in *AppNotFound) DeepCopyInto(out *AppNotFound) {
method DeepCopy (line 34) | func (in *AppNotFound) DeepCopy() *AppNotFound {
method DeepCopyInto (line 44) | func (in *Application) DeepCopyInto(out *Application) {
method DeepCopy (line 55) | func (in *Application) DeepCopy() *Application {
method DeepCopyInto (line 65) | func (in *Cache) DeepCopyInto(out *Cache) {
method DeepCopy (line 71) | func (in *Cache) DeepCopy() *Cache {
method DeepCopyInto (line 81) | func (in *Condition) DeepCopyInto(out *Condition) {
method DeepCopy (line 89) | func (in *Condition) DeepCopy() *Condition {
method DeepCopyInto (line 99) | func (in *EnvSource) DeepCopyInto(out *EnvSource) {
method DeepCopy (line 105) | func (in *EnvSource) DeepCopy() *EnvSource {
method DeepCopyInto (line 115) | func (in *HashedSource) DeepCopyInto(out *HashedSource) {
method DeepCopy (line 121) | func (in *HashedSource) DeepCopy() *HashedSource {
method DeepCopyInto (line 131) | func (in *KfConfig) DeepCopyInto(out *KfConfig) {
method DeepCopy (line 141) | func (in *KfConfig) DeepCopy() *KfConfig {
method DeepCopyObject (line 151) | func (in *KfConfig) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 159) | func (in *KfConfigSpec) DeepCopyInto(out *KfConfigSpec) {
method DeepCopy (line 191) | func (in *KfConfigSpec) DeepCopy() *KfConfigSpec {
method DeepCopyInto (line 201) | func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) {
method DeepCopy (line 222) | func (in *KustomizeConfig) DeepCopy() *KustomizeConfig {
method DeepCopyInto (line 232) | func (in *LiteralSource) DeepCopyInto(out *LiteralSource) {
method DeepCopy (line 238) | func (in *LiteralSource) DeepCopy() *LiteralSource {
method DeepCopyInto (line 248) | func (in *NameValue) DeepCopyInto(out *NameValue) {
method DeepCopy (line 254) | func (in *NameValue) DeepCopy() *NameValue {
method DeepCopyInto (line 264) | func (in *Plugin) DeepCopyInto(out *Plugin) {
method DeepCopy (line 275) | func (in *Plugin) DeepCopy() *Plugin {
method DeepCopyInto (line 285) | func (in *Repo) DeepCopyInto(out *Repo) {
method DeepCopy (line 291) | func (in *Repo) DeepCopy() *Repo {
method DeepCopyInto (line 301) | func (in *RepoRef) DeepCopyInto(out *RepoRef) {
method DeepCopy (line 307) | func (in *RepoRef) DeepCopy() *RepoRef {
method DeepCopyInto (line 317) | func (in *Secret) DeepCopyInto(out *Secret) {
method DeepCopy (line 328) | func (in *Secret) DeepCopy() *Secret {
method DeepCopyInto (line 338) | func (in *SecretNotFound) DeepCopyInto(out *SecretNotFound) {
method DeepCopy (line 344) | func (in *SecretNotFound) DeepCopy() *SecretNotFound {
method DeepCopyInto (line 354) | func (in *SecretRef) DeepCopyInto(out *SecretRef) {
method DeepCopy (line 360) | func (in *SecretRef) DeepCopy() *SecretRef {
method DeepCopyInto (line 370) | func (in *SecretSource) DeepCopyInto(out *SecretSource) {
method DeepCopy (line 391) | func (in *SecretSource) DeepCopy() *SecretSource {
method DeepCopyInto (line 401) | func (in *Status) DeepCopyInto(out *Status) {
method DeepCopy (line 419) | func (in *Status) DeepCopy() *Status {
FILE: pkg/apis/apps/kfdef/v1/application_types.go
type KfDef (line 34) | type KfDef struct
method GetPluginSpec (line 169) | func (d *KfDef) GetPluginSpec(pluginKind string, s interface{}) error {
method SetPluginSpec (line 197) | func (d *KfDef) SetPluginSpec(pluginKind string, spec interface{}) err...
method GetSecret (line 243) | func (d *KfDef) GetSecret(name string) (string, error) {
method SetSecret (line 264) | func (d *KfDef) SetSecret(newSecret Secret) {
method DeleteApplication (line 274) | func (d *KfDef) DeleteApplication(appName string) {
method IsValid (line 289) | func (d *KfDef) IsValid() (bool, string) {
type KfDefList (line 45) | type KfDefList struct
type KfDefSpec (line 51) | type KfDefSpec struct
type Application (line 60) | type Application struct
type KustomizeConfig (line 65) | type KustomizeConfig struct
type RepoRef (line 71) | type RepoRef struct
type NameValue (line 76) | type NameValue struct
type Plugin (line 82) | type Plugin struct
type Secret (line 91) | type Secret struct
type SecretSource (line 96) | type SecretSource struct
type LiteralSource (line 101) | type LiteralSource struct
type EnvSource (line 105) | type EnvSource struct
type SecretRef (line 110) | type SecretRef struct
type Repo (line 117) | type Repo struct
type KfDefStatus (line 127) | type KfDefStatus struct
type RepoCache (line 133) | type RepoCache struct
type KfDefConditionType (line 138) | type KfDefConditionType
constant KfAvailable (line 142) | KfAvailable KfDefConditionType = "Available"
constant KfDegraded (line 145) | KfDegraded KfDefConditionType = "Degraded"
constant Pending (line 148) | Pending KfDefConditionType = "Pending"
type KfDefCondition (line 151) | type KfDefCondition struct
FILE: pkg/apis/apps/kfdef/v1/application_types_test.go
type FakePluginSpec (line 28) | type FakePluginSpec struct
function TestKfDef_GetPluginSpec (line 33) | func TestKfDef_GetPluginSpec(t *testing.T) {
function TestKfDef_SetPluginSpec (line 83) | func TestKfDef_SetPluginSpec(t *testing.T) {
function TestKfDef_GetSecret (line 140) | func TestKfDef_GetSecret(t *testing.T) {
function TestKfDef_SetSecret (line 193) | func TestKfDef_SetSecret(t *testing.T) {
function Test_DeleteApplication (line 281) | func Test_DeleteApplication(t *testing.T) {
function Pformat (line 326) | func Pformat(value interface{}) (string, error) {
FILE: pkg/apis/apps/kfdef/v1/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 59) | func init() {
FILE: pkg/apis/apps/kfdef/v1/zz_generated.deepcopy.go
method DeepCopyInto (line 28) | func (in *Application) DeepCopyInto(out *Application) {
method DeepCopy (line 39) | func (in *Application) DeepCopy() *Application {
method DeepCopyInto (line 49) | func (in *EnvSource) DeepCopyInto(out *EnvSource) {
method DeepCopy (line 55) | func (in *EnvSource) DeepCopy() *EnvSource {
method DeepCopyInto (line 65) | func (in *KfDef) DeepCopyInto(out *KfDef) {
method DeepCopy (line 75) | func (in *KfDef) DeepCopy() *KfDef {
method DeepCopyObject (line 85) | func (in *KfDef) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 93) | func (in *KfDefCondition) DeepCopyInto(out *KfDefCondition) {
method DeepCopy (line 101) | func (in *KfDefCondition) DeepCopy() *KfDefCondition {
method DeepCopyInto (line 111) | func (in *KfDefList) DeepCopyInto(out *KfDefList) {
method DeepCopy (line 126) | func (in *KfDefList) DeepCopy() *KfDefList {
method DeepCopyObject (line 136) | func (in *KfDefList) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 144) | func (in *KfDefSpec) DeepCopyInto(out *KfDefSpec) {
method DeepCopy (line 176) | func (in *KfDefSpec) DeepCopy() *KfDefSpec {
method DeepCopyInto (line 186) | func (in *KfDefStatus) DeepCopyInto(out *KfDefStatus) {
method DeepCopy (line 204) | func (in *KfDefStatus) DeepCopy() *KfDefStatus {
method DeepCopyInto (line 214) | func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) {
method DeepCopy (line 235) | func (in *KustomizeConfig) DeepCopy() *KustomizeConfig {
method DeepCopyInto (line 245) | func (in *LiteralSource) DeepCopyInto(out *LiteralSource) {
method DeepCopy (line 251) | func (in *LiteralSource) DeepCopy() *LiteralSource {
method DeepCopyInto (line 261) | func (in *NameValue) DeepCopyInto(out *NameValue) {
method DeepCopy (line 267) | func (in *NameValue) DeepCopy() *NameValue {
method DeepCopyInto (line 277) | func (in *Plugin) DeepCopyInto(out *Plugin) {
method DeepCopy (line 290) | func (in *Plugin) DeepCopy() *Plugin {
method DeepCopyInto (line 300) | func (in *Repo) DeepCopyInto(out *Repo) {
method DeepCopy (line 306) | func (in *Repo) DeepCopy() *Repo {
method DeepCopyInto (line 316) | func (in *RepoCache) DeepCopyInto(out *RepoCache) {
method DeepCopy (line 322) | func (in *RepoCache) DeepCopy() *RepoCache {
method DeepCopyInto (line 332) | func (in *RepoRef) DeepCopyInto(out *RepoRef) {
method DeepCopy (line 338) | func (in *RepoRef) DeepCopy() *RepoRef {
method DeepCopyInto (line 348) | func (in *Secret) DeepCopyInto(out *Secret) {
method DeepCopy (line 359) | func (in *Secret) DeepCopy() *Secret {
method DeepCopyInto (line 369) | func (in *SecretRef) DeepCopyInto(out *SecretRef) {
method DeepCopy (line 375) | func (in *SecretRef) DeepCopy() *SecretRef {
method DeepCopyInto (line 385) | func (in *SecretSource) DeepCopyInto(out *SecretSource) {
method DeepCopy (line 401) | func (in *SecretSource) DeepCopy() *SecretSource {
FILE: pkg/apis/apps/kfdef/v1alpha1/application_types.go
type KfDefSpec (line 39) | type KfDefSpec struct
type Application (line 82) | type Application struct
type KustomizeConfig (line 87) | type KustomizeConfig struct
type RepoRef (line 93) | type RepoRef struct
type Plugin (line 101) | type Plugin struct
type SecretRef (line 108) | type SecretRef struct
type Repo (line 115) | type Repo struct
type Secret (line 132) | type Secret struct
type SecretSource (line 137) | type SecretSource struct
type LiteralSource (line 143) | type LiteralSource struct
type HashedSource (line 147) | type HashedSource struct
type EnvSource (line 151) | type EnvSource struct
type RegistryConfig (line 162) | type RegistryConfig struct
type KsComponent (line 170) | type KsComponent struct
type KsLibrary (line 175) | type KsLibrary struct
type KsParameter (line 181) | type KsParameter struct
type KsModule (line 188) | type KsModule struct
type KsPackage (line 194) | type KsPackage struct
type Registry (line 200) | type Registry struct
type LibrarySpec (line 210) | type LibrarySpec struct
type KsRegistry (line 217) | type KsRegistry struct
type RegistriesConfigFile (line 225) | type RegistriesConfigFile struct
type AppConfig (line 230) | type AppConfig struct
type KfDefStatus (line 240) | type KfDefStatus struct
type RepoCache (line 246) | type RepoCache struct
type KfDefConditionType (line 250) | type KfDefConditionType
constant KfCreated (line 254) | KfCreated KfDefConditionType = "Created"
constant KfDeploying (line 257) | KfDeploying KfDefConditionType = "Deploying"
constant KfSucceeded (line 260) | KfSucceeded KfDefConditionType = "Succeeded"
constant KfFailed (line 263) | KfFailed KfDefConditionType = "Failed"
constant InvalidKfDefSpecReason (line 268) | InvalidKfDefSpecReason = "InvalidKfDefSpec"
type KfDefCondition (line 271) | type KfDefCondition struct
type KfDef (line 290) | type KfDef struct
method SyncCache (line 421) | func (d *KfDef) SyncCache() error {
method GetSecret (line 508) | func (d *KfDef) GetSecret(name string) (string, error) {
method SetSecret (line 529) | func (d *KfDef) SetSecret(newSecret Secret) {
method GetPluginSpec (line 543) | func (d *KfDef) GetPluginSpec(pluginName string, s interface{}) error {
method SetPluginSpec (line 570) | func (d *KfDef) SetPluginSpec(pluginName string, spec interface{}) err...
method IsValid (line 616) | func (d *KfDef) IsValid() (bool, string) {
method WriteToFile (line 635) | func (d *KfDef) WriteToFile(path string) error {
method GetApplicationParameter (line 751) | func (d *KfDef) GetApplicationParameter(appName string, paramName stri...
method SetApplicationParameter (line 770) | func (d *KfDef) SetApplicationParameter(appName string, paramName stri...
type KfDefList (line 301) | type KfDefList struct
function GetDefaultRegistry (line 308) | func GetDefaultRegistry() *RegistryConfig {
constant DefaultCacheDir (line 313) | DefaultCacheDir = ".cache"
function isValidUrl (line 315) | func isValidUrl(toTest string) bool {
function LoadKFDefFromURI (line 329) | func LoadKFDefFromURI(configFile string) (*KfDef, error) {
type PluginNotFound (line 660) | type PluginNotFound struct
method Error (line 664) | func (e *PluginNotFound) Error() string {
function NewPluginNotFound (line 668) | func NewPluginNotFound(n string) *PluginNotFound {
function IsPluginNotFound (line 674) | func IsPluginNotFound(e error) bool {
type SecretNotFound (line 682) | type SecretNotFound struct
method Error (line 686) | func (e *SecretNotFound) Error() string {
function NewSecretNotFound (line 690) | func NewSecretNotFound(n string) *SecretNotFound {
function IsSecretNotFound (line 696) | func IsSecretNotFound(e error) bool {
function getParameter (line 704) | func getParameter(parameters []config.NameValue, paramName string) (stri...
function setParameter (line 714) | func setParameter(parameters []config.NameValue, paramName string, value...
type AppNotFound (line 734) | type AppNotFound struct
method Error (line 738) | func (e *AppNotFound) Error() string {
function IsAppNotFound (line 742) | func IsAppNotFound(e error) bool {
FILE: pkg/apis/apps/kfdef/v1alpha1/application_types_test.go
function TestSyncCache (line 74) | func TestSyncCache(t *testing.T) {
function TestWriteKfDef (line 165) | func TestWriteKfDef(t *testing.T) {
type FakePluginSpec (line 246) | type FakePluginSpec struct
function TestKfDef_GetPluginSpec (line 251) | func TestKfDef_GetPluginSpec(t *testing.T) {
function TestKfDef_SetPluginSpec (line 301) | func TestKfDef_SetPluginSpec(t *testing.T) {
function TestKfDef_GetSecret (line 358) | func TestKfDef_GetSecret(t *testing.T) {
function TestKfDef_SetSecret (line 412) | func TestKfDef_SetSecret(t *testing.T) {
function Test_PluginNotFoundError (line 500) | func Test_PluginNotFoundError(t *testing.T) {
function TestKfDef_SetApplicationParameter (line 525) | func TestKfDef_SetApplicationParameter(t *testing.T) {
function TestKfDef_GetApplicationParameter (line 684) | func TestKfDef_GetApplicationParameter(t *testing.T) {
function Pformat (line 789) | func Pformat(value interface{}) (string, error) {
FILE: pkg/apis/apps/kfdef/v1alpha1/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 59) | func init() {
FILE: pkg/apis/apps/kfdef/v1alpha1/zz_generated.deepcopy.go
method DeepCopyInto (line 29) | func (in *AppConfig) DeepCopyInto(out *AppConfig) {
method DeepCopy (line 66) | func (in *AppConfig) DeepCopy() *AppConfig {
method DeepCopyInto (line 76) | func (in *AppNotFound) DeepCopyInto(out *AppNotFound) {
method DeepCopy (line 82) | func (in *AppNotFound) DeepCopy() *AppNotFound {
method DeepCopyInto (line 92) | func (in *Application) DeepCopyInto(out *Application) {
method DeepCopy (line 103) | func (in *Application) DeepCopy() *Application {
method DeepCopyInto (line 113) | func (in *EnvSource) DeepCopyInto(out *EnvSource) {
method DeepCopy (line 119) | func (in *EnvSource) DeepCopy() *EnvSource {
method DeepCopyInto (line 129) | func (in *HashedSource) DeepCopyInto(out *HashedSource) {
method DeepCopy (line 135) | func (in *HashedSource) DeepCopy() *HashedSource {
method DeepCopyInto (line 145) | func (in *KfDef) DeepCopyInto(out *KfDef) {
method DeepCopy (line 155) | func (in *KfDef) DeepCopy() *KfDef {
method DeepCopyObject (line 165) | func (in *KfDef) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 173) | func (in *KfDefCondition) DeepCopyInto(out *KfDefCondition) {
method DeepCopy (line 181) | func (in *KfDefCondition) DeepCopy() *KfDefCondition {
method DeepCopyInto (line 191) | func (in *KfDefList) DeepCopyInto(out *KfDefList) {
method DeepCopy (line 206) | func (in *KfDefList) DeepCopy() *KfDefList {
method DeepCopyObject (line 216) | func (in *KfDefList) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 224) | func (in *KfDefSpec) DeepCopyInto(out *KfDefSpec) {
method DeepCopy (line 257) | func (in *KfDefSpec) DeepCopy() *KfDefSpec {
method DeepCopyInto (line 267) | func (in *KfDefStatus) DeepCopyInto(out *KfDefStatus) {
method DeepCopy (line 287) | func (in *KfDefStatus) DeepCopy() *KfDefStatus {
method DeepCopyInto (line 297) | func (in *KsComponent) DeepCopyInto(out *KsComponent) {
method DeepCopy (line 303) | func (in *KsComponent) DeepCopy() *KsComponent {
method DeepCopyInto (line 313) | func (in *KsLibrary) DeepCopyInto(out *KsLibrary) {
method DeepCopy (line 319) | func (in *KsLibrary) DeepCopy() *KsLibrary {
method DeepCopyInto (line 329) | func (in *KsModule) DeepCopyInto(out *KsModule) {
method DeepCopy (line 357) | func (in *KsModule) DeepCopy() *KsModule {
method DeepCopyInto (line 367) | func (in *KsPackage) DeepCopyInto(out *KsPackage) {
method DeepCopy (line 373) | func (in *KsPackage) DeepCopy() *KsPackage {
method DeepCopyInto (line 383) | func (in *KsParameter) DeepCopyInto(out *KsParameter) {
method DeepCopy (line 389) | func (in *KsParameter) DeepCopy() *KsParameter {
method DeepCopyInto (line 399) | func (in *KsRegistry) DeepCopyInto(out *KsRegistry) {
method DeepCopy (line 412) | func (in *KsRegistry) DeepCopy() *KsRegistry {
method DeepCopyInto (line 422) | func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) {
method DeepCopy (line 443) | func (in *KustomizeConfig) DeepCopy() *KustomizeConfig {
method DeepCopyInto (line 453) | func (in *LibrarySpec) DeepCopyInto(out *LibrarySpec) {
method DeepCopy (line 459) | func (in *LibrarySpec) DeepCopy() *LibrarySpec {
method DeepCopyInto (line 469) | func (in *LiteralSource) DeepCopyInto(out *LiteralSource) {
method DeepCopy (line 475) | func (in *LiteralSource) DeepCopy() *LiteralSource {
method DeepCopyInto (line 485) | func (in *Plugin) DeepCopyInto(out *Plugin) {
method DeepCopy (line 496) | func (in *Plugin) DeepCopy() *Plugin {
method DeepCopyInto (line 506) | func (in *PluginNotFound) DeepCopyInto(out *PluginNotFound) {
method DeepCopy (line 512) | func (in *PluginNotFound) DeepCopy() *PluginNotFound {
method DeepCopyInto (line 522) | func (in *RegistriesConfigFile) DeepCopyInto(out *RegistriesConfigFile) {
method DeepCopy (line 539) | func (in *RegistriesConfigFile) DeepCopy() *RegistriesConfigFile {
method DeepCopyInto (line 549) | func (in *Registry) DeepCopyInto(out *Registry) {
method DeepCopy (line 555) | func (in *Registry) DeepCopy() *Registry {
method DeepCopyInto (line 565) | func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) {
method DeepCopy (line 571) | func (in *RegistryConfig) DeepCopy() *RegistryConfig {
method DeepCopyInto (line 581) | func (in *Repo) DeepCopyInto(out *Repo) {
method DeepCopy (line 587) | func (in *Repo) DeepCopy() *Repo {
method DeepCopyInto (line 597) | func (in *RepoCache) DeepCopyInto(out *RepoCache) {
method DeepCopy (line 603) | func (in *RepoCache) DeepCopy() *RepoCache {
method DeepCopyInto (line 613) | func (in *RepoRef) DeepCopyInto(out *RepoRef) {
method DeepCopy (line 619) | func (in *RepoRef) DeepCopy() *RepoRef {
method DeepCopyInto (line 629) | func (in *Secret) DeepCopyInto(out *Secret) {
method DeepCopy (line 640) | func (in *Secret) DeepCopy() *Secret {
method DeepCopyInto (line 650) | func (in *SecretNotFound) DeepCopyInto(out *SecretNotFound) {
method DeepCopy (line 656) | func (in *SecretNotFound) DeepCopy() *SecretNotFound {
method DeepCopyInto (line 666) | func (in *SecretRef) DeepCopyInto(out *SecretRef) {
method DeepCopy (line 672) | func (in *SecretRef) DeepCopy() *SecretRef {
method DeepCopyInto (line 682) | func (in *SecretSource) DeepCopyInto(out *SecretSource) {
method DeepCopy (line 703) | func (in *SecretSource) DeepCopy() *SecretSource {
FILE: pkg/apis/apps/kfdef/v1beta1/application_types.go
type KfDef (line 34) | type KfDef struct
method GetPluginSpec (line 169) | func (d *KfDef) GetPluginSpec(pluginKind string, s interface{}) error {
method SetPluginSpec (line 197) | func (d *KfDef) SetPluginSpec(pluginKind string, spec interface{}) err...
method GetSecret (line 243) | func (d *KfDef) GetSecret(name string) (string, error) {
method SetSecret (line 264) | func (d *KfDef) SetSecret(newSecret Secret) {
method DeleteApplication (line 274) | func (d *KfDef) DeleteApplication(appName string) {
method IsValid (line 289) | func (d *KfDef) IsValid() (bool, string) {
type KfDefList (line 45) | type KfDefList struct
type KfDefSpec (line 51) | type KfDefSpec struct
type Application (line 60) | type Application struct
type KustomizeConfig (line 65) | type KustomizeConfig struct
type RepoRef (line 71) | type RepoRef struct
type NameValue (line 76) | type NameValue struct
type Plugin (line 82) | type Plugin struct
type Secret (line 91) | type Secret struct
type SecretSource (line 96) | type SecretSource struct
type LiteralSource (line 101) | type LiteralSource struct
type EnvSource (line 105) | type EnvSource struct
type SecretRef (line 110) | type SecretRef struct
type Repo (line 117) | type Repo struct
type KfDefStatus (line 127) | type KfDefStatus struct
type RepoCache (line 133) | type RepoCache struct
type KfDefConditionType (line 138) | type KfDefConditionType
constant KfAvailable (line 142) | KfAvailable KfDefConditionType = "Available"
constant KfDegraded (line 145) | KfDegraded KfDefConditionType = "Degraded"
constant Pending (line 148) | Pending KfDefConditionType = "Pending"
type KfDefCondition (line 151) | type KfDefCondition struct
FILE: pkg/apis/apps/kfdef/v1beta1/application_types_test.go
type FakePluginSpec (line 28) | type FakePluginSpec struct
function TestKfDef_GetPluginSpec (line 33) | func TestKfDef_GetPluginSpec(t *testing.T) {
function TestKfDef_SetPluginSpec (line 83) | func TestKfDef_SetPluginSpec(t *testing.T) {
function TestKfDef_GetSecret (line 140) | func TestKfDef_GetSecret(t *testing.T) {
function TestKfDef_SetSecret (line 193) | func TestKfDef_SetSecret(t *testing.T) {
function Test_DeleteApplication (line 281) | func Test_DeleteApplication(t *testing.T) {
function Pformat (line 326) | func Pformat(value interface{}) (string, error) {
FILE: pkg/apis/apps/kfdef/v1beta1/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 59) | func init() {
FILE: pkg/apis/apps/kfdef/v1beta1/zz_generated.deepcopy.go
method DeepCopyInto (line 28) | func (in *Application) DeepCopyInto(out *Application) {
method DeepCopy (line 39) | func (in *Application) DeepCopy() *Application {
method DeepCopyInto (line 49) | func (in *EnvSource) DeepCopyInto(out *EnvSource) {
method DeepCopy (line 55) | func (in *EnvSource) DeepCopy() *EnvSource {
method DeepCopyInto (line 65) | func (in *KfDef) DeepCopyInto(out *KfDef) {
method DeepCopy (line 75) | func (in *KfDef) DeepCopy() *KfDef {
method DeepCopyObject (line 85) | func (in *KfDef) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 93) | func (in *KfDefCondition) DeepCopyInto(out *KfDefCondition) {
method DeepCopy (line 101) | func (in *KfDefCondition) DeepCopy() *KfDefCondition {
method DeepCopyInto (line 111) | func (in *KfDefList) DeepCopyInto(out *KfDefList) {
method DeepCopy (line 126) | func (in *KfDefList) DeepCopy() *KfDefList {
method DeepCopyObject (line 136) | func (in *KfDefList) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 144) | func (in *KfDefSpec) DeepCopyInto(out *KfDefSpec) {
method DeepCopy (line 176) | func (in *KfDefSpec) DeepCopy() *KfDefSpec {
method DeepCopyInto (line 186) | func (in *KfDefStatus) DeepCopyInto(out *KfDefStatus) {
method DeepCopy (line 204) | func (in *KfDefStatus) DeepCopy() *KfDefStatus {
method DeepCopyInto (line 214) | func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) {
method DeepCopy (line 235) | func (in *KustomizeConfig) DeepCopy() *KustomizeConfig {
method DeepCopyInto (line 245) | func (in *LiteralSource) DeepCopyInto(out *LiteralSource) {
method DeepCopy (line 251) | func (in *LiteralSource) DeepCopy() *LiteralSource {
method DeepCopyInto (line 261) | func (in *NameValue) DeepCopyInto(out *NameValue) {
method DeepCopy (line 267) | func (in *NameValue) DeepCopy() *NameValue {
method DeepCopyInto (line 277) | func (in *Plugin) DeepCopyInto(out *Plugin) {
method DeepCopy (line 290) | func (in *Plugin) DeepCopy() *Plugin {
method DeepCopyInto (line 300) | func (in *Repo) DeepCopyInto(out *Repo) {
method DeepCopy (line 306) | func (in *Repo) DeepCopy() *Repo {
method DeepCopyInto (line 316) | func (in *RepoCache) DeepCopyInto(out *RepoCache) {
method DeepCopy (line 322) | func (in *RepoCache) DeepCopy() *RepoCache {
method DeepCopyInto (line 332) | func (in *RepoRef) DeepCopyInto(out *RepoRef) {
method DeepCopy (line 338) | func (in *RepoRef) DeepCopy() *RepoRef {
method DeepCopyInto (line 348) | func (in *Secret) DeepCopyInto(out *Secret) {
method DeepCopy (line 359) | func (in *Secret) DeepCopy() *Secret {
method DeepCopyInto (line 369) | func (in *SecretRef) DeepCopyInto(out *SecretRef) {
method DeepCopy (line 375) | func (in *SecretRef) DeepCopy() *SecretRef {
method DeepCopyInto (line 385) | func (in *SecretSource) DeepCopyInto(out *SecretSource) {
method DeepCopy (line 401) | func (in *SecretSource) DeepCopy() *SecretSource {
FILE: pkg/apis/apps/kfupgrade/v1alpha1/application_types.go
constant KfUpgradeFile (line 30) | KfUpgradeFile = "update.yaml"
type KfUpgradeSpec (line 33) | type KfUpgradeSpec struct
type KfDefRef (line 46) | type KfDefRef struct
type KfUpgradeStatus (line 56) | type KfUpgradeStatus struct
type KfUpgradeConditionType (line 60) | type KfUpgradeConditionType
constant KfUpgradeInProgress (line 64) | KfUpgradeInProgress KfUpgradeConditionType = "InProgress"
constant KfUpgradeSucceeded (line 67) | KfUpgradeSucceeded KfUpgradeConditionType = "Succeeded"
constant KfUpgradeFailed (line 70) | KfUpgradeFailed KfUpgradeConditionType = "Failed"
constant InvalidKfUpgradeSpecReason (line 75) | InvalidKfUpgradeSpecReason = "InvalidKfUpgradeSpec"
type KfUpgradeCondition (line 78) | type KfUpgradeCondition struct
type KfUpgrade (line 97) | type KfUpgrade struct
method WriteToFile (line 159) | func (u *KfUpgrade) WriteToFile(path string) error {
type KfUpgradeList (line 108) | type KfUpgradeList struct
function LoadKfUpgradeFromUri (line 117) | func LoadKfUpgradeFromUri(configFile string) (*KfUpgrade, error) {
FILE: pkg/apis/apps/kfupgrade/v1alpha1/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 59) | func init() {
FILE: pkg/apis/apps/kfupgrade/v1alpha1/zz_generated.deepcopy.go
method DeepCopyInto (line 28) | func (in *KfDefRef) DeepCopyInto(out *KfDefRef) {
method DeepCopy (line 34) | func (in *KfDefRef) DeepCopy() *KfDefRef {
method DeepCopyInto (line 44) | func (in *KfUpgrade) DeepCopyInto(out *KfUpgrade) {
method DeepCopy (line 54) | func (in *KfUpgrade) DeepCopy() *KfUpgrade {
method DeepCopyObject (line 64) | func (in *KfUpgrade) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 72) | func (in *KfUpgradeCondition) DeepCopyInto(out *KfUpgradeCondition) {
method DeepCopy (line 80) | func (in *KfUpgradeCondition) DeepCopy() *KfUpgradeCondition {
method DeepCopyInto (line 90) | func (in *KfUpgradeList) DeepCopyInto(out *KfUpgradeList) {
method DeepCopy (line 105) | func (in *KfUpgradeList) DeepCopy() *KfUpgradeList {
method DeepCopyObject (line 115) | func (in *KfUpgradeList) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 123) | func (in *KfUpgradeSpec) DeepCopyInto(out *KfUpgradeSpec) {
method DeepCopy (line 139) | func (in *KfUpgradeSpec) DeepCopy() *KfUpgradeSpec {
method DeepCopyInto (line 149) | func (in *KfUpgradeStatus) DeepCopyInto(out *KfUpgradeStatus) {
method DeepCopy (line 162) | func (in *KfUpgradeStatus) DeepCopy() *KfUpgradeStatus {
FILE: pkg/apis/apps/plugins/aws/v1alpha1/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 58) | func init() {
FILE: pkg/apis/apps/plugins/aws/v1alpha1/types.go
type KfAwsPlugin (line 12) | type KfAwsPlugin struct
type AwsPluginSpec (line 20) | type AwsPluginSpec struct
method IsValid (line 58) | func (plugin *AwsPluginSpec) IsValid() (bool, string) {
type Auth (line 28) | type Auth struct
type BasicAuth (line 34) | type BasicAuth struct
type OIDC (line 39) | type OIDC struct
type Coginito (line 49) | type Coginito struct
FILE: pkg/apis/apps/plugins/aws/v1alpha1/zz_generated.deepcopy.go
method DeepCopyInto (line 29) | func (in *Auth) DeepCopyInto(out *Auth) {
method DeepCopy (line 50) | func (in *Auth) DeepCopy() *Auth {
method DeepCopyInto (line 60) | func (in *AwsPluginSpec) DeepCopyInto(out *AwsPluginSpec) {
method DeepCopy (line 76) | func (in *AwsPluginSpec) DeepCopy() *AwsPluginSpec {
method DeepCopyInto (line 86) | func (in *BasicAuth) DeepCopyInto(out *BasicAuth) {
method DeepCopy (line 97) | func (in *BasicAuth) DeepCopy() *BasicAuth {
method DeepCopyInto (line 107) | func (in *Coginito) DeepCopyInto(out *Coginito) {
method DeepCopy (line 113) | func (in *Coginito) DeepCopy() *Coginito {
method DeepCopyInto (line 123) | func (in *KfAwsPlugin) DeepCopyInto(out *KfAwsPlugin) {
method DeepCopy (line 132) | func (in *KfAwsPlugin) DeepCopy() *KfAwsPlugin {
method DeepCopyObject (line 142) | func (in *KfAwsPlugin) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 150) | func (in *OIDC) DeepCopyInto(out *OIDC) {
method DeepCopy (line 156) | func (in *OIDC) DeepCopy() *OIDC {
FILE: pkg/apis/apps/plugins/gcp/v1alpha1/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 58) | func init() {
FILE: pkg/apis/apps/plugins/gcp/v1alpha1/types.go
type KfGcpPlugin (line 13) | type KfGcpPlugin struct
type GcpPluginSpec (line 21) | type GcpPluginSpec struct
method IsValid (line 70) | func (s *GcpPluginSpec) IsValid() (bool, string) {
method GetCreatePipelinePersistentStorage (line 119) | func (p *GcpPluginSpec) GetCreatePipelinePersistentStorage() bool {
method GetEnableWorkloadIdentity (line 128) | func (p *GcpPluginSpec) GetEnableWorkloadIdentity() bool {
type Auth (line 49) | type Auth struct
type BasicAuth (line 54) | type BasicAuth struct
type IAP (line 59) | type IAP struct
type DeploymentManagerConfig (line 64) | type DeploymentManagerConfig struct
FILE: pkg/apis/apps/plugins/gcp/v1alpha1/types_test.go
function TestGcpPluginSpec_IsValid (line 9) | func TestGcpPluginSpec_IsValid(t *testing.T) {
FILE: pkg/apis/apps/plugins/gcp/v1alpha1/zz_generated.deepcopy.go
method DeepCopyInto (line 29) | func (in *Auth) DeepCopyInto(out *Auth) {
method DeepCopy (line 45) | func (in *Auth) DeepCopy() *Auth {
method DeepCopyInto (line 55) | func (in *BasicAuth) DeepCopyInto(out *BasicAuth) {
method DeepCopy (line 66) | func (in *BasicAuth) DeepCopy() *BasicAuth {
method DeepCopyInto (line 76) | func (in *DeploymentManagerConfig) DeepCopyInto(out *DeploymentManagerCo...
method DeepCopy (line 87) | func (in *DeploymentManagerConfig) DeepCopy() *DeploymentManagerConfig {
method DeepCopyInto (line 97) | func (in *GcpPluginSpec) DeepCopyInto(out *GcpPluginSpec) {
method DeepCopy (line 123) | func (in *GcpPluginSpec) DeepCopy() *GcpPluginSpec {
method DeepCopyInto (line 133) | func (in *IAP) DeepCopyInto(out *IAP) {
method DeepCopy (line 144) | func (in *IAP) DeepCopy() *IAP {
method DeepCopyInto (line 154) | func (in *KfGcpPlugin) DeepCopyInto(out *KfGcpPlugin) {
method DeepCopy (line 163) | func (in *KfGcpPlugin) DeepCopy() *KfGcpPlugin {
method DeepCopyObject (line 173) | func (in *KfGcpPlugin) DeepCopyObject() runtime.Object {
FILE: pkg/apis/kferrors.go
type StatusCode (line 22) | type StatusCode
constant OK (line 25) | OK StatusCode = 200
constant INVALID_ARGUMENT (line 26) | INVALID_ARGUMENT StatusCode = 400
constant NOT_FOUND (line 27) | NOT_FOUND StatusCode = 404
constant INTERNAL_ERROR (line 28) | INTERNAL_ERROR StatusCode = 500
constant UNKNOWN (line 29) | UNKNOWN StatusCode = 520
type KfError (line 34) | type KfError struct
method Error (line 40) | func (e *KfError) Error() string {
function IsNotFound (line 45) | func IsNotFound(e error) bool {
function NewKfErrorWithMessage (line 55) | func NewKfErrorWithMessage(e error, msg string) error {
FILE: pkg/controller/controller.go
function AddToManager (line 10) | func AddToManager(m manager.Manager) error {
FILE: pkg/controller/kfdef/const.go
constant KubeflowLabel (line 9) | KubeflowLabel = "app.kubernetes.io/managed-by"
FILE: pkg/controller/kfdef/kfdef_controller.go
constant finalizer (line 35) | finalizer = "kfdef-finalizer.kfdef.apps.kubeflow.org"
constant finalizerMaxRetries (line 37) | finalizerMaxRetries = 10
function AddToManager (line 53) | func AddToManager(m manager.Manager) error {
function Add (line 60) | func Add(mgr manager.Manager) error {
function newReconciler (line 65) | func newReconciler(mgr manager.Manager) reconcile.Reconciler {
function add (line 70) | func add(mgr manager.Manager, r reconcile.Reconciler) error {
function watchKubeflowResources (line 119) | func watchKubeflowResources(c controller.Controller, r client.Client, wa...
type ReconcileKfDef (line 227) | type ReconcileKfDef struct
method Reconcile (line 239) | func (r *ReconcileKfDef) Reconcile(request reconcile.Request) (reconci...
function kfApply (line 364) | func kfApply(instance *kfdefv1.KfDef) error {
function kfDelete (line 377) | func kfDelete(instance *kfdefv1.KfDef) error {
function kfLoadConfig (line 389) | func kfLoadConfig(instance *kfdefv1.KfDef, action string) (kftypesv3.KfA...
function setAnnotations (line 438) | func setAnnotations(configPath string, annotations map[string]string) er...
FILE: pkg/kfapp/aws/aws.go
constant KUBEFLOW_AWS_INFRA_DIR (line 53) | KUBEFLOW_AWS_INFRA_DIR = "aws_config"
constant KUBEFLOW_MANIFEST_DIR (line 54) | KUBEFLOW_MANIFEST_DIR = "kustomize"
constant CLUSTER_CONFIG_FILE (line 55) | CLUSTER_CONFIG_FILE = "cluster_config.yaml"
constant PATH (line 56) | PATH = "path"
constant BASIC_AUTH_SECRET (line 57) | BASIC_AUTH_SECRET = "kubeflow-login"
constant CONFIG_LOCAL_PATH (line 59) | CONFIG_LOCAL_PATH = "aws/infra_configs"
constant ALB_OIDC_SECRET (line 61) | ALB_OIDC_SECRET = "alb-oidc-secret"
constant IstioNamespace (line 64) | IstioNamespace = "istio-system"
constant AwsPluginName (line 67) | AwsPluginName = kfconfig.AWS_PLUGIN_KIND
constant MINIMUM_EKSCTL_VERSION (line 69) | MINIMUM_EKSCTL_VERSION = "0.1.32"
constant KUBEFLOW_ADMIN_ROLE_NAME (line 71) | KUBEFLOW_ADMIN_ROLE_NAME = "kf-admin-%v-%v"
constant KUBEFLOW_USER_ROLE_NAME (line 72) | KUBEFLOW_USER_ROLE_NAME = "kf-user-%v-%v"
type Aws (line 77) | type Aws struct
method GetPluginSpec (line 163) | func (aws *Aws) GetPluginSpec() (*awsplugin.AwsPluginSpec, error) {
method attachPoliciesToRoles (line 169) | func (aws *Aws) attachPoliciesToRoles(roles []string) error {
method updateEKSClusterConfig (line 192) | func (aws *Aws) updateEKSClusterConfig() error {
method getWorkerNodeGroupRoles (line 196) | func (aws *Aws) getWorkerNodeGroupRoles(clusterName string) ([]string,...
method updateClusterConfig (line 247) | func (aws *Aws) updateClusterConfig(clusterConfigFile string) error {
method generateInfraConfigs (line 295) | func (aws *Aws) generateInfraConfigs() error {
method generateBasicAuthPasswordHash (line 347) | func (aws *Aws) generateBasicAuthPasswordHash() (string, error) {
method Init (line 381) | func (aws *Aws) Init(resources kftypes.ResourceEnum) error {
method Generate (line 414) | func (aws *Aws) Generate(resources kftypes.ResourceEnum) error {
method setAwsPluginDefaults (line 608) | func (aws *Aws) setAwsPluginDefaults() error {
method Apply (line 646) | func (aws *Aws) Apply(resources kftypes.ResourceEnum) error {
method Delete (line 751) | func (aws *Aws) Delete(resources kftypes.ResourceEnum) error {
method Dump (line 804) | func (aws *Aws) Dump(resources kftypes.ResourceEnum) error {
method uninstallK8sDependencies (line 809) | func (aws *Aws) uninstallK8sDependencies() error {
method detachPoliciesFromWorkerRoles (line 866) | func (aws *Aws) detachPoliciesFromWorkerRoles() error {
method deleteIamRolePolicy (line 910) | func (aws *Aws) deleteIamRolePolicy(roleName, policyName string) error {
method attachIamInlinePolicy (line 929) | func (aws *Aws) attachIamInlinePolicy(roleName, policyName, policyDocu...
method setupIamRoleForServiceAccount (line 950) | func (aws *Aws) setupIamRoleForServiceAccount() error {
method deleteWebIdentityRolesAndProvider (line 1013) | func (aws *Aws) deleteWebIdentityRolesAndProvider() error {
method setupOIDC (line 1063) | func (aws *Aws) setupOIDC() error {
type manifest (line 94) | type manifest struct
function GetPlatform (line 100) | func GetPlatform(kfdef *kfconfig.KfConfig) (kftypes.Platform, error) {
function copyFile (line 218) | func copyFile(source string, dest string) error {
function base64EncryptPassword (line 367) | func base64EncryptPassword(password string) (string, error) {
function deleteManifests (line 846) | func deleteManifests(manifests []manifest) error {
FILE: pkg/kfapp/aws/eks.go
type Cluster (line 16) | type Cluster struct
method getEksCluster (line 26) | func (aws *Aws) getEksCluster(clusterName string) (*Cluster, error) {
method IsEksCluster (line 49) | func (aws *Aws) IsEksCluster(clusterName string) (bool, error) {
method createEKSCluster (line 70) | func (aws *Aws) createEKSCluster() error {
method deleteEKSCluster (line 102) | func (aws *Aws) deleteEKSCluster() error {
function isEksctlVersionLessThan (line 127) | func isEksctlVersionLessThan(v1, v2 string) (bool, error) {
FILE: pkg/kfapp/aws/eks_test.go
function TestIsEksctlVersionLessThan (line 8) | func TestIsEksctlVersionLessThan(t *testing.T) {
FILE: pkg/kfapp/aws/identity.go
constant AWS_DEFAULT_AUDIENCE (line 24) | AWS_DEFAULT_AUDIENCE = "sts.amazonaws.com"
constant AWS_TRUST_IDENTITY_SUBJECT (line 25) | AWS_TRUST_IDENTITY_SUBJECT = "system:serviceaccount:%s:%s"
constant AWS_SERVICE_ACCOUNT_ANNOTATION_KEY (line 26) | AWS_SERVICE_ACCOUNT_ANNOTATION_KEY = "eks.amazonaws.com/role-arn"
constant AWS_IAM_ROLE_TAG_KEY (line 27) | AWS_IAM_ROLE_TAG_KEY = "kubeflow/cluster-name"
constant AWS_IAM_ROLE_ARN (line 28) | AWS_IAM_ROLE_ARN = "arn:aws:iam::%s:role/%s"
method checkIdentityProviderExists (line 33) | func (aws *Aws) checkIdentityProviderExists(accountId, issuerURLWithoutP...
method createIdentityProvider (line 52) | func (aws *Aws) createIdentityProvider(issuerUrl string) (string, error) {
method DeleteIdentityProvider (line 71) | func (aws *Aws) DeleteIdentityProvider(providerArn string) error {
method createOrUpdateWebIdentityRole (line 82) | func (aws *Aws) createOrUpdateWebIdentityRole(oidcProviderArn, issuerUrl...
method createOrUpdateK8sServiceAccount (line 139) | func (aws *Aws) createOrUpdateK8sServiceAccount(k8sClientset *clientset....
method updateRoleTrustIdentity (line 181) | func (aws *Aws) updateRoleTrustIdentity(roleName, serviceAccountNamespac...
function getUpdatedAssumeRolePolicy (line 214) | func getUpdatedAssumeRolePolicy(policyDocument, serviceAccountNamespace,...
function getIssueCAThumbprint (line 263) | func getIssueCAThumbprint(issuerURL string) (string, error) {
method deleteIAMRole (line 291) | func (aws *Aws) deleteIAMRole(roleName string) error {
function getIAMRoleNameFromIAMRoleArn (line 304) | func getIAMRoleNameFromIAMRoleArn(arn string) string {
function getIssuerUrlFromRoleArn (line 309) | func getIssuerUrlFromRoleArn(arn string) string {
function MakeAssumeRoleWithWebIdentityPolicyDocument (line 314) | func MakeAssumeRoleWithWebIdentityPolicyDocument(providerARN string, con...
function MakePolicyDocument (line 326) | func MakePolicyDocument(statements ...MapOfInterfaces) MapOfInterfaces {
FILE: pkg/kfapp/aws/k8sClient.go
function getK8sclient (line 16) | func getK8sclient() (*clientset.Clientset, error) {
function homeDir (line 40) | func homeDir() string {
function createNamespace (line 47) | func createNamespace(client *clientset.Clientset, namespace string) error {
function deleteNamespace (line 65) | func deleteNamespace(client *clientset.Clientset, namespace string) error {
function createSecret (line 82) | func createSecret(client *clientset.Clientset, secretName string, namesp...
FILE: pkg/kfapp/coordinator/coordinator.go
type Builder (line 43) | type Builder interface
type DefaultBuilder (line 47) | type DefaultBuilder struct
method LoadKfAppCfgFile (line 50) | func (b *DefaultBuilder) LoadKfAppCfgFile(cfgFile string) (kftypesv3.K...
function getPlatform (line 56) | func getPlatform(kfdef *kfconfig.KfConfig) (kftypesv3.Platform, error) {
function getPackageManager (line 90) | func getPackageManager(kfdef *kfconfig.KfConfig) (kftypesv3.KfApp, error) {
function filterSpartakus (line 95) | func filterSpartakus(components []string) []string {
function usageReportWarn (line 106) | func usageReportWarn(applications []kfconfig.Application) {
function repoVersionToUri (line 133) | func repoVersionToUri(repo string, version string) string {
function isDirEmpty (line 149) | func isDirEmpty(dir string) bool {
function NewLoadKfAppFromURI (line 160) | func NewLoadKfAppFromURI(configFile string) (kftypesv3.KfApp, error) {
function CreateKfAppCfgFileWithKfDef (line 246) | func CreateKfAppCfgFileWithKfDef(d *kfdefsv1alpha1.KfDef) (string, error) {
function CreateKfAppCfgFile (line 261) | func CreateKfAppCfgFile(d *kfconfig.KfConfig) (string, error) {
function nameFromAppFile (line 283) | func nameFromAppFile(appFile string) string {
type coordinator (line 306) | type coordinator struct
method getPackageManagers (line 74) | func (coord *coordinator) getPackageManagers(kfdef *kfconfig.KfConfig)...
method GetKfDef (line 323) | func (kfapp *coordinator) GetKfDef() *kfdefsv1beta1.KfDef {
method GetKfDefV1Beta1 (line 328) | func (kfapp *coordinator) GetKfDefV1Beta1() *kfdefsv1beta1.KfDef {
method GetPlugin (line 343) | func (kfapp *coordinator) GetPlugin(name string) (kftypesv3.KfApp, boo...
method Dump (line 353) | func (kfapp *coordinator) Dump(resources kftypesv3.ResourceEnum) error {
method Apply (line 367) | func (kfapp *coordinator) Apply(resources kftypesv3.ResourceEnum) error {
method Delete (line 462) | func (kfapp *coordinator) Delete(resources kftypesv3.ResourceEnum) err...
method Generate (line 532) | func (kfapp *coordinator) Generate(resources kftypesv3.ResourceEnum) e...
method Init (line 602) | func (kfapp *coordinator) Init(resources kftypesv3.ResourceEnum) error {
method Show (line 662) | func (kfapp *coordinator) Show(resources kftypesv3.ResourceEnum) error {
type KfDefGetterV1beta1 (line 313) | type KfDefGetterV1beta1 interface
type PluginGetter (line 318) | type PluginGetter interface
FILE: pkg/kfapp/coordinator/coordinator_test.go
function Test_CreateKfAppCfgFile (line 16) | func Test_CreateKfAppCfgFile(t *testing.T) {
function Test_repoVersionToRepoStruct (line 112) | func Test_repoVersionToRepoStruct(t *testing.T) {
function Test_nameFromAppFile (line 143) | func Test_nameFromAppFile(t *testing.T) {
function Pformat (line 174) | func Pformat(value interface{}) (string, error) {
FILE: pkg/kfapp/coordinator/fake/fake.go
type FakeCoordinator (line 13) | type FakeCoordinator struct
method Apply (line 18) | func (f *FakeCoordinator) Apply(resources kftypes.ResourceEnum) error {
method Delete (line 22) | func (f *FakeCoordinator) Delete(resources kftypes.ResourceEnum) error {
method Dump (line 26) | func (f *FakeCoordinator) Dump(resources kftypes.ResourceEnum) error {
method Generate (line 30) | func (f *FakeCoordinator) Generate(resources kftypes.ResourceEnum) err...
method Init (line 34) | func (f *FakeCoordinator) Init(resources kftypes.ResourceEnum) error {
method GetKfDef (line 38) | func (f *FakeCoordinator) GetKfDef() *kfconfig.KfConfig {
method GetPlugin (line 42) | func (f *FakeCoordinator) GetPlugin(name string) (kftypes.KfApp, bool) {
type FakeBuilder (line 47) | type FakeBuilder struct
method CreateKfAppCfgFile (line 50) | func (b *FakeBuilder) CreateKfAppCfgFile(def *kfconfig.KfConfig) (stri...
method LoadKfAppCfgFile (line 54) | func (b *FakeBuilder) LoadKfAppCfgFile(cfgFile string) (kftypes.KfApp,...
FILE: pkg/kfapp/dockerfordesktop/dockerfordesktop.go
type DockerForDesktop (line 36) | type DockerForDesktop struct
method Apply (line 47) | func (dockerfordesktop *DockerForDesktop) Apply(resources kftypes.Reso...
method Delete (line 53) | func (dockerfordesktop *DockerForDesktop) Delete(resources kftypes.Res...
method Dump (line 57) | func (dockerfordesktop *DockerForDesktop) Dump(resources kftypes.Resou...
method generate (line 61) | func (dockerfordesktop *DockerForDesktop) generate() error {
method Generate (line 115) | func (dockerfordesktop *DockerForDesktop) Generate(resources kftypes.R...
method Init (line 133) | func (dockerfordesktop *DockerForDesktop) Init(resources kftypes.Resou...
method writeConfigFile (line 137) | func (dockerfordesktop *DockerForDesktop) writeConfigFile() error {
function GetKfApp (line 40) | func GetKfApp(kfdef *kfdefs.KfDef) kftypes.KfApp {
FILE: pkg/kfapp/existing_arrikto/existing.go
constant KUBEFLOW_USER_EMAIL (line 39) | KUBEFLOW_USER_EMAIL = "KUBEFLOW_USER_EMAIL"
constant KUBEFLOW_ENDPOINT (line 40) | KUBEFLOW_ENDPOINT = "KUBEFLOW_ENDPOINT"
constant OIDC_ENDPOINT (line 41) | OIDC_ENDPOINT = "OIDC_ENDPOINT"
constant CONFIG_LOCAL_PATH (line 44) | CONFIG_LOCAL_PATH = "kfdef/generic"
type Existing (line 47) | type Existing struct
method GetK8sConfig (line 100) | func (existing *Existing) GetK8sConfig() (*rest.Config, *clientcmdapi....
method Init (line 104) | func (existing *Existing) Init(resources kftypesv3.ResourceEnum) error {
method Generate (line 108) | func (existing *Existing) Generate(resources kftypesv3.ResourceEnum) e...
method Apply (line 112) | func (existing *Existing) Apply(resources kftypesv3.ResourceEnum) error {
method Delete (line 225) | func (existing *Existing) Delete(resources kftypesv3.ResourceEnum) err...
method Dump (line 272) | func (existing *Existing) Dump(resources kftypesv3.ResourceEnum) error {
type manifest (line 53) | type manifest struct
function GetPlatform (line 58) | func GetPlatform(kfdef *kfconfig.KfConfig) (kftypesv3.Platform, error) {
function internalError (line 276) | func internalError(err error) error {
type kfUser (line 283) | type kfUser struct
function getKubeflowUser (line 289) | func getKubeflowUser() (*kfUser, error) {
function getEndpoints (line 314) | func getEndpoints(kubeclient client.Client) (string, string, error) {
function createSelfSignedCerts (line 343) | func createSelfSignedCerts(kubeclient client.Client, addr string) error {
function generateCert (line 371) | func generateCert(addr string) ([]byte, []byte, error) {
function getLBAddress (line 429) | func getLBAddress(kubeclient client.Client) (string, error) {
function applyManifests (line 471) | func applyManifests(manifests []manifest) error {
function deleteManifests (line 487) | func deleteManifests(manifests []manifest) error {
function generateFromGoTemplate (line 507) | func generateFromGoTemplate(tmplPath, outPath string, data interface{}) ...
function genRandomString (line 522) | func genRandomString(length int) string {
FILE: pkg/kfapp/existing_arrikto/existing_test.go
function TestGenerateCert (line 13) | func TestGenerateCert(t *testing.T) {
function TestGetEndpoints (line 55) | func TestGetEndpoints(t *testing.T) {
function TestGetLBAddress (line 123) | func TestGetLBAddress(t *testing.T) {
FILE: pkg/kfapp/gcp/fake/fake.go
type FakeGcp (line 9) | type FakeGcp struct
method Apply (line 13) | func (g *FakeGcp) Apply(resources kftypes.ResourceEnum) error {
method Delete (line 17) | func (g *FakeGcp) Delete(resources kftypes.ResourceEnum) error {
method Dump (line 21) | func (g *FakeGcp) Dump(resources kftypes.ResourceEnum) error {
method Generate (line 25) | func (g *FakeGcp) Generate(resources kftypes.ResourceEnum) error {
method Init (line 29) | func (g *FakeGcp) Init(resources kftypes.ResourceEnum) error {
method SetTokenSource (line 33) | func (g *FakeGcp) SetTokenSource(s oauth2.TokenSource) error {
FILE: pkg/kfapp/gcp/gcp.go
constant GCP_CONFIG (line 73) | GCP_CONFIG = "gcp_config"
constant CONFIG_FILE (line 74) | CONFIG_FILE = "cluster-kubeflow.yaml"
constant STORAGE_FILE (line 75) | STORAGE_FILE = "storage-kubeflow.yaml"
constant NETWORK_FILE (line 76) | NETWORK_FILE = "network.yaml"
constant GCFS_FILE (line 77) | GCFS_FILE = "gcfs.yaml"
constant ADMIN_SECRET_NAME (line 78) | ADMIN_SECRET_NAME = "admin-gcp-sa"
constant USER_SECRET_NAME (line 79) | USER_SECRET_NAME = "user-gcp-sa"
constant KUBEFLOW_OAUTH (line 80) | KUBEFLOW_OAUTH = "kubeflow-oauth"
constant IMPORTS (line 81) | IMPORTS = "imports"
constant PATH (line 82) | PATH = "path"
constant CLIENT_ID (line 83) | CLIENT_ID = "CLIENT_ID"
constant CLIENT_SECRET (line 84) | CLIENT_SECRET = "CLIENT_SECRET"
constant BASIC_AUTH_SECRET (line 85) | BASIC_AUTH_SECRET = "kubeflow-login"
constant KUBECONFIG_FORMAT (line 86) | KUBECONFIG_FORMAT = "gke_{project}_{zone}_{cluster}"
constant DEFAULT_DM_PATH (line 91) | DEFAULT_DM_PATH = "deployment/gke/deployment_manager_configs"
constant GcpPluginName (line 94) | GcpPluginName = "KfGcpPlugin"
constant GcpAccessTokenName (line 95) | GcpAccessTokenName = "accessToken"
constant BasicAuthPasswordSecretName (line 96) | BasicAuthPasswordSecretName = "password"
constant PodDefaultName (line 98) | PodDefaultName = "add-gcp-secret"
constant DefaultIstioNamespace (line 100) | DefaultIstioNamespace = "istio-system"
type Gcp (line 106) | type Gcp struct
method SetTokenSource (line 127) | func (gcp *Gcp) SetTokenSource(s oauth2.TokenSource) error {
method SetRunGetCredentials (line 134) | func (gcp *Gcp) SetRunGetCredentials(v bool) {
method GetPluginSpec (line 159) | func (gcp *Gcp) GetPluginSpec() (*gcpplugin.GcpPluginSpec, error) {
method initGcpClient (line 169) | func (gcp *Gcp) initGcpClient() error {
method GetK8sConfig (line 217) | func (gcp *Gcp) GetK8sConfig() (*rest.Config, *clientcmdapi.Config) {
method getK8sClientset (line 342) | func (gcp *Gcp) getK8sClientset(ctx context.Context) (*clientset.Clien...
method updateDeployment (line 413) | func (gcp *Gcp) updateDeployment(deploymentmanagerService *deploymentm...
method ConfigK8s (line 552) | func (gcp *Gcp) ConfigK8s() error {
method AddNamedContext (line 586) | func (gcp *Gcp) AddNamedContext() error {
method updateDM (line 691) | func (gcp *Gcp) updateDM(resources kftypesv3.ResourceEnum) error {
method Apply (line 862) | func (gcp *Gcp) Apply(resources kftypesv3.ResourceEnum) error {
method deleteEndpoints (line 974) | func (gcp *Gcp) deleteEndpoints(ctx context.Context) error {
method Delete (line 1059) | func (gcp *Gcp) Delete(resources kftypesv3.ResourceEnum) error {
method Dump (line 1129) | func (gcp *Gcp) Dump(resources kftypesv3.ResourceEnum) error {
method copyFile (line 1133) | func (gcp *Gcp) copyFile(source string, dest string) error {
method getAccount (line 1162) | func (gcp *Gcp) getAccount() string {
method writeIamBindingsFile (line 1171) | func (gcp *Gcp) writeIamBindingsFile(src string, dest string) error {
method writeClusterConfig (line 1246) | func (gcp *Gcp) writeClusterConfig(src string, dest string, gcpPluginS...
method writeStorageConfig (line 1310) | func (gcp *Gcp) writeStorageConfig(src string, dest string) error {
method generateDMConfigs (line 1367) | func (gcp *Gcp) generateDMConfigs() error {
method createGcpServiceAcctSecret (line 1488) | func (gcp *Gcp) createGcpServiceAcctSecret(ctx context.Context, client...
method createIapSecret (line 1531) | func (gcp *Gcp) createIapSecret(ctx context.Context, client *clientset...
method buildBasicAuthSecret (line 1589) | func (gcp *Gcp) buildBasicAuthSecret() (*v1.Secret, error) {
method createBasicAuthSecret (line 1639) | func (gcp *Gcp) createBasicAuthSecret(client *clientset.Clientset) err...
method getIstioNamespace (line 1649) | func (gcp *Gcp) getIstioNamespace() string {
method createSecrets (line 1666) | func (gcp *Gcp) createSecrets() error {
method allowAdmineditUserSA (line 1698) | func (gcp *Gcp) allowAdmineditUserSA(gcpAdminSa string, gcpUserSa stri...
method setupWorkloadIdentity (line 1729) | func (gcp *Gcp) setupWorkloadIdentity(namespace string, k8sSa2gcpSa ma...
method SetupWorkloadIdentityPermission (line 1812) | func (gcp *Gcp) SetupWorkloadIdentityPermission() error {
method ConfigPodDefault (line 1875) | func (gcp *Gcp) ConfigPodDefault() error {
method setGcpPluginDefaults (line 1977) | func (gcp *Gcp) setGcpPluginDefaults() error {
method Generate (line 2101) | func (gcp *Gcp) Generate(resources kftypesv3.ResourceEnum) error {
method gcpInitProject (line 2249) | func (gcp *Gcp) gcpInitProject() error {
method Init (line 2323) | func (gcp *Gcp) Init(resources kftypesv3.ResourceEnum) error {
type Setter (line 120) | type Setter interface
type dmOperationEntry (line 138) | type dmOperationEntry struct
function GetPlatform (line 145) | func GetPlatform(kfdef *kfconfig.KfConfig) (kftypesv3.Platform, error) {
function newDefaultBackoff (line 204) | func newDefaultBackoff() *backoff.ExponentialBackOff {
function getSA (line 211) | func getSA(name string, nameSuffix string, project string) string {
function GetGcloudDefaultProject (line 240) | func GetGcloudDefaultProject() (string, error) {
function GetGcloudDefaultZone (line 252) | func GetGcloudDefaultZone() (string, error) {
function GetGcloudDefaultAccount (line 264) | func GetGcloudDefaultAccount() (string, error) {
function generateTarget (line 279) | func generateTarget(configPath string) (*deploymentmanager.TargetConfigu...
function blockingWait (line 369) | func blockingWait(project string, deploymentmanagerService *deploymentma...
function createNamespace (line 479) | func createNamespace(k8sClientset *clientset.Clientset, namespace string...
function bindAdmin (line 504) | func bindAdmin(k8sClientset *clientset.Clientset, user string) error {
function deleteDeployment (line 933) | func deleteDeployment(deploymentmanagerService *deploymentmanager.Servic...
function createOrUpdateSecret (line 1437) | func createOrUpdateSecret(client *clientset.Clientset, secret *v1.Secret...
function insertSecret (line 1464) | func insertSecret(client *clientset.Clientset, secretName string, namesp...
function base64EncryptPassword (line 1575) | func base64EncryptPassword(password string) (string, error) {
function createOrUpdateK8sServiceAccount (line 1771) | func createOrUpdateK8sServiceAccount(k8sClientset *clientset.Clientset, ...
function generatePodDefault (line 1826) | func generatePodDefault(group string, version string, kind string, names...
FILE: pkg/kfapp/gcp/gcp_test.go
function TestGcp_buildBasicAuthSecret (line 19) | func TestGcp_buildBasicAuthSecret(t *testing.T) {
function TestGcp_setGcpPluginDefaults (line 110) | func TestGcp_setGcpPluginDefaults(t *testing.T) {
function TestGcp_setPodDefault (line 443) | func TestGcp_setPodDefault(t *testing.T) {
function Pformat (line 495) | func Pformat(value interface{}) (string, error) {
FILE: pkg/kfapp/kustomize/kustomize.go
type MapType (line 82) | type MapType
constant basesMap (line 85) | basesMap MapType = 0
constant commonAnnotationsMap (line 86) | commonAnnotationsMap MapType = 1
constant commonLabelsMap (line 87) | commonLabelsMap MapType = 2
constant imagesMap (line 88) | imagesMap MapType = 3
constant resourcesMap (line 89) | resourcesMap MapType = 4
constant crdsMap (line 90) | crdsMap MapType = 5
constant varsMap (line 91) | varsMap MapType = 6
constant configurationsMap (line 92) | configurationsMap MapType = 7
constant configMapGeneratorMap (line 93) | configMapGeneratorMap MapType = 8
constant secretsMapGeneratorMap (line 94) | secretsMapGeneratorMap MapType = 9
constant patchesStrategicMergeMap (line 95) | patchesStrategicMergeMap MapType = 10
constant patchesJson6902Map (line 96) | patchesJson6902Map MapType = 11
constant OverlayParamName (line 97) | OverlayParamName = "overlay"
type kustomize (line 100) | type kustomize struct
method initK8sClients (line 142) | func (kustomize *kustomize) initK8sClients() error {
method render (line 151) | func (kustomize *kustomize) render(app kfconfig.Application) ([]byte, ...
method Dump (line 213) | func (kustomize *kustomize) Dump(resources kftypesv3.ResourceEnum) err...
method Apply (line 234) | func (kustomize *kustomize) Apply(resources kftypesv3.ResourceEnum) er...
method deleteGlobalResources (line 317) | func (kustomize *kustomize) deleteGlobalResources() error {
method Delete (line 367) | func (kustomize *kustomize) Delete(resources kftypesv3.ResourceEnum) e...
method Generate (line 525) | func (kustomize *kustomize) Generate(resources kftypesv3.ResourceEnum)...
method Init (line 729) | func (kustomize *kustomize) Init(resources kftypesv3.ResourceEnum) err...
method mapDirs (line 735) | func (kustomize *kustomize) mapDirs(dirPath string, root bool, depth i...
method SetK8sRestConfig (line 778) | func (kustomize *kustomize) SetK8sRestConfig(r *rest.Config) {
constant defaultUserId (line 113) | defaultUserId = "anonymous"
constant outputDir (line 114) | outputDir = "kustomize"
type Setter (line 118) | type Setter interface
function GetKfApp (line 123) | func GetKfApp(kfdef *kfconfig.KfConfig) kftypesv3.KfApp {
function sortResourceByKind (line 509) | func sortResourceByKind(resMap resmap.ResMap, order utils.SortOrder) {
function createStackAppKustomization (line 660) | func createStackAppKustomization(stackAppDir string, basePath string) (s...
function GetKustomization (line 784) | func GetKustomization(kustomizationPath string) *types.Kustomization {
function ReadUnstructured (line 800) | func ReadUnstructured(kfDefFile string) (*unstructured.Unstructured, err...
function ReadKfDef (line 813) | func ReadKfDef(kfDefFile string) *kfdefsv3.KfDef {
function WriteKfDef (line 826) | func WriteKfDef(kfdef *kfdefsv3.KfDef, kfdefpath string) error {
function MergeKustomization (line 844) | func MergeKustomization(compDir string, targetDir string, kfDef *kfconfi...
function MergeKustomizations (line 1084) | func MergeKustomizations(kfDef *kfconfig.KfConfig, compDir string, overl...
function GenerateKustomizationFile (line 1218) | func GenerateKustomizationFile(kfDef *kfconfig.KfConfig, root string,
function EvaluateKustomizeManifest (line 1287) | func EvaluateKustomizeManifest(compDir string) (resmap.ResMap, error) {
function WriteKustomizationFile (line 1315) | func WriteKustomizationFile(name string, kustomizeDir string, resMap res...
function readLines (line 1338) | func readLines(path string) ([]string, error) {
function writeLines (line 1354) | func writeLines(lines []string, path string) error {
function extractSuffix (line 1370) | func extractSuffix(dirPath string, subDirPath string) string {
function CreateKustomizationMaps (line 1375) | func CreateKustomizationMaps() map[MapType]map[string]bool {
function GenerateYamlWithOperatorAnnotation (line 1394) | func GenerateYamlWithOperatorAnnotation(resMap resmap.ResMap, instance *...
FILE: pkg/kfapp/kustomize/kustomize_test.go
function TestGenerateKustomizationFile (line 21) | func TestGenerateKustomizationFile(t *testing.T) {
function TestGenerateYamlWithOperatorAnnotation (line 92) | func TestGenerateYamlWithOperatorAnnotation(t *testing.T) {
function TestCreateStackAppKustomization (line 128) | func TestCreateStackAppKustomization(t *testing.T) {
FILE: pkg/kfapp/minikube/minikube.go
type Minikube (line 42) | type Minikube struct
method GetK8sConfig (line 54) | func (minikube *Minikube) GetK8sConfig() (*rest.Config, *clientcmdapi....
method Apply (line 58) | func (minikube *Minikube) Apply(resources kftypes.ResourceEnum) error {
method Delete (line 64) | func (minikube *Minikube) Delete(resources kftypes.ResourceEnum) error {
method Dump (line 68) | func (minikube *Minikube) Dump(resources kftypes.ResourceEnum) error {
method generate (line 72) | func (minikube *Minikube) generate() error {
method Generate (line 128) | func (minikube *Minikube) Generate(resources kftypes.ResourceEnum) err...
method Init (line 152) | func (minikube *Minikube) Init(kftypes.ResourceEnum) error {
method writeConfigFile (line 156) | func (minikube *Minikube) writeConfigFile() error {
function Getplatform (line 46) | func Getplatform(kfdef *kfconfig.KfConfig) kftypes.Platform {
FILE: pkg/kfconfig/awsplugin/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 58) | func init() {
FILE: pkg/kfconfig/awsplugin/types.go
type KfAwsPlugin (line 11) | type KfAwsPlugin struct
type AwsPluginSpec (line 19) | type AwsPluginSpec struct
method IsValid (line 86) | func (plugin *AwsPluginSpec) IsValid() (bool, string) {
method GetEnablePodIamPolicy (line 221) | func (p *AwsPluginSpec) GetEnablePodIamPolicy() bool {
method GetEnableNodeGroupLog (line 231) | func (p *AwsPluginSpec) GetEnableNodeGroupLog() bool {
method GetManagedCluster (line 241) | func (p *AwsPluginSpec) GetManagedCluster() bool {
type RelationDatabaseConfig (line 41) | type RelationDatabaseConfig struct
type ObjectStorageConfig (line 49) | type ObjectStorageConfig struct
type Auth (line 56) | type Auth struct
type BasicAuth (line 62) | type BasicAuth struct
type OIDC (line 67) | type OIDC struct
type Coginito (line 77) | type Coginito struct
FILE: pkg/kfconfig/awsplugin/zz_generated.deepcopy.go
method DeepCopyInto (line 28) | func (in *Auth) DeepCopyInto(out *Auth) {
method DeepCopy (line 49) | func (in *Auth) DeepCopy() *Auth {
method DeepCopyInto (line 59) | func (in *AwsPluginSpec) DeepCopyInto(out *AwsPluginSpec) {
method DeepCopy (line 100) | func (in *AwsPluginSpec) DeepCopy() *AwsPluginSpec {
method DeepCopyInto (line 110) | func (in *BasicAuth) DeepCopyInto(out *BasicAuth) {
method DeepCopy (line 121) | func (in *BasicAuth) DeepCopy() *BasicAuth {
method DeepCopyInto (line 131) | func (in *Coginito) DeepCopyInto(out *Coginito) {
method DeepCopy (line 137) | func (in *Coginito) DeepCopy() *Coginito {
method DeepCopyInto (line 147) | func (in *KfAwsPlugin) DeepCopyInto(out *KfAwsPlugin) {
method DeepCopy (line 156) | func (in *KfAwsPlugin) DeepCopy() *KfAwsPlugin {
method DeepCopyObject (line 166) | func (in *KfAwsPlugin) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 174) | func (in *OIDC) DeepCopyInto(out *OIDC) {
method DeepCopy (line 180) | func (in *OIDC) DeepCopy() *OIDC {
method DeepCopyInto (line 190) | func (in *ObjectStorageConfig) DeepCopyInto(out *ObjectStorageConfig) {
method DeepCopy (line 196) | func (in *ObjectStorageConfig) DeepCopy() *ObjectStorageConfig {
method DeepCopyInto (line 206) | func (in *RelationDatabaseConfig) DeepCopyInto(out *RelationDatabaseConf...
method DeepCopy (line 217) | func (in *RelationDatabaseConfig) DeepCopy() *RelationDatabaseConfig {
FILE: pkg/kfconfig/gcpplugin/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 58) | func init() {
FILE: pkg/kfconfig/gcpplugin/types.go
type KfGcpPlugin (line 15) | type KfGcpPlugin struct
type GcpPluginSpec (line 23) | type GcpPluginSpec struct
method IsValid (line 72) | func (s *GcpPluginSpec) IsValid() error {
method GetCreatePipelinePersistentStorage (line 135) | func (p *GcpPluginSpec) GetCreatePipelinePersistentStorage() bool {
method GetEnableWorkloadIdentity (line 144) | func (p *GcpPluginSpec) GetEnableWorkloadIdentity() bool {
type Auth (line 51) | type Auth struct
type BasicAuth (line 56) | type BasicAuth struct
type IAP (line 61) | type IAP struct
type DeploymentManagerConfig (line 66) | type DeploymentManagerConfig struct
FILE: pkg/kfconfig/gcpplugin/types_test.go
function TestGcpPluginSpec_IsValid (line 10) | func TestGcpPluginSpec_IsValid(t *testing.T) {
FILE: pkg/kfconfig/gcpplugin/zz_generated.deepcopy.go
method DeepCopyInto (line 29) | func (in *Auth) DeepCopyInto(out *Auth) {
method DeepCopy (line 45) | func (in *Auth) DeepCopy() *Auth {
method DeepCopyInto (line 55) | func (in *BasicAuth) DeepCopyInto(out *BasicAuth) {
method DeepCopy (line 66) | func (in *BasicAuth) DeepCopy() *BasicAuth {
method DeepCopyInto (line 76) | func (in *DeploymentManagerConfig) DeepCopyInto(out *DeploymentManagerCo...
method DeepCopy (line 87) | func (in *DeploymentManagerConfig) DeepCopy() *DeploymentManagerConfig {
method DeepCopyInto (line 97) | func (in *GcpPluginSpec) DeepCopyInto(out *GcpPluginSpec) {
method DeepCopy (line 123) | func (in *GcpPluginSpec) DeepCopy() *GcpPluginSpec {
method DeepCopyInto (line 133) | func (in *IAP) DeepCopyInto(out *IAP) {
method DeepCopy (line 144) | func (in *IAP) DeepCopy() *IAP {
method DeepCopyInto (line 154) | func (in *KfGcpPlugin) DeepCopyInto(out *KfGcpPlugin) {
method DeepCopy (line 163) | func (in *KfGcpPlugin) DeepCopy() *KfGcpPlugin {
method DeepCopyObject (line 173) | func (in *KfGcpPlugin) DeepCopyObject() runtime.Object {
FILE: pkg/kfconfig/loaders/loaders.go
type Loader (line 21) | type Loader interface
constant Api (line 27) | Api = "kfdef.apps.kubeflow.org"
function isValidUrl (line 30) | func isValidUrl(toTest string) bool {
function LoadConfigFromURI (line 44) | func LoadConfigFromURI(configFile string) (*kfconfig.KfConfig, error) {
function isCwdEmpty (line 183) | func isCwdEmpty() string {
function WriteConfigToFile (line 192) | func WriteConfigToFile(config kfconfig.KfConfig) error {
FILE: pkg/kfconfig/loaders/loaders_test.go
function Test_loadKfdefLiteralSecrets (line 10) | func Test_loadKfdefLiteralSecrets(t *testing.T) {
FILE: pkg/kfconfig/loaders/utils.go
function maybeGetPlatform (line 8) | func maybeGetPlatform(pluginKind string) string {
FILE: pkg/kfconfig/loaders/v1.go
type V1 (line 14) | type V1 struct
method LoadKfConfig (line 17) | func (v V1) LoadKfConfig(def interface{}) (*kfconfig.KfConfig, error) {
method LoadKfDef (line 168) | func (v V1) LoadKfDef(config kfconfig.KfConfig, out interface{}) error {
FILE: pkg/kfconfig/loaders/v1_test.go
function TestV1_expectedConfig (line 16) | func TestV1_expectedConfig(t *testing.T) {
FILE: pkg/kfconfig/loaders/v1alpha1.go
type V1alpha1 (line 15) | type V1alpha1 struct
method LoadKfConfig (line 54) | func (v V1alpha1) LoadKfConfig(def interface{}) (*kfconfig.KfConfig, e...
method LoadKfDef (line 197) | func (v V1alpha1) LoadKfDef(config kfconfig.KfConfig, out interface{})...
function pluginNameToKind (line 18) | func pluginNameToKind(pluginName string) kfconfig.PluginKindType {
function copyGcpPluginSpec (line 34) | func copyGcpPluginSpec(from *kfdeftypes.KfDef, to *kfconfig.KfConfig) er...
FILE: pkg/kfconfig/loaders/v1alpha1_test.go
function TestV1alpha1_ConvertToKfConfigs (line 18) | func TestV1alpha1_ConvertToKfConfigs(t *testing.T) {
function TestV1alpha1_ConvertToKfDef (line 69) | func TestV1alpha1_ConvertToKfDef(t *testing.T) {
FILE: pkg/kfconfig/loaders/v1beta1.go
type V1beta1 (line 14) | type V1beta1 struct
method LoadKfConfig (line 17) | func (v V1beta1) LoadKfConfig(def interface{}) (*kfconfig.KfConfig, er...
method LoadKfDef (line 163) | func (v V1beta1) LoadKfDef(config kfconfig.KfConfig, out interface{}) ...
FILE: pkg/kfconfig/loaders/v1beta1_test.go
function TestV1beta1_expectedConfig (line 16) | func TestV1beta1_expectedConfig(t *testing.T) {
FILE: pkg/kfconfig/register.go
function Resource (line 46) | func Resource(resource string) schema.GroupResource {
function addKnownTypes (line 50) | func addKnownTypes(scheme *runtime.Scheme) error {
function init (line 58) | func init() {
FILE: pkg/kfconfig/types.go
constant DefaultCacheDir (line 31) | DefaultCacheDir = ".cache"
constant KfAppsStackName (line 34) | KfAppsStackName = "kubeflow-apps"
constant KustomizeDir (line 35) | KustomizeDir = "kustomize"
type KfConfig (line 42) | type KfConfig struct
method GetRepoCache (line 223) | func (c *KfConfig) GetRepoCache(repoName string) (Cache, bool) {
method GetPluginSpec (line 232) | func (c *KfConfig) GetPluginSpec(pluginKind PluginKindType, s interfac...
method SetPluginSpec (line 267) | func (c *KfConfig) SetPluginSpec(pluginKind PluginKindType, spec inter...
method SetCondition (line 321) | func (c *KfConfig) SetCondition(condType ConditionType,
method GetCondition (line 349) | func (c *KfConfig) GetCondition(condType ConditionType) (*Condition, e...
method IsPluginFinished (line 361) | func (c *KfConfig) IsPluginFinished(pluginKind PluginKindType) bool {
method SetPluginFinished (line 374) | func (c *KfConfig) SetPluginFinished(pluginKind PluginKindType, msg st...
method IsPluginFailed (line 385) | func (c *KfConfig) IsPluginFailed(pluginKind PluginKindType) bool {
method SetPluginFailed (line 398) | func (c *KfConfig) SetPluginFailed(pluginKind PluginKindType, msg stri...
method SyncCache (line 440) | func (c *KfConfig) SyncCache() error {
method GetSecret (line 660) | func (c *KfConfig) GetSecret(name string) (string, error) {
method GetSecretSource (line 681) | func (c *KfConfig) GetSecretSource(name string) (*SecretSource, error) {
method GetApplicationParameter (line 691) | func (c *KfConfig) GetApplicationParameter(appName string, paramName s...
method legacySetApplicationParameter (line 815) | func (c *KfConfig) legacySetApplicationParameter(appName string, param...
method SetApplicationParameter (line 843) | func (c *KfConfig) SetApplicationParameter(appName string, paramName s...
method UsingStacks (line 885) | func (c *KfConfig) UsingStacks() bool {
method DeleteApplication (line 897) | func (c *KfConfig) DeleteApplication(appName string) error {
method AddApplicationOverlay (line 917) | func (c *KfConfig) AddApplicationOverlay(appName, overlayName string) ...
method RemoveApplicationOverlay (line 948) | func (c *KfConfig) RemoveApplicationOverlay(appName, overlayName strin...
method SetSecret (line 981) | func (c *KfConfig) SetSecret(newSecret Secret) {
type KfConfigSpec (line 51) | type KfConfigSpec struct
type Application (line 83) | type Application struct
type KustomizeConfig (line 88) | type KustomizeConfig struct
type RepoRef (line 94) | type RepoRef struct
type NameValue (line 99) | type NameValue struct
type Plugin (line 104) | type Plugin struct
type Secret (line 113) | type Secret struct
type SecretSource (line 118) | type SecretSource struct
type LiteralSource (line 124) | type LiteralSource struct
type HashedSource (line 128) | type HashedSource struct
type EnvSource (line 132) | type EnvSource struct
type SecretRef (line 137) | type SecretRef struct
type Repo (line 144) | type Repo struct
type Status (line 153) | type Status struct
type Condition (line 158) | type Condition struct
type Cache (line 173) | type Cache struct
type PluginKindType (line 178) | type PluginKindType
constant pluginNotFoundErrPrefix (line 183) | pluginNotFoundErrPrefix = "Missing plugin"
constant conditionNotFoundErrPrefix (line 187) | conditionNotFoundErrPrefix = "Missing condition"
constant AWS_PLUGIN_KIND (line 192) | AWS_PLUGIN_KIND PluginKindType = "KfAwsPlugin"
constant GCP_PLUGIN_KIND (line 193) | GCP_PLUGIN_KIND PluginKindType = "KfGcpPlugin"
constant MINIKUBE_PLUGIN_KIND (line 194) | MINIKUBE_PLUGIN_KIND PluginKindType = "KfMinikubePlugin"
constant EXISTING_ARRIKTO_PLUGIN_KIND (line 195) | EXISTING_ARRIKTO_PLUGIN_KIND PluginKindType = "KfExistingArriktoPlugin"
type ConditionType (line 198) | type ConditionType
constant Available (line 202) | Available ConditionType = "Available"
constant Degraded (line 205) | Degraded ConditionType = "Degraded"
constant Pending (line 208) | Pending ConditionType = "Pending"
function GetPluginSucceededCondition (line 214) | func GetPluginSucceededCondition(pluginKind PluginKindType) ConditionType {
function GetPluginFailedCondition (line 217) | func GetPluginFailedCondition(pluginKind PluginKindType) ConditionType {
function untar (line 611) | func untar(body []byte, cacheDir string) error {
function addPatchStratgicMerge (line 706) | func addPatchStratgicMerge(k *types.Kustomization, patchFile string) bool {
function setApplicationParameterInConfigMap (line 729) | func setApplicationParameterInConfigMap(kustomizeDir string, appName str...
function IsPluginNotFound (line 992) | func IsPluginNotFound(e error) bool {
function IsConditionNotFound (line 1000) | func IsConditionNotFound(e error) bool {
type SecretNotFound (line 1009) | type SecretNotFound struct
method Error (line 1013) | func (e *SecretNotFound) Error() string {
function NewSecretNotFound (line 1017) | func NewSecretNotFound(n string) *SecretNotFound {
function IsSecretNotFound (line 1023) | func IsSecretNotFound(e error) bool {
type AppNotFound (line 1031) | type AppNotFound struct
method Error (line 1035) | func (e *AppNotFound) Error() string {
function IsAppNotFound (line 1039) | func IsAppNotFound(e error) bool {
function getParameter (line 1047) | func getParameter(parameters []NameValue, paramName string) (string, boo...
function setParameter (line 1057) | func setParameter(parameters []NameValue, paramName string, value string...
FILE: pkg/kfconfig/types_test.go
function TestSyncCache (line 35) | func TestSyncCache(t *testing.T) {
type FakePluginSpec (line 206) | type FakePluginSpec struct
function TestKfConfig_GetPluginSpec (line 211) | func TestKfConfig_GetPluginSpec(t *testing.T) {
function TestKfConfig_SetPluginSpec (line 263) | func TestKfConfig_SetPluginSpec(t *testing.T) {
function TestKfConfig_GetSecret (line 324) | func TestKfConfig_GetSecret(t *testing.T) {
function TestKfConfig_SetSecret (line 378) | func TestKfConfig_SetSecret(t *testing.T) {
function TestKfConfig_addPatchStratgicMerge (line 466) | func TestKfConfig_addPatchStratgicMerge(t *testing.T) {
function Test_setApplicationParameterInConfigMap (line 514) | func Test_setApplicationParameterInConfigMap(t *testing.T) {
function TestKfConfig_SetApplicationParameter (line 668) | func TestKfConfig_SetApplicationParameter(t *testing.T) {
function TestKfConfig_GetApplicationParameter (line 763) | func TestKfConfig_GetApplicationParameter(t *testing.T) {
function TestKfConfig_DeleteApplication (line 829) | func TestKfConfig_DeleteApplication(t *testing.T) {
function TestKfConfig_AddApplicationOverlay (line 901) | func TestKfConfig_AddApplicationOverlay(t *testing.T) {
function TestKfConfig_RemoveApplicationOverlay (line 1026) | func TestKfConfig_RemoveApplicationOverlay(t *testing.T) {
function Pformat (line 1223) | func Pformat(value interface{}) (string, error) {
FILE: pkg/kfconfig/zz_generated.deepcopy.go
method DeepCopyInto (line 28) | func (in *AppNotFound) DeepCopyInto(out *AppNotFound) {
method DeepCopy (line 34) | func (in *AppNotFound) DeepCopy() *AppNotFound {
method DeepCopyInto (line 44) | func (in *Application) DeepCopyInto(out *Application) {
method DeepCopy (line 55) | func (in *Application) DeepCopy() *Application {
method DeepCopyInto (line 65) | func (in *Cache) DeepCopyInto(out *Cache) {
method DeepCopy (line 71) | func (in *Cache) DeepCopy() *Cache {
method DeepCopyInto (line 81) | func (in *Condition) DeepCopyInto(out *Condition) {
method DeepCopy (line 89) | func (in *Condition) DeepCopy() *Condition {
method DeepCopyInto (line 99) | func (in *EnvSource) DeepCopyInto(out *EnvSource) {
method DeepCopy (line 105) | func (in *EnvSource) DeepCopy() *EnvSource {
method DeepCopyInto (line 115) | func (in *HashedSource) DeepCopyInto(out *HashedSource) {
method DeepCopy (line 121) | func (in *HashedSource) DeepCopy() *HashedSource {
method DeepCopyInto (line 131) | func (in *KfConfig) DeepCopyInto(out *KfConfig) {
method DeepCopy (line 141) | func (in *KfConfig) DeepCopy() *KfConfig {
method DeepCopyObject (line 151) | func (in *KfConfig) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 159) | func (in *KfConfigSpec) DeepCopyInto(out *KfConfigSpec) {
method DeepCopy (line 191) | func (in *KfConfigSpec) DeepCopy() *KfConfigSpec {
method DeepCopyInto (line 201) | func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) {
method DeepCopy (line 222) | func (in *KustomizeConfig) DeepCopy() *KustomizeConfig {
method DeepCopyInto (line 232) | func (in *LiteralSource) DeepCopyInto(out *LiteralSource) {
method DeepCopy (line 238) | func (in *LiteralSource) DeepCopy() *LiteralSource {
method DeepCopyInto (line 248) | func (in *NameValue) DeepCopyInto(out *NameValue) {
method DeepCopy (line 254) | func (in *NameValue) DeepCopy() *NameValue {
method DeepCopyInto (line 264) | func (in *Plugin) DeepCopyInto(out *Plugin) {
method DeepCopy (line 275) | func (in *Plugin) DeepCopy() *Plugin {
method DeepCopyInto (line 285) | func (in *Repo) DeepCopyInto(out *Repo) {
method DeepCopy (line 291) | func (in *Repo) DeepCopy() *Repo {
method DeepCopyInto (line 301) | func (in *RepoRef) DeepCopyInto(out *RepoRef) {
method DeepCopy (line 307) | func (in *RepoRef) DeepCopy() *RepoRef {
method DeepCopyInto (line 317) | func (in *Secret) DeepCopyInto(out *Secret) {
method DeepCopy (line 328) | func (in *Secret) DeepCopy() *Secret {
method DeepCopyInto (line 338) | func (in *SecretNotFound) DeepCopyInto(out *SecretNotFound) {
method DeepCopy (line 344) | func (in *SecretNotFound) DeepCopy() *SecretNotFound {
method DeepCopyInto (line 354) | func (in *SecretRef) DeepCopyInto(out *SecretRef) {
method DeepCopy (line 360) | func (in *SecretRef) DeepCopy() *SecretRef {
method DeepCopyInto (line 370) | func (in *SecretSource) DeepCopyInto(out *SecretSource) {
method DeepCopy (line 391) | func (in *SecretSource) DeepCopy() *SecretSource {
method DeepCopyInto (line 401) | func (in *Status) DeepCopyInto(out *Status) {
method DeepCopy (line 419) | func (in *Status) DeepCopy() *Status {
FILE: pkg/kfupgrade/kfupgrade.go
type KfUpgrader (line 45) | type KfUpgrader struct
method Generate (line 259) | func (upgrader *KfUpgrader) Generate() error {
method Apply (line 269) | func (upgrader *KfUpgrader) Apply() error {
method Dump (line 297) | func (upgrader *KfUpgrader) Dump() error {
method DeleteObsoleteResources (line 307) | func (upgrader *KfUpgrader) DeleteObsoleteResources(ns string) error {
method DeleteResources (line 330) | func (upgrader *KfUpgrader) DeleteResources(ns string, obj runtime.Obj...
function createNewKfApp (line 54) | func createNewKfApp(baseConfig string, version string, oldKfCfg *kfconfi...
function NewKfUpgrade (line 111) | func NewKfUpgrade(upgradeConfig string) (*KfUpgrader, error) {
function computeHash (line 158) | func computeHash(d *kfconfig.KfConfig) (string, error) {
function findKfCfg (line 169) | func findKfCfg(kfDefRef *kfupgrade.KfDefRef) (*kfconfig.KfConfig, string...
function MergeKfCfg (line 218) | func MergeKfCfg(oldKfCfg *kfconfig.KfConfig, newKfCfg *kfconfig.KfConfig) {
FILE: pkg/kfupgrade/kfupgrade_test.go
function Test_MergeKfCfg (line 10) | func Test_MergeKfCfg(t *testing.T) {
FILE: pkg/mirror/mirror_image.go
constant INPUT_IMAGE (line 23) | INPUT_IMAGE = "inputImage"
constant OUTPUT_IMAGE (line 24) | OUTPUT_IMAGE = "outputImage"
constant CONTEXT (line 25) | CONTEXT = "context"
constant TASK_NAME (line 26) | TASK_NAME = "mirror-image"
constant KUSTOMIZE_FOLDER (line 27) | KUSTOMIZE_FOLDER = "kustomize"
constant CLOUD_BUILD_IMAGE (line 28) | CLOUD_BUILD_IMAGE = "gcr.io/cloud-builders/docker"
constant CLOUD_BUILD_FILE (line 29) | CLOUD_BUILD_FILE = "cloudbuild.yaml"
type ReplicateTasks (line 31) | type ReplicateTasks
method orderedKeys (line 148) | func (rt *ReplicateTasks) orderedKeys() []string {
method processKustomizeDir (line 158) | func (rt *ReplicateTasks) processKustomizeDir(absPath string, registry...
method fillTasks (line 246) | func (rt *ReplicateTasks) fillTasks(directory string, registry string,...
function GenerateMirroringPipeline (line 34) | func GenerateMirroringPipeline(directory string, spec mirrorv1alpha1.Rep...
function generateCloudBuild (line 122) | func generateCloudBuild(rt ReplicateTasks) error {
function verifyCurrDir (line 261) | func verifyCurrDir() error {
function UpdateKustomize (line 279) | func UpdateKustomize(inputFile string) error {
FILE: pkg/mirror/mirror_image_test.go
constant KUSTOMIZATION (line 14) | KUSTOMIZATION = "kustomize/kustomization.yaml"
type testCase (line 16) | type testCase struct
function init (line 21) | func init() {
function TestGenerateMirroringPipeline (line 27) | func TestGenerateMirroringPipeline(t *testing.T) {
function TestUpdateKustomize (line 69) | func TestUpdateKustomize(t *testing.T) {
function compFile (line 93) | func compFile(cases []testCase, t *testing.T) {
FILE: pkg/utils/awsutil.go
function CheckAwsStsCallerIdentity (line 32) | func CheckAwsStsCallerIdentity(sess *session.Session) error {
function CheckAwsAccountId (line 47) | func CheckAwsAccountId(sess *session.Session) (string, error) {
function CheckCommandExist (line 61) | func CheckCommandExist(commandName string) error {
function GetEksctlVersion (line 71) | func GetEksctlVersion() (string, error) {
FILE: pkg/utils/diff.go
function PrintDiff (line 12) | func PrintDiff(actual string, expected string) {
function tabToSpace (line 38) | func tabToSpace(input string) string {
function convertToArray (line 50) | func convertToArray(x string) ([]string, int) {
function hint (line 63) | func hint(a, b string) string {
FILE: pkg/utils/gcputils.go
function GetClusterInfo (line 35) | func GetClusterInfo(ctx context.Context, project string, loc string, clu...
function BuildConfigFromClusterInfo (line 60) | func BuildConfigFromClusterInfo(ctx context.Context, cluster *containerp...
function CreateKubeconfig (line 80) | func CreateKubeconfig(ctx context.Context, project string, loc string, c...
FILE: pkg/utils/iamutils.go
function transformSliceToInterface (line 32) | func transformSliceToInterface(slice []string) []interface{} {
function transformInterfaceToSlice (line 40) | func transformInterfaceToSlice(inter []interface{}) []string {
function GetIamPolicy (line 49) | func GetIamPolicy(project string, gcpClient *http.Client) (*cloudresourc...
function ClearIamPolicy (line 70) | func ClearIamPolicy(currentPolicy *cloudresourcemanager.Policy, deployNa...
type Members (line 94) | type Members
type Roles (line 95) | type Roles
type Bindings (line 97) | type Bindings struct
type IamBindingsYAML (line 102) | type IamBindingsYAML struct
function ReadIamBindingsYAML (line 107) | func ReadIamBindingsYAML(filename string) (*cloudresourcemanager.Policy,...
function RewriteIamPolicy (line 148) | func RewriteIamPolicy(currentPolicy *cloudresourcemanager.Policy, adding...
function SetIamPolicy (line 180) | func SetIamPolicy(project string, policy *cloudresourcemanager.Policy, g...
function UpdateWorkloadIdentityBindingsPolicy (line 205) | func UpdateWorkloadIdentityBindingsPolicy(currentPolicy *iam.Policy, pro...
function GetServiceAccountIamPolicy (line 217) | func GetServiceAccountIamPolicy(iamService *iam.Service, project string,...
function SetServiceAccountIamPolicy (line 231) | func SetServiceAccountIamPolicy(iamService *iam.Service, policy *iam.Pol...
FILE: pkg/utils/iamutils_test.go
function Test (line 26) | func Test(t *testing.T) {
function Test_UpdateWorkloadIdentity (line 88) | func Test_UpdateWorkloadIdentity(t *testing.T) {
function PolicyToString (line 124) | func PolicyToString(input *cloudresourcemanager.Policy) string {
function IamPolicyToString (line 132) | func IamPolicyToString(input *iam.Policy) string {
FILE: pkg/utils/k8sAuth.go
function BuildClusterConfig (line 17) | func BuildClusterConfig(ctx context.Context, token string, project strin...
function BuildClientCmdAPI (line 46) | func BuildClientCmdAPI(config *rest.Config, token string) *clientcmdapi....
function CreateK8sRoleBing (line 71) | func CreateK8sRoleBing(config *rest.Config, roleBinding *v1.ClusterRoleB...
FILE: pkg/utils/k8utils.go
constant YamlSeparator (line 61) | YamlSeparator = "(?m)^---[ \t]*$"
constant CertDir (line 62) | CertDir = "/opt/ca"
constant controlPlaneLabel (line 63) | controlPlaneLabel = "control-plane"
constant katibMetricsCollectorLabel (line 64) | katibMetricsCollectorLabel = "katib-metricscollector-injection"
constant KfDefAnnotation (line 65) | KfDefAnnotation = "kfctl.kubeflow.io"
constant ForceDelete (line 66) | ForceDelete = "force-delete"
constant SetAnnotation (line 67) | SetAnnotation = "set-kubeflow-annotation"
constant KfDefInstance (line 68) | KfDefInstance = "kfdef-instance"
constant InstallByOperator (line 69) | InstallByOperator = "install-by-operator"
function generateRandStr (line 72) | func generateRandStr(length int) string {
function NewDefaultBackoff (line 81) | func NewDefaultBackoff() *backoff.ExponentialBackOff {
function CreateResourceFromFile (line 89) | func CreateResourceFromFile(config *rest.Config, filename string, elems ...
function IsRemoteFile (line 144) | func IsRemoteFile(configFile string) (bool, error) {
function GetObjectKindFromUri (line 161) | func GetObjectKindFromUri(configFile string) (string, error) {
function DeleteResourceFromFile (line 212) | func DeleteResourceFromFile(config *rest.Config, filename string) error {
type Apply (line 255) | type Apply struct
method IfNamespaceExist (line 300) | func (a *Apply) IfNamespaceExist(name string) bool {
method Apply (line 308) | func (a *Apply) Apply(data []byte) error {
method run (line 338) | func (a *Apply) run() error {
method cleanup (line 349) | func (a *Apply) cleanup() error {
method init (line 360) | func (a *Apply) init() error {
method patchNamespaceWithLabel (line 409) | func (a *Apply) patchNamespaceWithLabel(namespace string, labelKey str...
method namespace (line 432) | func (a *Apply) namespace(namespace string) error {
method tempFile (line 484) | func (a *Apply) tempFile(data []byte) *os.File {
method deleteFlags (line 498) | func (a *Apply) deleteFlags(usage string) *kubectldelete.DeleteFlags {
function NewApply (line 264) | func NewApply(namespace string, restConfig *rest.Config) (*Apply, error) {
function DeleteResource (line 532) | func DeleteResource(resourceBytes []byte, kubeclient client.Client, time...
function SplitYAML (line 597) | func SplitYAML(resources []byte) ([][]byte, error) {
FILE: pkg/utils/k8utils_test.go
function Test_IsRemoteFile (line 7) | func Test_IsRemoteFile(t *testing.T) {
function TestSplitYAML (line 43) | func TestSplitYAML(t *testing.T) {
FILE: pkg/utils/kindsorter.go
type SortOrder (line 9) | type SortOrder
function SortByKind (line 81) | func SortByKind(manifests []*resource.Resource, ordering SortOrder) []*r...
type kindSorter (line 87) | type kindSorter struct
method Len (line 104) | func (k *kindSorter) Len() int { return len(k.resources) }
method Swap (line 106) | func (k *kindSorter) Swap(i, j int) { k.resources[i], k.resources[j] =...
method Less (line 108) | func (k *kindSorter) Less(i, j int) bool {
function newKindSorter (line 92) | func newKindSorter(r []*resource.Resource, s SortOrder) *kindSorter {
FILE: pkg/utils/logging.go
function PrettyPrint (line 10) | func PrettyPrint(value interface{}) string {
FILE: py/kubeflow/kfctl/testing/ci/kfctl_e2e_workflow.py
class Builder (line 69) | class Builder(object):
method __init__ (line 70) | def __init__(self, name=None, namespace="kubeflow-test-infra",
method _build_workflow (line 216) | def _build_workflow(self):
method _build_task_template (line 262) | def _build_task_template(self):
method _build_step (line 329) | def _build_step(self, name, workflow, dag_name, task_template,
method _build_tests_dag (line 340) | def _build_tests_dag(self, dependences):
method _build_exit_dag (line 382) | def _build_exit_dag(self):
method build (line 434) | def build(self):
function create_workflow (line 673) | def create_workflow(**kwargs): # pylint: disable=too-many-statements
FILE: py/kubeflow/kfctl/testing/ci/kfctl_go_build_test.py
function test_build_kfctl_go (line 8) | def test_build_kfctl_go(record_xml_attribute):
FILE: py/kubeflow/kfctl/testing/ci/kfctl_go_deploy_test.py
function test_deploy_kfctl_go (line 9) | def test_deploy_kfctl_go(record_xml_attribute, app_path, project,
FILE: py/kubeflow/kfctl/testing/ci/kfctl_upgrade_e2e_workflow.py
class Builder (line 47) | class Builder(kfctl_e2e_workflow.Builder):
method __init__ (line 48) | def __init__(self,
method _build_upgrade_dag (line 56) | def _build_upgrade_dag(self):
method build (line 91) | def build(self):
function create_workflow (line 157) | def create_workflow(**kwargs): # pylint: disable=too-many-statements
FILE: py/kubeflow/kfctl/testing/ci/update_jupyter_web_app.py
class WebAppUpdater (line 31) | class WebAppUpdater(object): # pylint: disable=useless-object-inheritance
method __init__ (line 32) | def __init__(self):
method build_image (line 36) | def build_image(self, build_project, registry_project):
method last_commit (line 66) | def last_commit(self):
method _find_remote_repo (line 78) | def _find_remote_repo(self, repo, remote_url): # pylint: disable=no-se...
method all (line 97) | def all(self, build_project, registry_project, remote_fork, # pylint: ...
method _pr_title (line 209) | def _pr_title(self, commit):
method _check_if_pr_exists (line 214) | def _check_if_pr_exists(self, commit=None):
method create_pull_request (line 254) | def create_pull_request(self, base="kubeflow:master", commit=None):
method _root_dir (line 278) | def _root_dir(self):
method _component_dir (line 282) | def _component_dir(self):
FILE: py/kubeflow/kfctl/testing/pytests/conftest.py
function pytest_addoption (line 3) | def pytest_addoption(parser):
function app_path (line 81) | def app_path(request):
function app_name (line 85) | def app_name(request):
function kfctl_path (line 89) | def kfctl_path(request):
function kfctl_repo_path (line 93) | def kfctl_repo_path(request):
function namespace (line 97) | def namespace(request):
function project (line 101) | def project(request):
function config_path (line 105) | def config_path(request):
function values (line 109) | def values(request):
function eks_cluster_version (line 113) | def eks_cluster_version(request):
function cluster_creation_script (line 117) | def cluster_creation_script(request):
function cluster_deletion_script (line 121) | def cluster_deletion_script(request):
function cluster_name (line 125) | def cluster_name(request):
function build_and_apply (line 129) | def build_and_apply(request):
function use_basic_auth (line 139) | def use_basic_auth(request):
function use_istio (line 148) | def use_istio(request):
function self_signed_cert (line 157) | def self_signed_cert(request):
function upgrade_spec_path (line 165) | def upgrade_spec_path(request):
FILE: py/kubeflow/kfctl/testing/pytests/endpoint_ready_test.py
function test_endpoint_is_ready (line 14) | def test_endpoint_is_ready(record_xml_attribute, project, app_path, app_...
FILE: py/kubeflow/kfctl/testing/pytests/jupyter_test.py
function test_jupyter (line 26) | def test_jupyter(record_xml_attribute, kfctl_repo_path, namespace, clust...
FILE: py/kubeflow/kfctl/testing/pytests/kf_is_ready_test.py
function set_logging (line 12) | def set_logging():
function get_platform_app_name (line 21) | def get_platform_app_name(app_path):
function check_deployments_ready (line 47) | def check_deployments_ready(record_xml_attribute, namespace, name, deplo...
function test_admission_is_ready (line 65) | def test_admission_is_ready(record_xml_attribute, namespace, cluster_name):
function test_katib_is_ready (line 74) | def test_katib_is_ready(record_xml_attribute, namespace, cluster_name):
function test_metadata_is_ready (line 86) | def test_metadata_is_ready(record_xml_attribute, namespace, cluster_name):
function test_pipeline_is_ready (line 98) | def test_pipeline_is_ready(record_xml_attribute, namespace, cluster_name):
function test_notebook_is_ready (line 118) | def test_notebook_is_ready(record_xml_attribute, namespace, cluster_name):
function test_centraldashboard_is_ready (line 128) | def test_centraldashboard_is_ready(record_xml_attribute, namespace, clus...
function test_profiles_is_ready (line 134) | def test_profiles_is_ready(record_xml_attribute, namespace, cluster_name):
function test_seldon_is_ready (line 140) | def test_seldon_is_ready(record_xml_attribute, namespace, cluster_name):
function test_spark_is_ready (line 149) | def test_spark_is_ready(record_xml_attribute, namespace, cluster_name):
function test_training_operators_are_ready (line 158) | def test_training_operators_are_ready(record_xml_attribute, namespace, c...
function test_workflow_controller_is_ready (line 171) | def test_workflow_controller_is_ready(record_xml_attribute, namespace, c...
function test_kf_is_ready (line 177) | def test_kf_is_ready(record_xml_attribute, namespace, use_basic_auth,
FILE: py/kubeflow/kfctl/testing/pytests/kfam_test.py
function test_kfam (line 13) | def test_kfam(record_xml_attribute, cluster_name):
function verify_profile_creation (line 34) | def verify_profile_creation(jupyterpod, profile_name):
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_create_cluster_test.py
function test_create_cluster (line 7) | def test_create_cluster(record_xml_attribute, cluster_name, eks_cluster_...
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_delete_cluster_test.py
function test_kfctl_delete (line 11) | def test_kfctl_delete(record_xml_attribute, cluster_deletion_script,
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_delete_test.py
function test_kfctl_delete (line 17) | def test_kfctl_delete(record_xml_attribute, kfctl_path, app_path,
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_delete_wrong_cluster.py
function test_kfctl_delete_wrong_cluster (line 16) | def test_kfctl_delete_wrong_cluster(record_xml_attribute, kfctl_path, ap...
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_deploy_kubeflow_test.py
function test_build_kfctl_go (line 9) | def test_build_kfctl_go(record_xml_attribute, app_path, project, use_bas...
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_go_test.py
function test_build_kfctl_go (line 8) | def test_build_kfctl_go(record_xml_attribute, config_path, kfctl_repo_pa...
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_second_apply.py
function test_second_apply (line 10) | def test_second_apply(record_xml_attribute, app_path, kfctl_path):
FILE: py/kubeflow/kfctl/testing/pytests/kfctl_upgrade_test.py
function test_upgrade_kubeflow (line 10) | def test_upgrade_kubeflow(record_xml_attribute, app_path, kfctl_path, up...
FILE: py/kubeflow/kfctl/testing/pytests/pytorch_job_deploy.py
function test_deploy_pytorchjob (line 13) | def test_deploy_pytorchjob(kfctl_repo_path, namespace, cluster_name):
FILE: py/kubeflow/kfctl/testing/test_deploy.py
function _setup_test (line 55) | def _setup_test(api_client, run_label):
function create_k8s_client (line 84) | def create_k8s_client(_):
function setup_kubeflow_ks_app (line 97) | def setup_kubeflow_ks_app(args, api_client):
function deploy_model (line 180) | def deploy_model(args):
function test_successful_deployment (line 234) | def test_successful_deployment(deployment_name):
function test_katib (line 268) | def test_katib(args):
function deploy_argo (line 275) | def deploy_argo(args):
function deploy_pytorchjob (line 309) | def deploy_pytorchjob(args):
function teardown (line 328) | def teardown(args):
function determine_test_name (line 336) | def determine_test_name(args):
function wrap_test (line 344) | def wrap_test(args):
function ks_deploy (line 371) | def ks_deploy(app_dir,
function modify_minikube_config (line 420) | def modify_minikube_config(config_path, certs_dir):
function deploy_minikube (line 447) | def deploy_minikube(args):
function teardown_minikube (line 557) | def teardown_minikube(args):
function get_gcp_identity (line 618) | def get_gcp_identity():
function main (line 624) | def main(): # pylint: disable=too-many-locals,too-many-statements
FILE: py/kubeflow/kfctl/testing/test_deploy_test.py
class TestDeploy (line 9) | class TestDeploy(unittest.TestCase):
method testModifyMinikubeConfig (line 11) | def testModifyMinikubeConfig(self):
FILE: py/kubeflow/kfctl/testing/util/application_util.py
function set_kustomize_image (line 12) | def set_kustomize_image(kustomize_file, image_name, image):
function regenerate_manifest_tests (line 47) | def regenerate_manifest_tests(manifests_dir):
FILE: py/kubeflow/kfctl/testing/util/application_util_test.py
class ApplicationUttilTest (line 13) | class ApplicationUttilTest(unittest.TestCase):
method test_set_image (line 14) | def test_set_image(self):
FILE: py/kubeflow/kfctl/testing/util/aws_util.py
function aws_auth_load_kubeconfig (line 7) | def aws_auth_load_kubeconfig(cluster_name):
FILE: py/kubeflow/kfctl/testing/util/deploy_utils.py
function get_gcp_identity (line 25) | def get_gcp_identity():
function create_k8s_client (line 31) | def create_k8s_client():
function _setup_test (line 42) | def _setup_test(api_client, run_label):
function setup_kubeflow_ks_app (line 71) | def setup_kubeflow_ks_app(dir, namespace, github_token, api_client):
function log_operation_status (line 152) | def log_operation_status(operation):
function wait_for_operation (line 159) | def wait_for_operation(client,
FILE: py/kubeflow/kfctl/testing/util/gcp_util.py
function may_get_env_var (line 15) | def may_get_env_var(name):
function make_iap_request (line 25) | def make_iap_request(url, client_id, method='GET', **kwargs):
function iap_is_ready (line 65) | def iap_is_ready(url, wait_min=15):
function _send_req (line 93) | def _send_req(wait_sec, url, req_gen, retry_result_code=None):
function basic_auth_is_ready (line 136) | def basic_auth_is_ready(url, username, password, wait_min=15):
FILE: py/kubeflow/kfctl/testing/util/kfctl_go_test_utils.py
function run_with_retries (line 21) | def run_with_retries(*args, **kwargs):
function build_kfctl_go (line 24) | def build_kfctl_go(kfctl_repo_path):
function get_or_create_app_path_and_parent_dir (line 40) | def get_or_create_app_path_and_parent_dir(app_path):
function load_config (line 60) | def load_config(config_path):
function set_env_for_auth (line 80) | def set_env_for_auth(use_basic_auth):
function set_env_init_args (line 96) | def set_env_init_args(config_spec):
function write_basic_auth_login (line 105) | def write_basic_auth_login(filename):
function filter_spartakus (line 125) | def filter_spartakus(spec):
function get_config_spec (line 140) | def get_config_spec(config_path, app_path, cluster_name):
function kfctl_deploy_kubeflow (line 190) | def kfctl_deploy_kubeflow(app_path, config_path, kfctl_path, build_and_a...
function push_kfctl_to_s3 (line 249) | def push_kfctl_to_s3(kfctl_path):
function apply_kubeflow (line 255) | def apply_kubeflow(kfctl_path, app_path):
function build_and_apply_kubeflow (line 259) | def build_and_apply_kubeflow(kfctl_path, app_path):
function upgrade_kubeflow (line 264) | def upgrade_kubeflow(kfctl_path, parent_dir):
function verify_kubeconfig (line 267) | def verify_kubeconfig(app_path):
function kfctl_upgrade_kubeflow (line 283) | def kfctl_upgrade_kubeflow(app_path, kfctl_path, upgrade_spec_path, use_...
FILE: py/kubeflow/kfctl/testing/util/run_with_retry.py
function parse_args (line 19) | def parse_args():
function run_with_retry (line 29) | def run_with_retry(_):
function main (line 40) | def main():
FILE: py/kubeflow/kfctl/testing/util/vm_util.py
function wait_for_operation (line 18) | def wait_for_operation(client,
function wait_for_vm (line 68) | def wait_for_vm(project,
function execute (line 103) | def execute(project, zone, vm, commands):
function execute_script (line 111) | def execute_script(project, zone, vm, script):
FILE: third_party/concatenate_license.py
function fetch_license_text (line 41) | def fetch_license_text(download_link):
function main (line 48) | def main():
Condensed preview — 288 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,150K chars).
[
{
"path": ".github/issue_label_bot.yaml",
"chars": 143,
"preview": "# for https://mlbot.net\nlabel-alias:\n bug: 'kind/bug'\n feature_request: 'kind/feature'\n feature: 'kind/feature'\n que"
},
{
"path": ".github/workflows/kfctl_go_unittests.yaml",
"chars": 242,
"preview": "name: Unit Test\n\non:\n - push\n - pull_request\n\njobs:\n build:\n name: Test\n runs-on: ubuntu-latest\n\n steps:\n "
},
{
"path": ".github/workflows/triage_issues.yaml",
"chars": 730,
"preview": "# Define a GitHub action workflow to determine whether issues \n# should be added or removed from the Needs Triage Kanban"
},
{
"path": ".gitignore",
"chars": 909,
"preview": "# pkg and bin directories currently contain build artifacts\n# only so we exclude them.\nbin/\nvendor/\n\n.vscode/\n\n# Compile"
},
{
"path": "Dockerfile",
"chars": 2266,
"preview": "#**********************************************************************\n# Builder\n# Create a go runtime suitable for bui"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 12796,
"preview": "# Copyright 2017 The Kubernetes Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may n"
},
{
"path": "OWNERS",
"chars": 154,
"preview": "approvers:\n - adrian555\n - animeshsingh\n - crobby\n - Jeffwan\n - PatrickXYS\n - vpavlin\n - yanniszark\nreviewers:\n "
},
{
"path": "README.md",
"chars": 668,
"preview": "# kfctl\n\n_kfctl_ is the control plane for deploying and managing Kubeflow. The primary mode of deployment is to use [kfc"
},
{
"path": "build/Dockerfile",
"chars": 686,
"preview": "ARG binary_name=kfctl\nFROM registry.access.redhat.com/ubi8/ubi-minimal:latest AS build\n\nENV OPERATOR=/usr/local/bin/${bi"
},
{
"path": "build/Dockerfile.ubi",
"chars": 332,
"preview": "ARG binary_name=kfctl\nFROM registry.access.redhat.com/ubi8/ubi-minimal:latest\nENV OPERATOR=/usr/local/bin/${binary_name}"
},
{
"path": "cmd/kfctl/.gitignore",
"chars": 357,
"preview": "\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\nbin\n\n# Test binary, build with `go test -c`\n*.test\n"
},
{
"path": "cmd/kfctl/OWNERS",
"chars": 32,
"preview": "approvers:\n- jlewi\n- yanniszark\n"
},
{
"path": "cmd/kfctl/README.md",
"chars": 9838,
"preview": "<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD "
},
{
"path": "cmd/kfctl/cmd/alpha.go",
"chars": 322,
"preview": "package cmd\n\nimport (\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\nvar alphaCfg = viper.New()\n\n// alphaCmd rep"
},
{
"path": "cmd/kfctl/cmd/apply.go",
"chars": 4394,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/build.go",
"chars": 3480,
"preview": "// Copyright © 2019 NAME HERE <EMAIL ADDRESS>\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// y"
},
{
"path": "cmd/kfctl/cmd/completion.go",
"chars": 1454,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/delete.go",
"chars": 3924,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/generate.go",
"chars": 1352,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/init.go",
"chars": 1351,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/mirror.go",
"chars": 268,
"preview": "package cmd\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\n// alphaCmd represents the commands that are in alpha\nvar mirrorCmd ="
},
{
"path": "cmd/kfctl/cmd/mirror_build.go",
"chars": 2856,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\tkftypes \"github.com/kubeflow/kfctl/v3/pkg/apis/apps\"\n\tmirrortypes \"github.com/kubeflow/kfc"
},
{
"path": "cmd/kfctl/cmd/mirror_overwrite.go",
"chars": 1477,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\tkftypes \"github.com/kubeflow/kfctl/v3/pkg/apis/apps\"\n\t\"github.com/kubeflow/kfctl/v3/pkg/mi"
},
{
"path": "cmd/kfctl/cmd/root.go",
"chars": 2027,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/set-image-name.go",
"chars": 5735,
"preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sigs.k8s.io/kustomize/v3/pkg/image\"\n\t\"strings\"\n\n"
},
{
"path": "cmd/kfctl/cmd/set-image-name_test.go",
"chars": 6556,
"preview": "package cmd\n\nimport (\n\t\"reflect\"\n\t\"sigs.k8s.io/kustomize/v3/pkg/image\"\n\t\"testing\"\n)\n\nfunc Test_imageToString(t *testing."
},
{
"path": "cmd/kfctl/cmd/show.go",
"chars": 2197,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/cmd/version.go",
"chars": 1507,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/kfctl/main.go",
"chars": 1020,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "cmd/manager/main.go",
"chars": 5623,
"preview": "package main\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\n\t// Import all Kubernetes client auth plugins (e.g. A"
},
{
"path": "cmd/plugins/dockerfordesktop/dockerfordesktop.go",
"chars": 305,
"preview": "package main\n\nimport (\n\tkftypes \"github.com/kubeflow/kfctl/v3/pkg/apis/apps\"\n\tcltypes \"github.com/kubeflow/kfctl/v3/pkg/"
},
{
"path": "config/doc.go",
"chars": 693,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "config/types.go",
"chars": 1660,
"preview": "/*\nCopyright The Kubeflow Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this"
},
{
"path": "config/zz_generated.deepcopy.go",
"chars": 3308,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "deploy/cluster_role_binding.yaml",
"chars": 315,
"preview": "kind: ClusterRoleBinding\napiVersion: rbac.authorization.k8s.io/v1\nmetadata:\n name: kubeflow-operator\nsubjects:\n- kind: "
},
{
"path": "deploy/crds/kfdef.apps.kubeflow.org_kfdefs_crd.yaml",
"chars": 1484,
"preview": "apiVersion: apiextensions.k8s.io/v1beta1\nkind: CustomResourceDefinition\nmetadata:\n name: kfdefs.kfdef.apps.kubeflow.org"
},
{
"path": "deploy/crds/kustomization.yaml",
"chars": 53,
"preview": "resources:\n- kfdef.apps.kubeflow.org_kfdefs_crd.yaml\n"
},
{
"path": "deploy/kustomization.yaml",
"chars": 378,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n- ./crds\n- ./service_account.yaml\n- ./role.ya"
},
{
"path": "deploy/olm-catalog/kubeflow/0.1.0/kfdef.apps.kubeflow.org.crd.yaml",
"chars": 1527,
"preview": "apiVersion: apiextensions.k8s.io/v1beta1\nkind: CustomResourceDefinition\nmetadata:\n name: kfdefs.kfdef.apps.kubeflow.org"
},
{
"path": "deploy/olm-catalog/kubeflow/0.1.0/kubeflow.v0.1.0.clusterserviceversion.yaml",
"chars": 102481,
"preview": "apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n annotations:\n alm-examples: '[{\"api"
},
{
"path": "deploy/olm-catalog/kubeflow/1.0.0/kfdef.apps.kubeflow.org.crd.yaml",
"chars": 1527,
"preview": "apiVersion: apiextensions.k8s.io/v1beta1\nkind: CustomResourceDefinition\nmetadata:\n name: kfdefs.kfdef.apps.kubeflow.org"
},
{
"path": "deploy/olm-catalog/kubeflow/1.0.0/kubeflow.v1.0.0.clusterserviceversion.yaml",
"chars": 103739,
"preview": "apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n annotations:\n alm-examples: '[{\"api"
},
{
"path": "deploy/olm-catalog/kubeflow/1.1.0/kfdef.apps.kubeflow.org.crd.yaml",
"chars": 1527,
"preview": "apiVersion: apiextensions.k8s.io/v1beta1\nkind: CustomResourceDefinition\nmetadata:\n name: kfdefs.kfdef.apps.kubeflow.org"
},
{
"path": "deploy/olm-catalog/kubeflow/1.1.0/kubeflow.v1.1.0.clusterserviceversion.yaml",
"chars": 101593,
"preview": "apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n annotations:\n alm-examples: >-\n "
},
{
"path": "deploy/olm-catalog/kubeflow/1.2.0/kfdef.apps.kubeflow.org.crd.yaml",
"chars": 1527,
"preview": "apiVersion: apiextensions.k8s.io/v1beta1\nkind: CustomResourceDefinition\nmetadata:\n name: kfdefs.kfdef.apps.kubeflow.org"
},
{
"path": "deploy/olm-catalog/kubeflow/1.2.0/kubeflow.v1.2.0.clusterserviceversion.yaml",
"chars": 101363,
"preview": "apiVersion: operators.coreos.com/v1alpha1\nkind: ClusterServiceVersion\nmetadata:\n annotations:\n alm-examples: >-\n "
},
{
"path": "deploy/olm-catalog/kubeflow/kubeflow.package.yaml",
"chars": 98,
"preview": "channels:\n- currentCSV: kubeflow.v1.2.0\n name: alpha\ndefaultChannel: alpha\npackageName: kubeflow\n"
},
{
"path": "deploy/operator.yaml",
"chars": 906,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: kubeflow-operator\nspec:\n replicas: 1\n selector:\n matchLabels"
},
{
"path": "deploy/params.yaml",
"chars": 109,
"preview": "varReference:\n- path: subjects/namespace\n kind: ClusterRoleBinding\n apiGroup: rbac.authorization.k8s.io/v1\n"
},
{
"path": "deploy/role.yaml",
"chars": 359,
"preview": "apiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n annotations:\n rbac.authorization.kubernetes.io"
},
{
"path": "deploy/service_account.yaml",
"chars": 72,
"preview": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: kubeflow-operator\n"
},
{
"path": "go.mod",
"chars": 5383,
"preview": "module github.com/kubeflow/kfctl/v3\n\nrequire (\n\tcloud.google.com/go v0.57.0\n\tgithub.com/Azure/go-autorest v13.3.3+incomp"
},
{
"path": "go.sum",
"chars": 142344,
"preview": "bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeN"
},
{
"path": "hack/boilerplate.go.txt",
"chars": 566,
"preview": " \n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use "
},
{
"path": "hack/cp_update.sh",
"chars": 1293,
"preview": "#!/usr/bin/env bash\n\n#\n# this copies kubeflow/bootstrap/{go.*,cmd/kfctl,pkg} to here and updates all references \n# githu"
},
{
"path": "kustomization.yaml",
"chars": 227,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n- kustomize/base\n# only enable this if the k8"
},
{
"path": "kustomize/base/kustomization.yaml",
"chars": 21,
"preview": "bases:\n- ../../deploy"
},
{
"path": "kustomize/include/quota/kfdef_quota.yaml",
"chars": 125,
"preview": "apiVersion: v1\nkind: ResourceQuota\nmetadata:\n name: kfdef-quota\nspec:\n hard:\n count/kfdefs.kfdef.apps.kubeflow.org:"
},
{
"path": "kustomize/include/quota/kustomization.yaml",
"chars": 30,
"preview": "resources:\n- kfdef_quota.yaml\n"
},
{
"path": "operator.md",
"chars": 12504,
"preview": "# Kubeflow Operator\n\nKubeflow Operator helps deploy, monitor and manage the lifecycle of Kubeflow. Built using the [Oper"
},
{
"path": "pkg/apis/apis.go",
"chars": 1087,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/addtoscheme_kfdef_v1.go",
"chars": 270,
"preview": "package apps\n\nimport (\n\tv1 \"github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1\"\n)\n\nfunc init() {\n\t// Register the types"
},
{
"path": "pkg/apis/apps/apis.go",
"chars": 1087,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/group.go",
"chars": 12384,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/group_test.go",
"chars": 719,
"preview": "package apps\n\nimport (\n\t\"testing\"\n)\n\nfunc TestEmailToDefaultName(t *testing.T) {\n\n\ttestCases := [][]string{\n\t\t[]string{\n"
},
{
"path": "pkg/apis/apps/imagemirror/v1alpha1/replication_types.go",
"chars": 1293,
"preview": "// Copyright 2020 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfconfig/doc.go",
"chars": 904,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfconfig/register.go",
"chars": 2094,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfconfig/types.go",
"chars": 20132,
"preview": "package kfconfig\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/ghodss/yaml\"\n\tgogetter \"github.com"
},
{
"path": "pkg/apis/apps/kfconfig/zz_generated.deepcopy.go",
"chars": 11369,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/kfdef/kfdef.go",
"chars": 658,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/testdata/doc.go",
"chars": 18,
"preview": "package testdata\n\n"
},
{
"path": "pkg/apis/apps/kfdef/v1/README.md",
"chars": 1806,
"preview": "## `KfDef` defines an interface for controlling Kubeflow resources\n\nIn the following sections we explain what fields in "
},
{
"path": "pkg/apis/apps/kfdef/v1/application_types.go",
"chars": 8821,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1/application_types_test.go",
"chars": 6847,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1/doc.go",
"chars": 887,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1/register.go",
"chars": 2084,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1/testdata/doc.go",
"chars": 17,
"preview": "package testdata\n"
},
{
"path": "pkg/apis/apps/kfdef/v1/testdata/kfctl_plugin_test.yaml",
"chars": 192,
"preview": "apiVersion: kfdef.apps.kubeflow.org/v1\nkind: KfDef\nspec:\n applications:\n - name: delete\n - name: keep\n plugins:\n - "
},
{
"path": "pkg/apis/apps/kfdef/v1/zz_generated.deepcopy.go",
"chars": 10922,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/application_types.go",
"chars": 25574,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/application_types_test.go",
"chars": 16817,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/doc.go",
"chars": 905,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/register.go",
"chars": 2108,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/testdata/doc.go",
"chars": 18,
"preview": "package testdata\n\n"
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/testdata/kfctl_plugin_test.yaml",
"chars": 158,
"preview": "apiVersion: kfdef.apps.kubeflow.org/v1alpha1\nkind: KfDef\nspec:\n plugins:\n - name: fakeplugin\n spec:\n par"
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/v1alpha1_suite_test.go",
"chars": 1471,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1alpha1/zz_generated.deepcopy.go",
"chars": 19043,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/README.md",
"chars": 1806,
"preview": "## `KfDef` defines an interface for controlling Kubeflow resources\n\nIn the following sections we explain what fields in "
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/application_types.go",
"chars": 8826,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/application_types_test.go",
"chars": 6852,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/doc.go",
"chars": 902,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/register.go",
"chars": 2106,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/testdata/doc.go",
"chars": 17,
"preview": "package testdata\n"
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/testdata/kfctl_plugin_test.yaml",
"chars": 197,
"preview": "apiVersion: kfdef.apps.kubeflow.org/v1beta1\nkind: KfDef\nspec:\n applications:\n - name: delete\n - name: keep\n plugins:"
},
{
"path": "pkg/apis/apps/kfdef/v1beta1/zz_generated.deepcopy.go",
"chars": 10927,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/kfupgrade/kfupgrade.go",
"chars": 670,
"preview": "// Copyright 2019 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfupgrade/v1alpha1/application_types.go",
"chars": 5600,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfupgrade/v1alpha1/doc.go",
"chars": 917,
"preview": "// Copyright 2019 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfupgrade/v1alpha1/register.go",
"chars": 2125,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/kfupgrade/v1alpha1/zz_generated.deepcopy.go",
"chars": 4755,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/plugins/aws/aws.go",
"chars": 610,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/plugins/aws/v1alpha1/doc.go",
"chars": 903,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/plugins/aws/v1alpha1/register.go",
"chars": 2103,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/plugins/aws/v1alpha1/types.go",
"chars": 3994,
"preview": "package v1alpha1\n\nimport (\n\tkfdeftypes \"github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1\"\n\tmetav1 \"k8s.io/apimac"
},
{
"path": "pkg/apis/apps/plugins/aws/v1alpha1/zz_generated.deepcopy.go",
"chars": 4300,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/plugins/gcp/gcp.go",
"chars": 610,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/plugins/gcp/v1alpha1/doc.go",
"chars": 903,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/plugins/gcp/v1alpha1/register.go",
"chars": 2103,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/apps/plugins/gcp/v1alpha1/types.go",
"chars": 3842,
"preview": "package v1alpha1\n\nimport (\n\t\"fmt\"\n\tkfdeftypes \"github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1\"\n\tmetav1 \"k8s.io"
},
{
"path": "pkg/apis/apps/plugins/gcp/v1alpha1/types_test.go",
"chars": 2407,
"preview": "package v1alpha1\n\nimport (\n\tkfdeftypes \"github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1\"\n\tkfutils \"github.com/k"
},
{
"path": "pkg/apis/apps/plugins/gcp/v1alpha1/zz_generated.deepcopy.go",
"chars": 4926,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/apis/apps/plugins/plugins.go",
"chars": 614,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/apis/kferrors.go",
"chars": 2011,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/controller/controller.go",
"chars": 261,
"preview": "package controller\n\nimport (\n\t\"sigs.k8s.io/controller-runtime/pkg/manager\"\n\n\t\"github.com/kubeflow/kfctl/v3/pkg/controlle"
},
{
"path": "pkg/controller/kfdef/const.go",
"chars": 2162,
"preview": "package kfdef\n\nimport (\n\t\"k8s.io/apimachinery/pkg/runtime/schema\"\n)\n\nconst (\n\t// KubeflowLabel represents Label for kfct"
},
{
"path": "pkg/controller/kfdef/kfdef_controller.go",
"chars": 15676,
"preview": "package kfdef\n\nimport (\n\t\"context\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/ghodss/yaml\"\n\tkftypesv3 \"github.c"
},
{
"path": "pkg/kfapp/aws/OWNERS",
"chars": 38,
"preview": "approvers:\n - jeffwan\n - PatrickXYS\n"
},
{
"path": "pkg/kfapp/aws/aws.go",
"chars": 36117,
"preview": "/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use th"
},
{
"path": "pkg/kfapp/aws/eks.go",
"chars": 4369,
"preview": "package aws\n\nimport (\n\t\"fmt\"\n\tawssdk \"github.com/aws/aws-sdk-go/aws\"\n\t\"github.com/aws/aws-sdk-go/aws/awserr\"\n\t\"github.co"
},
{
"path": "pkg/kfapp/aws/eks_test.go",
"chars": 499,
"preview": "package aws\n\nimport (\n\t\"github.com/golangplus/testing/assert\"\n\t\"testing\"\n)\n\nfunc TestIsEksctlVersionLessThan(t *testing."
},
{
"path": "pkg/kfapp/aws/identity.go",
"chars": 11037,
"preview": "package aws\n\nimport (\n\t\"crypto/sha1\"\n\t\"crypto/tls\"\n\tjson \"encoding/json\"\n\t\"fmt\"\n\tawssdk \"github.com/aws/aws-sdk-go/aws\"\n"
},
{
"path": "pkg/kfapp/aws/k8sClient.go",
"chars": 2569,
"preview": "package aws\n\nimport (\n\tkfapis \"github.com/kubeflow/kfctl/v3/pkg/apis\"\n\t\"github.com/pkg/errors\"\n\tlog \"github.com/sirupsen"
},
{
"path": "pkg/kfapp/coordinator/coordinator.go",
"chars": 21498,
"preview": "/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use th"
},
{
"path": "pkg/kfapp/coordinator/coordinator_test.go",
"chars": 4126,
"preview": "package coordinator\n\nimport (\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"reflect\"\n\t\"testing\"\n\n\tkftypesv3 \"github.com/"
},
{
"path": "pkg/kfapp/coordinator/fake/fake.go",
"chars": 1638,
"preview": "// package fake provides a fake implementation of the coordinator for use in tests\npackage fake\n\nimport (\n\t\"path\"\n\n\tkfty"
},
{
"path": "pkg/kfapp/dockerfordesktop/dockerfordesktop.go",
"chars": 4067,
"preview": "/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use th"
},
{
"path": "pkg/kfapp/existing_arrikto/existing.go",
"chars": 14059,
"preview": "package existing_arrikto\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\tcryptorand \"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"crypto/x"
},
{
"path": "pkg/kfapp/existing_arrikto/existing_test.go",
"chars": 4957,
"preview": "package existing_arrikto\n\nimport (\n\t\"crypto/tls\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta"
},
{
"path": "pkg/kfapp/gcp/fake/fake.go",
"chars": 700,
"preview": "// package fake provides a fake implementation of the GCP Plugin\npackage fake\n\nimport (\n\tkftypes \"github.com/kubeflow/kf"
},
{
"path": "pkg/kfapp/gcp/gcp.go",
"chars": 77420,
"preview": "/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use th"
},
{
"path": "pkg/kfapp/gcp/gcp_test.go",
"chars": 12417,
"preview": "package gcp\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/gogo/protobuf/proto\"\n\tkftypes \"github.com/kubeflow/kfctl/v3/pkg/api"
},
{
"path": "pkg/kfapp/gcp/testdata/doc.go",
"chars": 17,
"preview": "package testdata\n"
},
{
"path": "pkg/kfapp/gcp/testdata/kfctl_gcp.yaml",
"chars": 219,
"preview": "apiVersion: kfdef.apps.kubeflow.org/v1alpha1\nkind: KfDef\nspec:\n plugins:\n - name: gcp\n args:\n auth:\n "
},
{
"path": "pkg/kfapp/kfapp.go",
"chars": 629,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfapp/kfdef.go",
"chars": 629,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfapp/kustomize/kustomize.go",
"chars": 52416,
"preview": "/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use th"
},
{
"path": "pkg/kfapp/kustomize/kustomize_test.go",
"chars": 5930,
"preview": "package kustomize\n\nimport (\n\t\"github.com/ghodss/yaml\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"path/"
},
{
"path": "pkg/kfapp/kustomize/testdata/doc.go",
"chars": 17,
"preview": "package testdata\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/grpc-params.env",
"chars": 80,
"preview": "METADATA_GRPC_SERVICE_HOST=metadata-grpc-service\nMETADATA_GRPC_SERVICE_PORT=8080"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/kustomization.yaml",
"chars": 2014,
"preview": "namePrefix: metadata-\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\ncommonLabels:\n kustomize.componen"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-deployment.yaml",
"chars": 1980,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: deployment\n labels:\n component: server\nspec:\n replicas: 1\n "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-envoy-deployment.yaml",
"chars": 534,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: envoy-deployment\n labels:\n component: envoy\nspec:\n replicas:"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-envoy-service.yaml",
"chars": 207,
"preview": "kind: Service\napiVersion: v1\nmetadata:\n labels:\n app: metadata\n name: envoy-service\nspec:\n selector:\n component"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-service.yaml",
"chars": 438,
"preview": "kind: Service\napiVersion: v1\nmetadata:\n labels:\n app: metadata\n name: service\nspec:\n selector:\n component: serv"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-deployment.yaml",
"chars": 524,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: ui\n labels:\n app: metadata-ui\nspec:\n selector:\n matchLabe"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-role.yaml",
"chars": 323,
"preview": "apiVersion: rbac.authorization.k8s.io/v1beta1\nkind: Role\nmetadata:\n labels:\n app: metadata-ui\n name: ui\nrules:\n- ap"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-rolebinding.yaml",
"chars": 253,
"preview": "apiVersion: rbac.authorization.k8s.io/v1beta1\nkind: RoleBinding\nmetadata:\n labels:\n app: metadata-ui\n name: ui\nrole"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-sa.yaml",
"chars": 57,
"preview": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: ui\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-service.yaml",
"chars": 163,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: ui\n labels:\n app: metadata-ui\nspec:\n ports:\n - port: 80\n targetP"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/params.env",
"chars": 30,
"preview": "uiClusterDomain=cluster.local\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/expected/kustomization.yaml",
"chars": 1045,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nbases:\n- base\ncommonLabels:\n app.kubernetes.io/component: metadata\n app.ku"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/application/application.yaml",
"chars": 1040,
"preview": "apiVersion: app.k8s.io/v1beta1\nkind: Application\nmetadata:\n name: metadata\nspec:\n addOwnerRef: true\n componentKinds:\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/application/kustomization.yaml",
"chars": 203,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nbases:\n- ../../base\ncommonLabels:\n app.kubernetes.io/component: metadata\n "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/kustomization.yaml",
"chars": 747,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\ncommonLabels:\n kustomize.component: metadata\nnamespace:"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-db-deployment.yaml",
"chars": 1132,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: metadata-db\n labels:\n component: db\nspec:\n selector:\n mat"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-db-pvc.yaml",
"chars": 164,
"preview": "apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: metadata-mysql\nspec:\n accessModes:\n - ReadWriteOnce\n r"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-db-service.yaml",
"chars": 205,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: metadata-db\n labels:\n component: db\nspec:\n type: ClusterIP\n ports:\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-deployment.yaml",
"chars": 1723,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: deployment\n labels:\n component: server\nspec:\n replicas: 1\n "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/params.env",
"chars": 69,
"preview": "MYSQL_DATABASE=metadb\nMYSQL_PORT=3306\nMYSQL_ALLOW_EMPTY_PASSWORD=true"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/secrets.env",
"chars": 45,
"preview": "MYSQL_USER_NAME=root\nMYSQL_ROOT_PASSWORD=test"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/kustomization.yaml",
"chars": 322,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\ncommonLabels:\n kustomize.component: metadata\nconfigMapG"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/metadata-deployment.yaml",
"chars": 1693,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: deployment\n labels:\n component: server\nspec:\n replicas: 1\n "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/params.env",
"chars": 94,
"preview": "MYSQL_HOST=external_host\nMYSQL_DATABASE=metadb\nMYSQL_PORT=3306\nMYSQL_ALLOW_EMPTY_PASSWORD=true"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/secrets.env",
"chars": 39,
"preview": "MYSQL_USERNAME=root\nMYSQ_PASSWORD=test\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/README.md",
"chars": 3247,
"preview": "This directory contains configurations and guidelines on setting up metadata services to connect to a [Google CloudSQL]("
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/kustomization.yaml",
"chars": 436,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\ngeneratorOptions:\n # name suffix hash is not propagated"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/metadata-deployment.yaml",
"chars": 3635,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: deployment\n labels:\n component: server\nspec:\n replicas: 1\n "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/params.env",
"chars": 153,
"preview": "MYSQL_HOST=127.0.0.1\nMYSQL_DATABASE=metadb\nMYSQL_PORT=3306\nMYSQL_ALLOW_EMPTY_PASSWORD=true\nMYSQL_INSTANCE=your-project:y"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/ibm-storage-config/kustomization.yaml",
"chars": 145,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nbases:\n- ../../base\nimages:\n - name: mysql\n newTag: "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/kustomization.yaml",
"chars": 185,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nbases:\n- ../../base\nresources:\n- virtual-service.yaml\n- "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/params.yaml",
"chars": 78,
"preview": "varReference:\n- path: spec/http/route/destination/host\n kind: VirtualService\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/virtual-service-metadata-grpc.yaml",
"chars": 411,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: metadata-grpc\nspec:\n gateways:\n - kube"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/virtual-service.yaml",
"chars": 395,
"preview": "apiVersion: networking.istio.io/v1alpha3\nkind: VirtualService\nmetadata:\n name: metadata-ui\nspec:\n gateways:\n - kubefl"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/cluster-role-binding.yaml",
"chars": 292,
"preview": "apiVersion: rbac.authorization.k8s.io/v1beta1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n app: pytorch-operator\n n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/cluster-role.yaml",
"chars": 704,
"preview": "apiVersion: rbac.authorization.k8s.io/v1beta1\nkind: ClusterRole\nmetadata:\n labels:\n app: pytorch-operator\n name: py"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/config-map.yaml",
"chars": 126,
"preview": "apiVersion: v1\ndata:\n controller_config_file.yaml: |-\n {\n\n }\nkind: ConfigMap\nmetadata:\n name: pytorch-operator-c"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/deployment.yaml",
"chars": 968,
"preview": "apiVersion: extensions/v1beta1\nkind: Deployment\nmetadata:\n name: pytorch-operator\nspec:\n replicas: 1\n selector:\n m"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/kustomization.yaml",
"chars": 427,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: kubeflow\nresources:\n- cluster-role-binding.ya"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/params.env",
"chars": 74,
"preview": "pytorchDefaultImage=null\ndeploymentScope=cluster\ndeploymentNamespace=null\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/service-account.yaml",
"chars": 107,
"preview": "apiVersion: v1\nkind: ServiceAccount\nmetadata:\n labels:\n app: pytorch-operator\n name: pytorch-operator\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/service.yaml",
"chars": 347,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n annotations:\n prometheus.io/path: /metrics\n prometheus.io/port: \"8443\"\n "
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/expected/kustomization.yaml",
"chars": 524,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nbases:\n- base\ncommonLabels:\n app.kubernetes.io/component: pytorch\n app.kub"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/overlays/application/application.yaml",
"chars": 419,
"preview": "apiVersion: app.k8s.io/v1beta1\nkind: Application\nmetadata:\n name: pytorch-operator-application\nspec:\n type: pytorch-op"
},
{
"path": "pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/overlays/application/kustomization.yaml",
"chars": 444,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nbases:\n- ../../base\nresources:\n- application.yaml\ncommon"
},
{
"path": "pkg/kfapp/kustomize/testdata/operator/base/kustomization.yaml",
"chars": 116,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\ncommonLabels:\n app: fake\nresources:\n- service.yaml\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/operator/base/service.yaml",
"chars": 155,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: fake-service\nspec:\n ports:\n - port: 9000\n protocol: TCP\n targetPo"
},
{
"path": "pkg/kfapp/kustomize/testdata/operator/expected/service.yaml",
"chars": 272,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n annotations:\n kfctl.kubeflow.io/kfdef-instance: operator.kubeflow\n labels:\n"
},
{
"path": "pkg/kfapp/kustomize/testdata/operator/kustomization.yaml",
"chars": 98,
"preview": "apiVersion: kustomize.config.k8s.io/v1beta1\nbases:\n- base\nkind: Kustomization\nnamespace: kubeflow\n"
},
{
"path": "pkg/kfapp/minikube/minikube.go",
"chars": 4485,
"preview": "/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use th"
},
{
"path": "pkg/kfconfig/awsplugin/OWNERS",
"chars": 38,
"preview": "approvers:\n - jeffwan\n - PatrickXYS\n"
},
{
"path": "pkg/kfconfig/awsplugin/doc.go",
"chars": 915,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfconfig/awsplugin/register.go",
"chars": 2115,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfconfig/awsplugin/types.go",
"chars": 6289,
"preview": "package awsplugin\n\nimport (\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n)\n\n// +k8s:deepcopy-gen:interfaces=k8s.io/api"
},
{
"path": "pkg/kfconfig/awsplugin/zz_generated.deepcopy.go",
"chars": 6020,
"preview": "// +build !ignore_autogenerated\n\n/*\nCopyright The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (t"
},
{
"path": "pkg/kfconfig/doc.go",
"chars": 904,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfconfig/gcpplugin/doc.go",
"chars": 915,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfconfig/gcpplugin/register.go",
"chars": 2115,
"preview": "// Copyright 2018 The Kubeflow Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may "
},
{
"path": "pkg/kfconfig/gcpplugin/types.go",
"chars": 4277,
"preview": "package gcpplugin\n\nimport (\n\t\"fmt\"\n\tkfapis \"github.com/kubeflow/kfctl/v3/pkg/apis\"\n\t\"github.com/kubeflow/kfctl/v3/pkg/kf"
}
]
// ... and 88 more files (download for full content)
About this extraction
This page contains the full source code of the kubeflow/kfctl GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 288 files (3.8 MB), approximately 1.0M tokens, and a symbol index with 1342 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.