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 ================================================ **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) # 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 . If just , a directory 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/). (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 [: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 [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 // // 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 `) replicateBuildCmd.Flags().StringVarP(&directory, "directory", "d", "kustomize", `The directory to search for kustomization files listing images to mirror kfctl alpha mirror build -d `) 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 -o ", 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 `) // 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 ", 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 ", 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 =, 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 [: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(\w[\w-0-9]+\.)+\w+)(:(?P\d+))?(/(?P([\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(\w[\w-0-9]+\.)+\w+)(:(?P\d+))?/)?((?P([\w-_]+/)*([\w-_]+))/)?(?P[\w-_]*)(:(?P.*))?$`) 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":""},{"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: iVBORw0KGgoAAAANSUhEUgAABvAAAAbwCAYAAAC1MBbrAAAACXBIWXMAAC4jAAAuIwF4pT92AAAgAElEQVR4nOzdPXJbV6Ku4W+fcngD3hEc3hEcMt5Bgz0CaQQg81VlKuxIUnRDUVXIhT0CcQRXcIBY8AgMzwBB5/sGG2pL3f6RBIALG3ieKpVY7bb5lX9kF1+utRIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICDKl1/W7r+l9L1t7W3AAAAnKqm9gAAAADGoXT9VZIPSS62/9M6ydsk89m02dTaBQAAcGoEPAAAAP5S6fqLJB+TXP7Ob95kCHkPQh4AAMDuBDwAAAD+Uun690me/cX/TcgDAADYAwEPAACAP1W6/j7Jm2/4XT6FvPls2qwPMgoAAOCECXgAAAD8odL1kwzv3n2veZLXQh4AAMDXE/AAAAD4Xdt3735JcrGHP9w8Qh4AAMBX+a/aAwAAADha77OfeJckt0l+KV3/rnT95Z7+mAAAACfJCTwAAAD+Q+n6N0nuD/gpFhlO5C0O+DkAAABGScADAADgC6Xrn2U4ffcUFhHyAAAAviDgAQAA8C/b6y0/Zn9XZ36tRYQ8AACAJAIeAAAAW6XrL5J8SHJVccYqydvZtJlX3AAAAFDVf9UeAAAAwNF4k7rxLtvP/650/S+l628rbwEAAKjCCTwAAACyjWXvau/4HesMV2vOK+8AAAB4MgIeAADAd5gt+4sk90lS2uZV3TW7KV1/leHqzKd+9+5brJO8TTKfTZtN5S0AAAAHJeABAAB8g8/C3Y8ZotJNaccblLbv3n1Mcll5ytfaZAh5D0IeAABwqgQ8AACAr/Bv4e4iQ0i6KW2zqjpsR6Xr3yd5VnvHdxDyAACAkyXgAQAA/InZsr9M8jJD5Pr8ism70o77XbbS9fdJ3tTesaNPIW8+mzbrylsAAAD2QsADAAD4HZ+Fu9vf+c0PpW1ePOmgPStdP8nw7t0pmSd5LeQBAABjJ+ABAAB85i/CXZKsSttcP9mgA9i+e/dLvjxReErmEfIAAIAR+6H2AAAAgGMwW/aTJNP8cbhLhusanz/FngN7n9ONd8nw1/C2dP08Qh4AADBCTuABAABnbRvuXiaZfMX//aa0zeKQew6tdP2bJPe1dzyxRYaQt6i8AwAA4KsIeAAAwFn6xnCXJK9L27w61J6nULr+WYbTd+dqESEPAAAYAQEPAAA4K7Nl/yzJj/n6cJcki9I2N4dZ9DRK118m+ZjTvjrzay0i5AEAAEdMwAMAAM7CbNnfZjhxd/mNv+s6yXVpm82eJz2Z0vUXST4kuaq95ciskrydTZt57SEAAACfE/AAAICTtkO4++S6tM1qb4MqKF3/Lslt7R1HbJ3hRN688g4AAIAkAh4AAHCi9hDukuRFaZuHvQyqpHT9bZJ3tXeMxDpCHgAAcAQEPAAA4GTMlv1FkvsMb9zt+tbbvLTN3e6r6ildf5Xh6kzv3n2bdZK3Seaz6XivTgUAAMZLwAMAAEZvz+EuGd5Gu/Hu3dnbZAh5D0IeAADwlAQ8AABgtA4Q7pIh2tycwLt375M8q73jRAh5AADAkxLwAACA0Zkt+8sM79s9y/6vh7wr7bjfQCtdf5/kTe0dJ+hTyJvPps268hYAAOCECXgAAMBofBbubg/0KR5K27w40B/7SWzfvftYe8cZmCd5LeQBAACHIOABAABH7wnCXZKsSttcH/CPf3Dbd+9+yf5PJfLH5hHyAACAPfuh9gAAAIA/Mlv2kyTTHDbcJcPViM8P/DmewvuId0/tNslt6fp5hDwAAGBPnMADAACOzjbcvUwyeaJPeVPaZvFEn+sgSte/yvDnjLoek7ydTcf99xMAAFCXgAcAAByNCuEuSV6Xtnn1hJ9v70rXP8tw+o7jschwIm9ReQcAADBCAh4AAFDdbNk/S/JjnjbcJcmitM3NE3/OvSpdf5nkY1ydeawWEfIAAIBv5A08AACgmtmyv81w4u6ywqdfx7t3HN4kyaR0/SJJN5s286prAACAUXACDwAAeHKVw90n16VtVhU//85K179Lclt7B99kneFE3rzyDgAA4IgJeAAAwJM5knCXJC9K2zxU3rCT0vW3Sd7V3sF3W0fIAwAA/oCABwAAHNRs2V8kuc/wxt0xXPU4L21zV3vELkrXXyX5kOP488lu1kleJ3mcTZtN5S0AAMCREPAAAICDOMJwlySrJDelHW8oKV1/kSHeXdXewl5tkrxN8iDkAQAAAh4AALBXRxrukiGQ3JzAu3fvkzyrvYODEfIAAAABDwAA2I/Zsr/M8L7dsxxXuPvkrrTjfm+sdP19kje1d/AkhDwAADhjAh4AALCTz8Ldbd0lf+pU3r37WHsHVcyTvJ5Nm3XlHQAAwBMR8AAAgO8yknCXJKvSNte1R+xi++7dLznOk408nXmEPAAAOAv/VXsAAAAwLrNlfzVb9u8yBKXbynP+yibJ89oj9uB9xDuGf95+KV3/rnT9ZeUtAADAATmBBwAAfJXZsp9kOHE3qbvkmzwvbfNYe8QuSte/yvDnHf7dY5K3s2mzqD0EAADYLwEPAAD4UyMNd0nyurTNq9ojdlG6/lmG03fwZxYZrtZcVN4BAADsiYAHAAD8rhGHuyRZlLa5qT1iF9srEj/G1Zl8vUWEPAAAOAk/1B4AAAAcl9myv80Q7i7rLvlu3r3jXE2STErXL5J0s2kzr7oGAAD4bk7gAQAASU4i3H1yXdpmVXvELkrXv0tyW3sHo7fOcCJvXnkHAADwjQQ8AAA4cycU7pLkRWmbh9ojdlG6/jbJu9o7OCnrCHkAADAqAh4AAJyh2bK/SHKfZJrTCHdJ8ljaZtRXZ5auv0ryIa7O5DDWSV4neZxNm03lLQAAwJ8Q8AAA4Ix8Fu5+zGlFolWSm9KON0qUrr/IEO+uam/h5G2SvE3yIOQBAMBxEvAAAOAMnHC4S4YYcXMC7969T/Ks9g7OipAHAABHSsADAIATNlv2lxmi3W1OL9x9clfacb/tVbr+Psmb2js4W0IeAAAcGQEPAABO0DbcvcwQ7k7ZvLTNXe0Ru9i+e/ex9g7Ymid5PZs268o7AADgrAl4AABwQs4o3CXJqrTNde0Ru9i+e/cxyWXlKfDv5hHyAACgGgEPAABOwGzZX+W3qzLPwSbJdWnHHRdK139IMqm9A/7EPEIeAAA8OQEPAABGbLbsJxlO3E3qLnlyz0vbPNYesYvS9a8y/LWDMXhM8nY2bRa1hwAAwDkQ8AAAYITOONwlyevSNq9qj9hF6fpJkg+1d8B3WGQ4kbeovAMAAE6agAcAACNy5uEuSRalbW5qj9hF6frLDO/eXVSeArtYRMgDAICD+aH2AAAA4K/Nlv1thnB3WXdJVZskz2uP2IP3Ee8Yv0mSSen6RZJuNm3mVdcAAMCJcQIPAACOmHD3hevSNqvaI3ZRuv5NkvvaO+AA1hlO5M0r7wAAgJMg4AEAwBES7v7Di9I2D7VH7KJ0/W2Sd7V3wIGtI+QBAMDOBDwAADgSs2V/keF01jTC3eceS9uM+urM0vVXST7E1Zmcj3WS10keZ9NmU3kLAACMjoAHAACVfRbufozA8+9WSW5KO94AULr+IkO8u6q9BSrYJHmb5EHIAwCAryfgAQBAJcLdX9pkiHdjf/fuXZLb2jugMiEPAAC+gYAHAABPbLbsLzNEu9sId3/mrrTjfkerdP19kje1d8AREfIAAOArCHgAAPBEtuHuZZzG+hrz0jZ3tUfsYvvu3cfaO+CIzZO8nk2bdeUdAABwdAQ8AAA4MOHum61K21zXHrGL7bt3H5NcVp4CYzCPkAcAAF8Q8AAA4EBmy/4qv12VydfZJLku7bi/kF+6/kOSSe0dMDLzCHkAAJBEwAMAgL2bLftJhhN3k7pLRul5aZvH2iN2Ubr+VYa//sD3eUzydjZtFrWHAABALQIeAADsiXC3s4fSNi9qj9hF6fpJkg+1d8CJWGQ4kbeovAMAAJ6cgAcAADsS7vZiUdrmpvaIXZSuv8zw7t1F5SlwahYR8gAAODM/1B4AAABjNVv2txnC3WXdJaO3SfK89og9eB/xDg5hkmRSun6RpJtNm3nVNQAA8AScwAMAgG8k3O3dTWnHfbKmdP2bJPe1d8CZWGc4kTevvAMAAA5GwAMAgK8k3B3Ei9I2D7VH7KJ0/W2Sd7V3wBlaR8gDAOBECXgAAPAnZsv+IsPJqmmEu317LG0z6qszS9dfJfkQV2dCTeskr5M8zqbNpvIWAADYCwEPAAB+x2fh7seIM4ewTnJd2vF+sb10/UWGeHdVewuQZHhP822SByEPAICxE/AAAOAzwt2T2GR4925Ve8guSte/S3JbewfwH4Q8AABGT8ADAIAks2V/mSHa3Ua4O7S70o77zarS9fdJ3tTeAfwpIQ8AgNES8AAAOGvbcPcyTlI9lXlpm7vaI3axfffuY+0dwFfbJHlM8no2bdaVtwAAwFcR8AAAOEvCXRWrDFdnjvYkzPbdu49JLitPAb7PPEIeAAAjIOABAHBWZsv+Kr9dlcnT2SS5Lu24v2heuv5DkkntHcDO5hHyAAA4YgIeAABnYbbsJxlO3E3qLjlbz0vbPNYesYvS9a8y/D0EnI55km42bRaVdwAAwBcEPAAATppwdxQeStu8qD1iF6XrJ0k+1N4BHMwiw4m8ReUdAACQRMADAOBECXdHY1Ha5qb2iF1s3737JclF7S3AwS0i5AEAcAR+qD0AAAD2abbsbzOEu8u6S8jw7t3z2iP24EPEOzgXkyST0vWLJG9n03Ff/QsAwHg5gQcAwEkQ7o7STWnHfYqldP2bJPe1dwDVrDOcyJtX3gEAwJkR8AAAGDXh7mi9KG3zUHvELkrXP0vyvvYO4CisI+QBAPCEBDwAAEZntuwvktwm+THC3TF6LG0z6qszS9dfxdWZwH9aR8gDAOAJCHgAAIzGNtzdZwh3wspxWie5Lm2zqT3ke5Wuv8gQ765qbwGO1ibJ2yQPs+l4f70DAOB4CXgAABw94W40NhnevVvVHrKL0vXvMpzwBPgrQh4AAAch4AEAcLRmy/4yv12VKdwdv7vSjvtaudL1t0ne1d4BjI6QBwDAXgl4AAAcnW24exmnoMZkXtrmrvaIXWzfvftYewcwapskjxneyVtX3gIAwIgJeAAAHA3hbrRWGa7OHO2pk+27dx+TXFaeApyOeYQ8AAC+k4AHAEB1wt2obZJcl3bcX6AuXf8+ybPaO4CTNI+QBwDANxLwAACoZrbsJxnC3aTuEnbwvLTNY+0Ruyhd/yrD34cAhzRP0s2mzaLyDgAARkDAAwDgyQl3J+OhtM2L2iN2Ubp+kuRD7R3AWVlkOJG3qLwDAIAjJuABAPBkhLuTsihtc1N7xC627979kuSi9hbgLC0i5AEA8Ad+qD0AAIDTN1v2t0l+THJVeQr7sUnyvPaIPfgQ8Q6oZ5JkUrp+keTtbDru64gBANgvJ/AAADiYbbh7meSy7hL27Ka04z4xUrr+TZL72jsAPrPOcCJvXnkHAABHQMADAGDvhLuT9rq0zavaI3ZRuv5Zkve1dwD8gXWEPACAsyfgAQCwF7Nlf5HkNsNVmZdVx3Aoj6VtRn11Zun6q7g6ExiHdYQ8AICzJeABALCTbbi7zxDuRJHTtU5yXdpmU3vI9ypdf5Eh3nmLERiTTZK3SR5m0/H+GgwAwLcR8AAA+C7C3dm5Lm2zqj1iF6Xr32U4JQowRkIeAMAZEfAAAPgms2V/md+uyhTuzsNdacd9hVvp+tsk72rvANgDIQ8A4AwIeAAAfJVtuHsZJ5jOzby0zV3tEbvYvnv3sfYOgD3bJHnM8E7euvIWAAD2TMADAOBPCXdnbZXk5gTevfuY5LLyFIBDmkfIAwA4KQIeAAC/S7g7e5sM8W7s7969T/Ks9g6AJzKPkAcAcBIEPAAAvjBb9pMM4W5SdwmVPS9t81h7xC5K17/K8PcywLmZJ+lm02ZReQcAAN9JwAMAIIlwxxceStu8qD1iF6XrJ0k+1N4BUNkiw4m8ReUdAAB8IwEPAODMCXf8m1Vpm+vaI3axfffulyQXtbcAHIlFhDwAgFH5ofYAAADqmC372yQ/JrmqPIXjsUlyU3vEHnyIeAfwuUmSSen6RZK3s+m4r0gGADgHTuABAJyZbbh7meSy7hKO0E1px306o3T9myT3tXcAHLl1hhN588o7AAD4AwIeAMCZEO74C69L27yqPWIXpeufJXlfewfAiKwj5AEAHCUBDwDghM2W/UWS2wxXZV5WHcMxeyxt87z2iF2Urr9M8jGuzgT4HusIeQAAR0XAAwA4Qdtwd58h3Aka/Jl1kuvSNpvaQ75X6fqLDO/eec8RYDebJG+TPMym4/33AgDAKRDwAABOiHDHd7gubbOqPWIXpevfZThpCsB+CHkAAJUJeAAAJ2C27C/z21WZwh1f6660474urXT9bZJ3tXcAnCghDwCgEgEPAGDEtuHuZZw+4tvNS9vc1R6xi9L1VxmuzhStAQ5rk+Qxwzt568pbAADOgoAHADBCwh07WiW5OYF37z4muaw8BeDczCPkAQAcnIAHADAiwh17sMkQ78b+7t37JM9q7wA4Y/MIeQAAByPgAQCMwGzZTzKEu0ndJZyA56VtHmuP2EXp+vskb2rvACDJEPK62bRZVN4BAHBSBDwAgCMm3LFnD6VtXtQesYvS9ZMM794BcFwWGU7kLSrvAAA4CQIeAMAREu44gFVpm+vaI3axfffulyQXtbcA8IcWEfIAAHb2Q+0BAAD8Zrbsb5P8mOSq8hROyybJTe0Re/A+4h3AsZskmZSuXyR5O5uO+9pmAIBanMADADgC23D3Msll3SWcqJvSjvskROn6N0nua+8A4JutM5zIm1feAQAwKgIeAEBFwh1P4HVpm1e1R+yidP2zDKfvABivdYQ8AICvJuABADyx2bK/SHKb4arMy6pjOHWPpW2e1x6xi9L1l0k+xtWZAKdiHSEPAOAvCXgAAE9kG+7uM4Q7MYJDWye5Lm2zqT3ke5Wuv0jyId6EBDhF6yRdkofZdLz/rgIAOBQBDwDgwIQ7KrkubbOqPWIXpevfZTitCsDp2iR5GyEPAOALAh4AwIHMlv1lfrsqU7jjKb0obfNQe8QuStffJnlXewcAT0bIAwD4jIAHALBn23D3Mk4OUce8tM1d7RG7KF1/leHqTOEb4PxsksyTvJ1Nm3XdKQAA9Qh4AAB7ItxxBFZJbk7g3buPSS4rTwGgvnmS10IeAHCOBDwAgB0JdxyJTYZ4N/Z3794neVZ7BwBHZR4hDwA4MwIeAMB3mi37SYb37cQGjsFdaZt57RG7KF1/n+RN7R0AHK15hqs1R/3NKgAAX0PAAwD4Rttw9zLJpO4S+JeH0jYvao/YRen6SYZ37wDgrywynMhbVN4BAHAwAh4AwFcS7jhSq9I217VH7GL77t0vSS5qbwFgVBYR8gCAE/VD7QEAAMdutuxvk0wj3HF8Nkme1x6xB+8j3gHw7SZJJqXrFxHyAIAT4wQeAMAf2Ia7l0ku6y6BP3RT2nF/sbJ0/Zsk97V3AHAS1hlC3rzyDgCAnQl4AAD/RrhjJF6XtnlVe8QuStc/y3D6DgD2aR0hDwAYOQEPACDJbNlfJHkW4Y5xWJS2uak9Yhel6y+TfIyrMwE4nHWEPABgpAQ8AOCsbcPdfZIfIyQwDusk16VtNrWHfK/S9RdJPiS5qr0FgLOwTtIleZhNx/vvTwDgvAh4AMBZEu4YsevSNqvaI3ZRuv5dktvaOwA4O5skbyPkAQAjIOABAGdFuGPkXpS2eag9Yhel62+TvKu9A4CzJuQBAEdPwAMAzsJs2V9meN/utu4S+G7z0jZ3tUfsonT9VYarM8VzAI7BJsk8ydvZtFnXnQIA8CUBDwA4acIdJ2KV5Ma7dwBwMPMkr4U8AOBYCHgAwEkS7jghmwzxbuzv3r1P8qz2DgD4C/MIeQDAERDwAICTMlv2kwzv2wkFnIq70jbz2iN2Ubr+Psmb2jsA4BvMM1ytOepvoAEAxkvAAwBOwjbcvUwyqbsE9uqhtM2L2iN2sX337mPtHQDwnRYZTuQtKu8AAM6MgAcAjJpwxwlblba5rj1iF9t3735JclF7CwDsaBEhDwB4Qj/UHgAA8D1my/42yTTCHadpk+R57RF78D7iHQCnYZJkUrp+ESEPAHgCTuABAKOyDXcvk1zWXQIHdVPacX9hsHT9qwz/rALAKVpnCHnzyjsAgBMl4AEAoyDccUZel7Z5VXvELkrXP8tw+g4ATt06Qh4AcAACHgBwtGbL/iLJswh3nI9FaZub2iN2Ubr+MsnHuDoTgPOyjpAHAOyRgAcAHJ1tuLtP8mNEAM7HOsl1aZtN7SG7KF3/MclV7R0AUMk6SZfkYTYd97/TAYC6BDwA4GgId5y569I2q9ojdlG6/l2S29o7AOAIbJK8jZAHAHwnAQ8AqE64g7wobfNQe8QuStffJnlXewcAHBkhDwD4LgIeAFDNbNlfZnjf7rbuEqhqXtrmrvaIXZSuv0ryIQI8APyRTZJ5krezabOuOwUAGAMBDwB4csId/Msqyc2Y370rXX+RId559w4Avs48yWshDwD4MwIeAPBkhDv4wiZDvBv7u3fvkzyrvQMARmgeIQ8A+AMCHgBwcLNlP8nwvp0v8sNv7krbzGuP2EXp+vskb2rvAICRm2e4WnPU39QDAOyXgAcAHMw23L1MMqm7BI7Oqbx797H2DgA4IYsMJ/IWlXcAAEdAwAMA9k64gz+1Km1zXXvELrbv3v2S5KL2FgA4QYsIeQBw9n6oPQAAOB2zZX+bZBrhDv7IJsnz2iP24H3EOwA4lEmSSen6RYQ8ADhbTuABADvbhruXSS7rLoGj97y0zWPtEbsoXf8qwz/vAMDTWGcIefPKOwCAJyTgAQDfTbiDb/K6tM2r2iN2Ubr+WYbTdwDA01tHyAOAsyHgAQDfZLbsL5I8i3AH32JR2uam9ohdlK6/TPIxrs4EgNrWEfIA4OQJeADAV9mGu/skP8YX8OFbbJL8n9I2m9pDdlG6/mOSq9o7AIB/WSfpkjzMpuP+7wwA4D8JeADAnxLuYGfXpW1WtUfsonT9uyS3tXcAAL9rk+RthDwAOCkCHgDwu4Q72IsXpW0eao/YRen62yTvau8AAP6SkAcAJ0TAAwC+MFv2lxnet7utuwRG77G0zfPaI3ZRuv4qyYeI+AAwJpsk8yRvZ9NmXXcKAPC9BDwAIIlwB3u2SnIz5nfvStdfZIh33r0DgPGaJ3kt5AHA+Ah4AHDmhDvYu02GeDf2d+/eJ3lWewcAsBfzCEKWPvYAACAASURBVHkAMCoCHgCcqdmyn2R4384X6GG/7krbzGuP2EXp+vskb2rvAAD2bp7has1Rf6MRAJwDAQ8Azsw23L1MMqm7BE7SvLTNXe0Ru9i+e/ex9g4A4GDWGSLeQ+0hAMAfE/AA4EwId3Bwq9I217VH7GL77t3HJJeVpwAAu9tkeJf3pwzRbj2bNouagwCAr/dD7QEAwGHNlv1tkmmEOzikTZLntUfswfuIdwAwNp9C3SrJr58+nk2bTdVVAMBOBDwAOFHbcPcyvhgPT+GutM269ohdlK5/FaEfAI7dIsNpul8/fTybjvu/QQCA3+cKTQA4McIdPLnXpW1e1R6xi9L1kyQfau8AAP5llSHU/ZzfTtStaw4CAJ6WgAcAJ0K4gyoWpW1uao/YRen6ywzv3l1UngIA52i9/fFTttFuNm1WNQcBAMfBFZoAcAJmy/4yybvaO+DMnNK7d+IdABzWp3fqfso22s2mzaLmIADguAl4AHAarmoPgDN0U9pmU3vELkrXv4lfPwBgnz6FulWGd+o+XX856v9mAACenoAHAKfhb7UHwJl5UdpxX29Vuv42yX3tHQAwYosMp+l+/fSxd+oAgH0R8ADgNExqD4Az8lja5qH2iF2Urr9K8qb2DgAYiVWGUPdzvFMHADwRAQ8AToMr8OBprJLc1R6xi9L1FxnezPTuHQB8ab398emdupVQBwDUIuABwMjNlv2k9gY4E5skd2N/9y7DyTvRH4Bz9vk7dT9nOFG3qLoIAODfCHgAMH6T2gPgTJzCu3f3SW5r7wCAJ7TIEOp+3f68mk1H/804AMAZEPAAYPz+p/YAOAPz0jbz2iN24d07AE7cIsO1l79++ng2bdb15gAA7EbAA4Dxm9QeACduVdrmFN69e197BwDswSpDqPv508feqQMATpGABwAjNlv2V0kuau+AE7ZJ8rz2iD14n+Sy9ggA+Abr7Y+ftj+vhDoA4JwIeAAwble1B8CJuyvtuK/fKl3/Kk7qAnC8Ntm+TZfhVN16Nm0WVRcBABwBAQ8Axu1vtQfACXsobfNYe8QuStdPkrysvQMAthYZQt2v259Xs2mzqboIAOBICXgAMG6T2gPgRC1K27yoPWIXpesv4907AOr4dKLu1wzRbj2bjvtEOwDAUxPwAGCkZsv+It60gkM4pXfvvJEJwCGtMrxP9/Onj71TBwCwHwIeAIzXpPYAOFHPSzvu67xK17+JNzIB2J/19sdPnz72Th0AwGEJeAAwXr44D/v3orTj/oJk6frbJPe1dwAwSpt8ef3lSqgDAKhDwAOA8fpb7QFwYh5L2zzUHrGL0vVXSd7U3gHAKCzy5fWXq9l03CfQAQBOiYAHAOM1qT0ATsg6yV3tEbsoXX+R5F28ewfAlz4/UbfIcP3luuYgAAD+moAHACM0W/aT2hvghGxyAu/eZTh552pdgPO1ypcn6tazabOquggAgO8m4AHAOPkiPezPi9KO+wucpevvk9zW3gHAk1hvf/z06WPv1AEAnB4BDwDGyft3sB/z0jbz2iN24d07gJO1yZfXX66EOgCA8yHgAcA4TWoPgBOwSvKi9ohdbN+9e197BwA7W2Q4TffpnbrVbDr6q50BANiBgAcAIzNb9pdJLmrvgJE7lXfv3ie5rD0CgK/2+Tt1iwzXX64r7gEA4EgJeAAwPpPaA+AE3JV23F8wLV3/Kn49ADhW6wyx7uftz+vZdNzvrQIA8LQEPAAYn/+pPQBG7qG0zWPtEbsoXT9J8rL2DgCy3v746dPH3qkDAGAfBDwAGJ9J7QEwYovSNt69A+BbbTKcpFtleKduFe/UAQBwQAIeAIzIbNlfJLmqvQNGapPkee0Re/Ah3sEEOKRFhtN0v24/FuoAAHhyAh4AjIt4B9/veWnH/QXY0vVv4tcBgH1ZZQh1P2cb7WbTcb+PCgDA6RDwAGBcJrUHwEi9KO243yQqXf8syX3tHQAjtM4Q637e/ryeTZtV1UUAAPAXBDwAGJe/1R4AI/RY2uah9ohdlK6/SvKu9g6AI7fe/vjp08ez6bi/eQMAgPMl4AHAuLg6D77NOsld7RG7KF1/kSHeefcOYLDJcJJuleGdulW8UwcAwIkR8ABgJGbL/iq+gA/fYpMTePcuiXfvgHO2yPDNGL/GO3VQ3d//8c+LDP9dcpXkv7c/3/2///u/1jV3AcApEvAAYDwmtQfAyLwo7bjfOCpdf5vktvIMgKewyhDqPr1TtxLqoK6//+OfkySX2x9/yxDrfu8bCidJ5k+zCgDOh4AHAOPxP7UHwIjMS9vMa4/YhXfvgBO1zm/v1K0ynKgb9TdbwNj9/R//vMoQ6a4yhLrL7Y+v9bcIeACwdwIeAIzHpPYAGIlVkhe1R+xi++7d+9o7AHbw6Z26n7KNdrNps6g5CM7d3//xz8v8dv3l/+S3aLcrV30DwAE0tQcAAH9ttuwvk/xSeweMwCbJdWnHfe1a6fr3SZ7V3gHwFT6FulWGd+o+XX859vdHYbS2oe4ywzcA/vdnHx/S//5///d/+eceAPbICTwAGAff1Qpf5+4E4t2riHfAcVpkOE3366ePvVMH9fz9H/+8yG8n6v77s49/7526Q7vK8OsCALAnAh4AjMPfag+AEXgobfNYe8QuStdPkrysvQM4e6sMoe7n/Haibv3/2bt/3DaytV/ULw9uSODoG0Fzj8ByzMBlpkqsEVjKCVwrVNR2xNA+gHKJI7BGQGtDUNzSCDZ7BFcHYM4bVGlL7j9u26T41qp6HkBQffvbbf92m7ar6rfWejMDQd9NTldVPM6mexV5Rd3fqUKBBwBbpcADgDLYgQffdjUdD8y9A/gxy+br39GUdmdvB7eZgaDvJqer/XicTfcqHku7trPgEAC2TIEHAGWosgNAi91HxGF2iC34Eu1aSQ90x8Ocun9HU9qdvR1cZQaCvvvDnLoX8VjalarKDgAAXTPIDgAAfNvZzbqK+sU+8NdeT8dlv4ieztcfI+Jddg6gE66iLut+j8fjL+9TE0GPPZlTV0U9p24U3S27Xi5mQ7t4AWBL7MADgParsgNAi33oQHn3JpR3wI+7ino33e8P1+bUQZ4nRd1+1EXdw3WfdtdXUS8cAAC2QIEHAO33IjsAtNTldDx4nx1iE9P5ej8izrNzAK12G3VRdxfm1EErTE5XVTzOpitpTt1zexURn7JDAEBXKPAAoP2q7ADQQsuIOM4OsYnpfL0XdXnXp5X5wN9bNl8Pc+puFXWQa3K62o/H2XQvmu+jxEhtV/IMPwBoHQUeALTY2c26b8fuwPc6nI6Ln+n0Mbzogj66j2Y2XdS76pZnb8s+ChhKNzldjeJxNt2LeCzt+DGjyelqtJgNl9lBAKALFHgA0G5eHMCfHU/HZe9Kmc7XRxFxlBwDeH5XURd1vzffb8/eFr/4AIr1ZE5dFfWculE47WLb9qPeRQwAbEiBBwDt9io7ALTMxXQ8uMgOsQlz76CTrqJ+Yf37w/XZ28EyLw7025Oibj/qou7h2skWz+9VRFxmhwCALlDgAUC72YEHj24j4iQ7xCaauXefs3MAP+026qLu7uHanDrINTldVVHvpBtFXR49XJOjyg4AAF2hwAOAljq7WT+sHAbqmVHHHZh7dx5eKkIJls3Xv5vvt4o6yDU5Xe3H42y6F833UWIk/prnFwDYEgUeALRXlR0AWqQLc+/eR8Sb7BzAV+6jmU0X9a665dnbwVVqIui5yelqFI+z6Z4ef0khJqerajEbXmXnAIDSKfAAoL28qIDap+l4UPQslel8XUXEr9k5oOeu4uvjL2/P3ha/qxeK9Yc5dS/isbSjfFXUf+YCABtQ4AFAe73KDgAtcDsdD8y9A37Ew46636Mp7c7eDpaZgaDvmjl1+/H1jrq9zEw8qxfZAQCgCxR4ANBeVXYASHYfEa+zQ2zBl/CSEp7DbXy9o25pTh3kaoq6UfP16sk1/VJlBwCALhhkBwAA/uzsZr0fEb9l54Bkr6fjsmdRTefrjxHxLjsHFG7ZfP374dqcOsg1OV3tR13MPT3+0vHvPPVyMRtaVAEAG7ADDwDaqcoOAMk+dKC8exPKO/gR9/H18Ze3ijrINTldjeJxNt3T4y/hn+xH/ec5APCTFHgA0E7m39Fnl9Px4H12iE1M5+tRRJxn54AWu4qvj7+8PXs7uM8MBH02OV3txWM597CjrkqMRPleRcRFdggAKJkCDwDaycpm+moZEcfZITYxna/3IuJzmHsHEV/vqLuK+vjLZWYg6LtmTt1+fL2jzt9ZbFuVHQAASqfAA4CWObtZj6Je9Qx9dDgdF78L52Mo4emf2/h6R93y7O3A0WmQqCnqRs3XqyfXsAujyelqbzEbln5fBwBpFHgA0D5VdgBIcjwdl/3CfzpfH0XEUXIMeE7L5uvfD9fm1EGuyelqP+pi7unxlxaS0AZVRFxmhwCAUinwAKB9XmQHgAQX0/HgIjvEJqbz9X7Uu++gC+7j6+MvbxV1kGtyuhrF42y6X8KcOtpvPxR4APDTFHgA0D5VdgDYsduIOMkOsQlz7yjcVdS76R7m1N2evS3+KFso1uR0tRePs+ke5tRVmZngJ73KDgAAJVPgAUD7OPKIPrmP+ujM0suC8zBXiPZ7OqfuKurjL5eJeaD3nsypexGPpZ3FIHRFlR0AAEo2yA4AADw6u1lXEfElOwfs0OF0PCj6aKXpfP0uHJ1JuyyjLuvumu/Ls7dlz5eE0jVz6h5m1b1qvo/yEsHOvF7MhlfZIQCgRHbgAUC7VNkBYIc+daC8q0J5R55l8/Xvh2tz6iBXU9SNoi7rXjy5hr7aj3rXNwDwgxR4ANAu5kTQF7fT8aArc+/gud1HvZPuNuo5dbdhTh2kmpyuRlGXc1XUc+oeroGvvYqIT9khAKBECjwAaBcrtOmD+4h4nR1iCz6HOUVs31XUu+l+b64VdZBocrrai8fZdL8036vMTFCYKjsAAJTKDDwAaImzm/V+RPyWnQN24PV0XPYxf9P5+mNEvMvOQdFuoy7q7qIp7c7eDpaJeaD3JqerKuqddC/isbSzUAM296/FbLjMDgEApbEDDwDaw+47+uBDB8q7N6G84/stoy7r7prvy7O3g9vURNBzf5hT96q5HuUlgs6rIuIiOQMAFEeBBwDtYf4dXXc5HQ/eZ4fYxHS+HkXEeXYOWmnZfP374frsbdllNZSumVP3sJPuRTyWdsBuvcgOAAAlUuABQHtU2QHgGS0j4jg7xCam8/VemHtHPcPxtvn6/eHanDrI0xR1o6jvpX55cg20Q5UdAABKZAYeALTA2c16LyL+v+wc8IxeTsdlHxs4na/PI+IoOwc7dRV1+fx7mFMH6Sanq7143FH3S5hTByX5n8VsaLELAPwAO/AAoB2q7ADwjE46UN4dhfKuy26jLuoe5tTdKuog1+R0VcXjbLpXoaiD0u1HvRgGAPhOCjwAaAfz7+iqi+l48Ck7xCam8/V+RHzMzsFWLONxTt1t1Dvqii6XoXST09V+PM6mexWPpR3QLVUo8ADghyjwAKAd9rMDwDO4jYiT7BCbMPeuWA9z6v4dTWl39nZwlRkI+q6ZU/dw5OWLeCztgH6wYBEAfpACDwDaocoOAFt2HxHH0/Gg9Fkn52EnSJs9FHW3Uc+pezj+svTPHRSrKepGUd/b/PLkGug3hT0A/KBBdgAA6Luzm3UVEV+yc8CWHU/Hg4vsEJuYztfvwtGZbXIV9W663x+uzamDPJPT1V487qj75cm1HcvA33m5mA0dXQ0A38kOPADIZzUqXfOpA+VdFcq7LLdRF3V38bijbpkZCPpucrqq4nE23atQ1AE/p4r673YA4Dso8AAgn3kQdMntdDzoytw7ntey+fp3NKXd2duBl3qQaHK62o/H2XQvmu+jxEhAt7zIDgAAJVHgAUC+KjsAbMl9RBxmh9iCz2FnyTY9zKn7dzSl3dnbwVVmIOi7P8ypexGPpR3Ac6qyAwBASczAA4BEZzfrUUT8JzsHbMnr6bjsYmY6X3+MiHfZOQp2FXVZ93s8Hn95n5oIeuzJnLoq6jl1o/ACHcj1r8VsuMwOAQAlsAMPAHJV2QFgSz50oLx7E8q773UV9W663x+uzamDPE+Kuv2oi7qHa7uJgbbZj/oeAgD4Bwo8AMhl/h1dcDUdD95nh9jEdL4eRcR5do4Wuo36JdtdmFMHrTA5XVVR76QbRX0f8XANUIJXEXGZHQIASqDAA4Bc5s1QumUUPvduOl/vhbl3y+brYU7draIOck1OV/vxOJvuRfN9lBgJYBs8/wDAd1LgAUCSs5v1w3FXULLD6bj4GWcfoz+/F++jmU0X9a665dnbso8+hdJNTlejeJxN9yIeSzuALqqyAwBAKRR4AJDHyzlKdzIdl71LazpfH0XEUXKM53IVdVH3e/P99uxt8WUrFOvJnLoq6jl1o/AiG+ihyemqWsyGV9k5AKDtFHgAkKfKDgAbuJiOB5+yQ2xiOl/vR737rnRXUR97+fvD9dnbwTIvDvTbk6JuP+qi7uG6z8f0AjxVRX3PAgB8gwIPAPK8yg4AP+k2Ik6yQ2yi0Ll3t1EXdXcP1+bUQa7J6aqKeifdKOq/1x+uAfh7L7IDAEAJFHgAkKfKDgA/4T4ijjsw9+482vuSfdl8/bv5fquog1yT09V+PM6mM6cOYDNVdgAAKMEgOwAA9NHZzXo/In7LzgE/4Xg6Hlxkh9jEdL5+F+04OvM+mtl0Ue+qW569HVylJoKem5yuRvE4m+7p8ZcAbNfLxWxogRIAfIMdeACQo8oOAD/hUwfKu6y5d1fx9fGXt2dvi9/FCMX6w5y6hx11VWIkgL7Zj/qeCAD4Gwo8AMhh7gOluZ2OB12Ye/flmX+ahx11v0dT2p29HSyf+ecEvqGZU7cfX++oK2n+JUAXvYqIi+wQANBmCjwAyFFlB4AfcB8Rh9khtuBzbO+l/W18vaNuaU4d5GqKulHz9erJNQDt43hiAPgHZuABwI6d3axHEfGf7BzwA15Px2XPZpvO1+8j4tef+EeXzde/H67NqYNck9PVftTF3NPjL70IBijP/yxmQ0eKA8DfsAMPAHbPS0ZK8qED5d2b+Ofy7j6+Pv7yVlEHuSanq1E8zqZ7evwlAN1QRcRldggAaCsFHgDs3qvsAPCdrqbjwfvsEJuYztejiDj/w398FV8ff3l79nZg9TckmZyu9uKxnHvYUVclRgJgN/ZDgQcAf0uBBwC7V2UHgO+wjG7Mvasi4v9EU9qdvR0sM8NA3zVz6vbj6x1125pNCUBZLGwEgG8wAw8AduzsZr3OzgDf4eV0PLjNDgGUqZlT9zCr7lXzfZSXCIA2WsyG3k0CwN/wlyQA7NDZzbqKiC/ZOeAfnEzHg0/ZIYD2a4q6UXx9/KU5dQB8r5eL2dCiMQD4C47QBIDdqrIDwD+4UN4BfzQ5XY3icTbdL2FOHQDbUUU9kxgA+AMFHgDs1ovsAPANtxFxkh0CyDM5Xe3F42y6hzl1VWYmADrtVURYPAYAf0GBBwC7VWUHgL9xHxHH0/HgPjsIsBuT01UV9U66F/FY2u0lRgKgfxy7DAB/www8ANiRs5v1fkT8lp0D/sbxdDy4yA4BbF8zp+5hVt2r5vsoLxEAfOVfi9lwmR0CANrGDjwA2B2rS2mrC+UdlK8p6kZR/33z4sk1ALRZFREXyRkAoHUUeACwO6+yA8BfuJ2OB8fZIYDvNzldjaIu56qo59Q9XANAicwJB4C/oMADgN2psgPAH9xHxGF2COCvTU5Xe/E4m+6X5nuVmQkAnkGVHQAA2kiBBwA7cHaz3gvzhmif4+l4sMwOAURMTldVPM6mexV1WbeXlwgAdsZxzwDwFxR4ALAbVXYA+IMP0/HgMjsE9M0f5tS9isfSDgB6a3K6qhaz4VV2DgBoEwUeAOyGVaW0ydV0PHifHQK6rJlT93D85Yt4LO0AgD+rIuIqOQMAtIoCDwB241V2AGiYewdb1BR1o6hfPP7y5BoA+H6elwDgDxR4ALAbVXYAaLyejgf32SGgNJPT1V487qj75cm1OXUAsDm71AHgDwbZAQCg685u1lVEfMnOARFxMh0PPmWHgLabnK6qeJxN9yoUdQCwCy8Xs+FtdggAaAs78ADg+VlNShtcKu/ga5PT1X48zqZ7FY+lHQCwe/sRocADgIYCDwCen3kOZLuNiOPsEJClmVP3cOTli3gs7QCA9ngVERfZIQCgLRR4APD8vCQm031EHJt7Rx80Rd0o6rmjvzy5BgDar8oOAABtYgYeADyjs5v1KCL+k52DXjuejgcX2SFgmyanq7143FH3y5Nrc+oAoGz/s5gNLTwDgLADDwCeW5UdgF67UN5RusnpqorH2XTm1AFAt1URcZkdAgDaQIEHAM/rRXYAeut2Oh6Ye0cxJqer/XicTfei+T5KjAQA7N6rUOABQEQo8ADguVXZAeil+4g4zA4Bf+UPc+pexGNpBwDgngAAGgo8AHgmZzfrhxlNsGvH0/FgmR2Cfnsyp66Kek7dKCxqAAC+rcoOAABtocADgOejvCPDh+l44NghduZJUbcfdVH3cL2XmQsAKNPkdFUtZsOr7BwAkE2BBwDPp8oOQO9cTceD99kh6K7J6aqKeifdKOoZNQ/XAADbsh8RV9khACCbAg8Ans+r7AD0irl3bM3kdLUfj7PpXjTfR4mRAID+eBURn7JDAEA2BR4APB9HaLJLr6fjwX12CMoyOV2N4nE23Yt4LO0AALJU2QEAoA0G2QEAoIvObtb7EfFbdg5642Q6HlilzN96MqeuinpO3Si8HAMA2utfi9lwmR0CADLZgQcAz6PKDkBvXCrveKqZU7cfdVG333ztZWYCAPhBVURcJGcAgFQKPAB4Hi+yA9ALtxFxnB2CHE1RN2q+Xj25BgAo3atQ4AHQcwo8AHgeVXYAOu8+Io7Nveu+yelqPx5n05lTBwD0gXsdAHrPDDwA2LKzm/UoIv6TnYPOO56OBxfZIdieyelqFI+z6Z4efwkA0Ef/s5gNLVYDoLfswAOA7fPCned2obwr1+R0tReP5dzDjroqMRIAQBvtR8RVdggAyKLAA4Dte5UdgE67nY4H5t4VoplTtx9f76jby8wEAFCIKhR4APSYAg8Ats8OPJ7LfUQcZofgz5qibtR8vXpyDQDAz7EwEoBeU+ABwPZV2QHorOPpeLDMDtFnk9PVftTF3NPjL5X2AADbV2UHAIBMg+wAANAlZzfrKiK+ZOegkz5Nx4OT7BB9MTldjeJxNt3T4y8BANidl4vZ8DY7BABksAMPALaryg5AJ10p757H5HS1F4/l3MOOuioxEgAAj6qIUOAB0EsKPADYrhfZAegcc++25MmcuhfxWNrtJUYCAODbPF8B0FsKPADYrio7AJ1zOB0P7rNDlKSZU/cwq+5V832UlwgAgJ9UZQcAgCxm4AHAlpzdrEcR8Z/sHHTKyXQ8+JQdoq2aom4UXx9/aU4dAEC3/GsxGy6zQwDArtmBBwDbU2UHoFMulXe1yelqFI+z6X4Jc+oAAPpkPyKW2SEAYNcUeACwPa+yA9AZy4g4zg6xa5PT1V48zqb7pfleZWYCACDdq4i4zA4BALumwAOA7XF0H9twHz2Ye/dkTt2LeCzt9lJDAQDQRlV2AADIoMADgC04u1k/7ByCTZ1Mx4Pb7BA78DG8jAEA4J95zgKgl/5XdgAA6IgqOwCdcDEdDy6yQ+xIp3cYAgCwPZPTVZWdAQB2TYEHANthVSibuo2Ik+wQO3SXHQAAgGJU2QEAYNcUeACwHa+yA1C0Xsy9AwCAn/QiOwAA7JoCDwC2o8oOQNGOp+PBMjsEAAC0VJUdAAB2TYEHABs6u1k7PpNNfJqOB5fZIQAAoMX2Jqcrz10A9IoCDwA2V2UHoFhX0/GgT3PvAADgZynwAOgVBR4AbM78O37GfUQcZocAAIBCeO4CoFcUeACwOStB+RmH0/HgPjtEoqvsAAAAFKXKDgAAu6TAA4ANnN2sRxExSo5BeU6m48FVdggAACjIaHK62ssOAQC7osADgM1U2QEozuV0PPiUHQIAAApUZQcAgF1R4AHAZl5kB6Aoy4g4zg4BAACFMr4AgN5Q4AHAZqrsABTjPsy9AwCATbzKDgAAu6LAA4DNWAHK9zqZjge32SEAAKBgVXYAANgVBR4A/KSzm3WVnYFiXEzHg4vsEC2jzAQA4IdNTldVdgYA2AUFHgD8vCo7AEW4jYiT7BBts5gNHSUKAMDPcAoKAL2gwAOAn2f+Av/E3DsAANguz2EA9IICDwB+npWf/JPj6XiwzA4BAAAd4jkMgF5Q4AHATzi7We9HxF52Dlrt03Q8uMwOAQAAHTOanK5G2SEA4Lkp8ADg51j1ybdcTccDc+8AAOB5VNkBAOC5KfAA4OeYu8DfuY+Iw+wQhVhmBwAAoEgvsgMAwHNT4AHAz6myA9Bah9Px4D47RCGW2QEAAChSlR0AAJ6bAg8AftDZzXovIkbZOWilD9Px4Co7BAAAdNz+5HRlJjkAnabAA4AfV2UHoJUup+PB++wQAADQE+aSA9BpCjwA+HHm3/FHy4g4zg4BAAA9UmUHAIDnpMADgB9npSd/ZO4dAADsloWVAHSaAg8AflyVHYBWOZ6OB7fZIQq1zA4AAECxLKwEoNMUeADwA85u1lV2BlrlYjoeXGSHKNjv2QEAACjW3uR0pcQDoLMUeADwYzwg8uA2Ik6yQwAAQI9V2QEA4Lko8ADgx5izQETEfdRHZ5p7BwAAeV5kBwCA56LAA4AfU2UHoBXMvQMAgHxVdgAAeC4KPAD4Tmc361FE7GXnIN2n6XhwmR0CAACI0eR0NcoOAQDPQYEHAN+vyg5AutvpeGDu3fY4ghQAgE2ZUw5AJynwAOD7mX/Xb/cR8To7RMc4hhQAgE15TgOgkxR4APD9rOzst8PpeGDHGAAA9zVo8gAAIABJREFUtIvnNAA6SYEHAN/h7Ga9Fx4M++zDdDy4yg4BAAD8SZUdAACegwIPAL6P8q6/LqfjwfvsEAAAwF+bnK6q7AwAsG0KPAD4PlV2AFIsI+I4OwQAAPBNVXYAANg2BR4AfB+D0fup+Ll38+v1m+wMAADwzF5kBwCAbVPgAcD3qbIDsHPH0/HgNjvEJubX66OI+H+zc/ydxWx4lZ0BAIBOqLIDAMC2KfAA4B+c3azNv+ufi+l4cJEdYhPz6/V+RHzMzgEAADuwNzldjbJDAMA2KfAA4J9V2QHYqduIOMkOsYn59XovIj5HxF52FgAA2JEqOwAAbJMCDwD+mXkK/XEf9dGZRc+9i4jziBg113aQAgDQB+aWA9ApCjwA+GdVdgB2pgtz795FxJsn/5FdeAAA9IGFawB0igIPAL7h7GY9isedTHTbp+l4cJkdYhPz63UV5t4BANBP+5PTlcVrAHSGAg8Avs0qzn64nY4HXZl7V5qidzwCANAqVXYAANgWBR4AfJs5Ct13HxGvs0Nsweco87jM0ucNAgDQHhZgAtAZCjwA+LYqOwDP7nA6HhRdIs2v1x/DZxUAACzABKAzFHgA8G1WcHbbh+l4cJUdYhPz6/WbiHj3D/+d0W7SAABAqio7AABsy/+THQAA2ursZl1lZ+BZXU7Hg/fZITbRFHPn3/FfHUXE8jmzAAB/6TYiriLi9/jz3NdR8/UqlA6wNZPT1f5iNjRnGYDiKfAA4O9V2QF4NsuIOM4OsYn59Xovyp17BwBddhsR/yciLhez4Xcf0z05Xb2JiLcR8ea5gkFPVPHnwhwAiqPAA4C/9yI7AM+m+Ll3EfExunHE620oywHohquI+LCYDa9+5h9ezIaXEXE5OV2NIuLXiDjaVjDomVcR8Sk7BABsSoEHAH+vyg7AsziZjgdFr8idX6+Pojsv9f5vdgAA2NB91MXdVgqDxWy4jIjjyelqHvVR2aNt/LjQI11Y5AYA8b+yAwBAG53drPfD0YRddDEdD4pejTu/Xu9HvfsOAMh3GxGvt1XePdXs5HsZEZfb/rGh40bNTlYAKJoCDwD+mlWb3XMbESfZITaxwdw7ZTQAbN9DefdsO/sXs+H9YjY8jIgPz/VzQEdV2QEAYFMKPAD4a6+yA7BV9xFx3IG5dz97jJZCGgC266G828m9xWI2fB8Rh1Hf0wD/zDxzAIqnwAOAv6bw6JYuzL17FxFvsnMAALGMHZZ3Dxaz4WVEvI66PAS+rcoOAACbUuABwB+c3az3QoHXJZ+m48FFdohNzK/XVXR37t0yOwAA/KDDXZd3D5rjOl+HuXjwTzzPAVA8BR4A/FmVHYCtuZ2OB12Ze9dVy+wAAPADjp9z5t33eDIX71NmDmi7yemqys4AAJtQ4AHAn1mt2Q33Uc+KKd3niNjLDgEAxMViNrzIDvFgMRueRMRxmIsHf6fKDgAAm1DgAcCfvcoOwFYcTseDZXaITcyv1x9jOy8e/vcWfgwA6LPbxWx4nB3ij5pC8XXY0Q5/xXMdAEVT4AHAn1XZAdjYh+l4cJUdYhPz6/WbiHi3pR/OrlIA+Hmt3tXfHOn5MiKukqNA27gHBqBoCjwAeOLsZl1lZ2BjV9Px4H12iE3Mr9ejiDjPzgEARETE4WI2XGaH+JZmLt7rMBcPntqbnK6UeAAUS4EHAF/zgFe2ZbR4hfwP6NPcO3N7AGizk8VseJUd4nuZiwd/4vkOgGIp8ADga+YklO1wOh4U/cJqfr0+jx69aGiO/QKANrpczIbF7Wh7Mhev6Hsi2BLPdwAUS4EHAF/rTXHSQSfT8aDoMmh+vT6KiKPkGABAxG3UO9mK1CyQ+VfU/zugz6rsAADwsxR4ANA4u1mPImKUHIOfczEdD4pbIf/U/Hq9HxEfs3MAAHEfEceL2bDoHWzNXLyXEXGRnQUSjSanq74cTQ9AxyjwAOBRlR2An3IbESfZITYxv17vRcR5PN/cu+qZflwA6KLjLh3xvJgNj6Pg3YSwBVV2AAD4GQo8AHj0IjsAP+w+Io5Ln3sXdXnn+FYAyPdpMRteZofYtmYu3sswF49+MgcPgCIp8ADgUZUdgB/Whbl37yLiTXYOACCuFrNh0bv6v8VcPHrMQjkAiqTAA4CIOLtZ74UHu9J8mo4HF9khNmHu3X9dZQcAoPeWEXGYHeK5NXP9Xoe5ePRLlR0AAH6GAg8Aasq7stxOx4OiV8g3c+++ZOcAACIi4rAptzpvMRveN3Pxir6Xgh8xOV1V2RkA4Ecp8ACgVmUH4LvdRzdWyH+OiL3sEABAHDfHS/bKYjb8FPVuvF4Ul/SeBZsAFEeBBwA1g83LcTgdD5bZITYxv16/jx2Xxs1xnQDA1y4Ws+FFdogsi9nwKiJehrl4dJ/nPQCKo8ADgJpyowwfpuPBVXaITcyv128i4teEn9puPwD42m1zlGSvLWbDZZiLR/dV2QEA4Ecp8ADovbOb9X4oN0pwNR0P3meH2MT8ej2KiPPsHABAZ47k3oonc/E+ZGeBZ7I3OV2NskMAwI9Q4AGA1ZglWEY3XrKZe/fX/p0dAIDeOWx2nvHEYjZ8H/U9l7l4dFGVHQAAfoQCDwAiXmQH4B8dTseDol8kza/X5+GoVgBog5Nm9ht/YTEbXkZ9pKa5eHSNOXgAFEWBBwBWYrbdyXQ8KPoF0vx6fRQRR8kxAICIy8Vs+Ck7RNstZsPbqEu8y+wssEUW0wFQFAUeAL12drPei4hRdg7+1sV0PCj6Jdv8er0fER+zc4TPOQDcRsRxdohSNHPxDsNcPLpjf3K6cpw9AMVQ4AHQd1V2AP7WbUScZIfYxPx6vRcR59GOuXej7AAAkOg+Io4Xs2HRR3JnMBePjrELD4BiKPAA6DtzENrpPiKOS597F3V55yUBAOQ7bo6F5Cc8mYu3TI4Cm6qyAwDA91LgAdB3ypV26sLcu3cR8SY7RyGK/rUGoPU+NQUUG2gK0JcRcZUcBTZhAScAxVDgAdB3VXYA/uRiOh5cZIfYRIvm3pWi9J2WALTX1WI2LPpI7jZp5uK9joiiZxTTa1V2AAD4Xgo8AHrr7GZdZWfgT26n48FxdohNNHPvvmTnAABiGfXsNrasKUWPwyIcCjQ5XTmFBYAiKPAA6LMqOwBfuY9uvGT7HBF72SH+wi/ZAQBgxw4Xs6GC6ZksZsOLMBePMlXZAQDgeyjwAOizF9kB+MrxdDxYZofYxPx6/T7a+0JglB0AAHbouJnZxjN6MhfPv2tK4jkQgCIo8ADosyo7AP/1YToeXGaH2MT8ev0mIn7NzgEAxEWzO4wdaObivYyIi+ws8J2q7AAA8D0UeAD00tnNehTtPOawj66m48H77BCbmF+vRxFxnp2jYMvsAAB0xu1iNix6nm6pmn/v/t1TgtHkdDXKDgEA/0SBB0BfVdkBiAhz74iIxWy4zM4AQCd05b6iWM3Ox5dR/1pAm+1nBwCAf6LAA6CvXmUHICIiXk/Hg6Jf8Myv1+fhBQAAtMGhRSH5mrl4/wpz8Wg3z4MAtJ4CD4C+UrjkO5mOB0W/2Jlfr48i4ig5xveyQxCALjtZzIZX2SGomYtHAarsAADwTxR4APTO2c16LxR42S6n48Gn7BCbmF+v9yPiY3aOH+AzD0BXXS5mw6LvK7qqmYt3kp0D/oJ7YwBaT4EHQB9V2QF67jYijrNDbGJ+vd6LiPOwqw0AshV/X9F1Tbn6OszFo2Ump6sqOwMAfIsCD4A+stoyz31EHJc+9y7qnXc+R9tV+mcCgN27j4jjxWzo75CWa443fRnm4tEuVXYAAPgWBR4AfWRgeZ4uzL17F+XMvStJ0Z8LAFIcL2ZDf38UYjEbLqPeiXeRmwT+60V2AAD4FgUeAH1UZQfoqYvpeHCRHWITBc69A4Cu+rSYDS+zQ2zk4G4vDu6OsmPs0mI2vDcXjxapsgMAwLco8ADolbObtWMPc9xOx4Oi59M0c+8+Z+cAAOJqMRt2oQD6GBHncXB3Hgd3vZqray4eLbE3OV15PgSgtRR4APRNlR2gh+4j4jA7xBZ8johRdohNzK/XVXYGANjQMrpwX1HvvDtq/q+jiPjSwxLvKuoSzzGoZFLgAdBaCjwA+sb8u907no4Hy+wQm5hfr9+H8hcA2uBwMRuWvWvr4G4/Is7/8J/uR8R/mv9fbzQzDF9HRNnHoVIyz4cAtJYCD4C+6dVLkRb4MB0Pin4h0+xa+zU7Rw+U/TIWgF04bgqfctW77L78zf93LyJ+6+lcvMOI+JCdhV6qsgMAwN9R4AHQG2c361EUfgRiYa6m48H77BCbmF+vR2Hu3a7cZQcAoNUuFrPhRXaILfgcdVH3LfVcvJ5ZzIbvoz4e1aIedmk0OV316vhaAMqhwAOgT+y+250uzb3zQA8AuW4Xs+FxdoiNHdx9jO/f7XMUB3d9nIt3GebisXtVdgAA+CsKPAD6xHyD3Xk9HQ+KXj09v15/DKUvAGTrxqKg+ljMdz/4T1VRH6nZq/uRJ3PxrpKj0B+9+j0GQDkUeAD0SZUdoCdOpuNB0aum59fro/jxl2wl8HICgNIcLmbDZXaIjdQF3Mef/KdHEfGlp3PxXkfEp+ws9IKFngC0kgIPgD5RXjy/y+l4UPSLlvn1epOXbG3Xq2O4ACjeyWI2vMoOsZH6CMzz2Ozv4PrHOLh7v5VMBVnMhicRcRzm4vG8quwAAPBXFHgA9MLZzbrKztADt1G/YCnW/Hq9jZdsAMDmLhezYdGLghrnsb1FZL/Gwd3nHs7Fu4j6SM1lbhK6bHK6qrIzAMAfKfAA6IsqO0DH3UfEcelz76LeeWenZo6r7AAAtEbxi4IiIpodc2+2/KO+ifpIzV7drzRz8V6G+wWeT69+TwFQBgUeAH1hrsHz6sLcu3cRcZSdAwB67j4ijhezYdmLgg7uqoj49Zl+9P2oS7zqmX78VnoyF+8iOwud5HkRgNZR4AHQF1ZUPp+L6XhwkR1iEx2fewcAJTludluV6+BuFBGfn/ln2Yu6xHv3zD9P6yxmw+Powg5N2sbzIgCto8ADoPPObtb7YabZc7mdjgdFv0Bp5t4990u2tniRHQAAvuHTYja8zA6xkXo+3efY3b3nxzi4O+/pXLyXUe/YhG0YTU5Xo+wQAPCUAg+APrCa8nncR8Rhdogt+BwRo+wQO9Krl3sAFOVqMRueZIfYgox5ukdR78Yb7fjnTdXs1PxX1DMTYRuq7AAA8JQCD4A+MM/geRxPx4NldohNzK/X78ODOgBkW0YXFgUd3B1F3jzd/Yj4LQ7uerVwrZmL9zLMxWM7nFYBQKso8ADogyo7QAd9mI4HRR9xNb9eVxHxa3YO/svqeYD+OlzMhmUfhVgXZ+fJKfaiLvGOknPsnLl4bEmVHQAAnlLgAdBpZzfrvejP8Yi7cjUdD95nh9jE/Ho9iv7MvStC8S9uAfhZx81RiOWq5899yY7xxHkc3GWXiTtnLh5bsD85XTlyHoDWUOAB0HVVdoCO6dLcOw/nAJDroildStfG+4qjOLj7rSkXe6Mpg1+Gnf38vF4dQwtAuynwAOg68++263A6HhS9qnl+vf4Y/X0wH2UHAIDGbXPsYdkO7j5GexeM9XUu3jIiXoe5ePycKjsAADxQ4AHQdb16YfHMTqbjwVV2iE3Mr9dHEfEuO0eiUXYAAIiu7OivZ821/b5iFBFf+jYXbzEb3jcF8Ul2FopjASgAraHAA6DrquwAHXE5HQ8+ZYfYxPx6vR8RH7NzAABx2OySKle9q62U+4q9qOfilZJ3axaz4aeod+MVfYIEO2UBKACtocADoLPObtZVdoaOWEZE0Udcza/X9Yur9s2n4WvL7AAAPLuTxWx4lR1iI/VcuRLvK97Fwd3nHs7Fuwpz8fh+e5PTlRIPgFZQ4AHQZR68NncfHZh7F/UKeZ+H9ltmBwDgWV02O6JKdx7l3le8ifpIzVLz/5Qnc/Euk6NQhio7AABEKPAA6DbzCzZ3Mh0Pil6tPL9ev4uIo+wcANBzt1H4jv6IiDi4ex91CVay/ahLvNL/d/yQZi7eYUR8yM5C673IDgAAEQo8ALqtyg5QuIvpeHCRHWIT5t79WXOcKADs0n1EHC9mw7J39B/cVRHxa3aMLdmLiM9xcPcuO8iuLWbD9xFxGObi8feq7AAAEKHAA6Cjzm7WoyhvLkmb3EbESXaITTRF1efsHC3UqyOzAGiF48VsWPSO/ji4G0U37ys+xsHdeQ/n4l1GfaRm2Z9Lnstocrrq1e8JANpJgQdAV1XZAQrWlbl3nyNilB0CAHruU1OWlKsutz5HdxeHHUV9pOYoOcdONaWyuXj8nSo7AAAo8ADoKnMLft7xdDxYZofYxPx6/T48dJdomR0AgK26WsyGRe/ob3yM7u9g34+I35pjQnvjyVy8T9lZaB3z1AFIp8ADoKuq7ACF+jQdD4pehTy/XlfRnfk0ffN7dgAAtmYZ9Zyxsh3cHUW9Q60P9qLeiXeUHWTXmqL5OMzF41HXS3sACqDAA6Bzzm7We+GB62dcTceDolfJm3sHAK1xuJgNyy5DDu72I+I8O0aC8zi4693/7sVseBH1kZrL3CS0RJUdAAAUeAB0kfLux91HF1bJR3yJ7s6nAYBSHDfzxcpVz737kh0j0VEc3P3W/HvojeZz+zIirpKj0AKT01WVnQGAflPgAdBFVXaAAh1Ox4OiV8nPr9d9mE+zDVV2AAA67aLZyVS6z2FR0H5E/KfZidgbzVy812EuHu6bAUimwAOgiwwc/zEn0/HgKjvEJubX6zcR8S47BwD03O1iNjzODrGxg7uP4cX9A3PxzMXrsxfZAQDoNwUeAF1UZQcoyOV0PCh6dfH8et3X+TRd5AUZQLm6cRx3XVRZFPS1vajn4n3MDrJrT+biuUfppyo7AAD9psADoFPObta9OuJnQ8uoVxUXa369rl8oOeKqK8qelwTQb4eL2XCZHWIj9VGRvSupfsC7OLj70tO5eP8K9yl9tDc5XY2yQwDQXwo8ALqmyg5QiPvowNy7qF+yKW0BINfJYja8yg6xkbqUsijon1VRH6nZq/uvZi7ey4i4yM7CzlXZAQDoLwUeAF1jTsH3OZmOB0WvIp5fr48i4ig5BgD03eViNiz6OO7GeVgU9L32oy7x3mQH2bVmxmPRJ1jww8xXByCNAg+ArqmyAxTgYjoeXGSH2IS5dxvxEgKAbbmNLpQZB3fvI6J3ZdSG9iLic/PvrleauXgvw1y8vlDsA5BGgQdAZ5zdrEcRMUqO0Xa3EXGSHWITzdy7z9k5AKDn7iPieDEbll1iHNxVEfFrdoyC/RoHd+fm4tFh+5PTVa8+3wC0hwIPgC6xOvLbujL37jwUtQCQ7bgpMcp1cDcKi4K24SjqIzVHyTl2qimvX4e5eH1QZQcAoJ8UeAB0iaMBv+14Oh4ss0NsYn69fh+OuOqsxWx4lZ0BgO/yaTEbXmaH2Ei9Y+xz1EdBsrn9iPit2dHYG4vZ8L6Zi1f0CRf8IwtFAUihwAOgS6rsAC32aToeFP2ibX69rsIRVwCQ7WoxG3ahrPgYXspv217UO/HeZQfZtcVs+Cnq3Xiln3TBX7NQFIAUCjwAusRLmL92NR0Pin7RZu4dALTCMiIOs0Ns7ODuKOpjH3keH+Pg7jw7xK41Jwm8DHPxuqjKDgBAPynwAOiEs5t1lZ2hpe6jCy/aIr6EI662RdENwM86bOZ+levgbj/qebo8r6M4uPutOaq0Nxaz4TLMxeukyenKPTQAO6fAA6ArquwALXU4HQ+KftE2v1474mq7evUiDYCtOV7MhmXvLKrLpC/ZMXpkPyL+05SmvfFkLt6H7CxsVZUdAID+UeAB0BUvsgO00Ml0PLjKDrGJ+fX6TUT0bo4KALTMxWI2vMgOsQWfw0KWXduLiN+aY0t7ZTEbvo/6JIyiF9PxX+bgAbBzCjwAuqLKDtAyl9Px4FN2iE3Mr9eOuOqnsnd3AHTPbbObqGwHdx/D/WKm8+bXoFcWs+Fl1Edqur8pX692kgLQDgo8AIp3drPeD6upn1pGRNEv2ubX672oyzu/rv1jlTpAe3Rjlm69+8uO/nzv4uDuSw/n4t1GXeJdZmdhI6PJ6WqUHQKAflHgAdAFVkN+rfi5dxFh7h0A5DtczIbL7BAbqeev9W7nV4tVUR+p2av7vGYu3mGYi1e6Xn1uAcinwAOgC8wjeHQ8HQ+KPqJnfr0+ioij5BidNr9ej7IzANB6J4vZ8Co7xEbqnV529LfPKCK+xMHdm+wgu2YuXvE8dwKwUwo8ALrASsjaxXQ8uMgOsQlz73ZmlB0AgFa7XMyGRc/SbZyH+8S22ouIz3Fw9z47yK49mYu3TI7Cj6uyAwDQLwo8AIp2drPeCy9mIiJuI+IkO8Qmmrl3n7NzAEDP3Ubhs3QjIppiqHc7vAr0axzcfe7pXLyXEXGVHIUf47kTgJ1S4AFQuio7QAvcR310ZulH8ZyHnWHUL44ByHEfEceL2bDse4qDuyoifs2OwXd7E/WRmqPsILvUzMV7HRFd2O3aG5PTVZWdAYD+UOABUDqrILsx9+59WCVP7f9mBwDoseNmZ1C56hLIjv7y7EfEb0352iuL2fAk6l2vZRfn/VFlBwCgPxR4AJSu74PEP03Hg8vsEJuYX6+rsEoeALJ9amZzlas+hvFz1PPVKM9e1Dvx3mUH2bXFbHgR5uKVou/PnwDskAIPgNJV2QES3U7HA3Pv+BlebALw1FWzC6h0H8PpDF3wMQ7uzns8F6/sXbDd588YAHZGgQdAsc5u1lV2hkT3Ua/SLd2XUCZl8OIBgAfLiDjMDrGxg7ujiDhKTsH2HEW9G69X94nNXLyXEXGRnYW/tTc5XbmXBmAnFHgAlKzPD06H0/Gg6DkZ8+u1VfIAkO9wMRsWfU8RB3f7EXGeHYOt24+I/zS/vr2ymA2Po56LRzv17jMJQA4FHgAl6+v8gQ/T8eAqO8Qm5tfrNxHRu/kmfJdldgCAHjluju0rV71D60t2DJ7NXkT81uyw7JVmLt7LqE/eoF36+hwKwI4p8AAoWR9XPl5Ox4P32SE2Mb9ej8Iqef7eMjsAQE9cNAVB6T6H47j74DwO7np3/9gU7P8Kc/HapsoOAEA/KPAAKNLZzXoUEaPkGLu2jMKP0plfr/fCizYAyHbbHNFXtoO7j+FFep8cxcGduXi0wWhyuurV5xCAHAo8AEpVZQdIUPzcu4gw964d/nd2AADS3EfEYXaIjdVHKjqOu3+qqI/U7N39ZFO6n2Tn4L+q7AAAdJ8CD4BSvcgOsGPH0/Gg6KNz5tfro4g4So5BrXcvvQD4r8PFbLjMDrGRurz5mB2DNKOI+NLTuXifIuJ1mIvXBubgAfDsFHgAlKrKDrBDF9Px4CI7xCbm12sv2gAg38liNrzKDrGR+vjE83Acd9/Vn4ODu/fZQXat+T38MszFy2ZBHADPToEHQHHObtZ70Z8Hptso/Kgcc+/4QVaUAzyPy2b3TunOoz/3gfyzX+Pg7nMP5+Ito96Jd5GbpNeq7AAAdJ8CD4AS9eWlzX3UR2eWXmicR33UEfyjxWxoNTnA9t1GxHF2iI3Vu63eZMegdd5EfaRmX54RIiJiMRvem4uXa3K6qrIzANBtCjwASlRlB9iRLsy9exdetAFApvuIOF7MhmUvCDq4qyLi1+wYtNZ+1CVelR1k18zFS9Wr0hiA3VPgAVCiPgwM/zQdDy6zQ2xifr2uwtw7AMh2XPzu5oO7UdTHccO37EVd4r3LDrJrzVy812Eu3q714bkUgEQKPABK1PWVjrfT8aDoo3CezL2jnarsAADsxKfFbFj0gqBmtplZuvyIj3Fwd97DuXi3UZd4Zf+eL0uVHQCAblPgAVCUs5v1fnT7Bc591A/epfOiDQByXS1mw6IXBDU+RvcXb7F9R1HvxuvV/WgzF+8wIj5kZ+mJvcnpapQdAoDuUuABUJoqO8AzO5yOB0XPr5hfrz9G93+deF5F/x4AaIFlRBxmh9jYwd1R1EUM/Iz9iPhPHNz1rgBezIbvo/4zwD3V86uyAwDQXQo8AErzIjvAM/owHQ+uskNsYn69fhMRvZs7wtaZ3wKwmcPFbFj2i/u6dDnPjkHx9iLit6YM7pXm+Fxz8Z5fl59PAUimwAOgNFV2gGdyOR0P3meH2MT8ej0KL9oAINtxMwurXPWxh1+yY9Ap53Fw17v71Cdz8a6So3RZlR0AgO5S4AFQjLOb9V5EjLJzPINlRBxnh9jE/Hq9F+beAUC2i8VseJEdYgvcU/AcjuLg7reezsV7HRGfsrN01P7kdNWrzxQAu6PAA6AkVXaAZ1L83LuI+Bj1nBEKMb9e+/UC6JbbxWxY9IKgiIg4uDNLl+e0H/WRmr27D1rMhidRLxos/bmjjXr3eQJgNxR4AJTkVXaAZ3A8HQ+KPuZqfr0+ioij5Bj8OCuFAbrjPiIOs0NsrJ5TZpYuz20UEV96OhfvIuojNZe5STqnyg4AQDcp8AAoSddWNl5Mx4OL7BCbaHZxfczOAQA9d7iYDZfZITZS74hyT8Gu7EU9F693n7lmLt7LMBdvm7q40BSAFlDgAVCSKjvAFt1GxEl2iE2Ye8cz+nd2AICCnCxmw6vsEBupZ5Kdh3sKdu9dHNx97vFcvIvsLB1RZQcAoJsUeAAU4exmXWVn2KL7qI/OLH3+xHnURxABADkuF7Php+wQW3Ae3TtpgXK8ifpIzd59Bpu5meXPzmyByemqd58fAJ6fAg+AUlTZAbbopANz795F/bIDAMhxG1148X5w9z7cU5BvP+oSr3efxWYu3suoFxny86rsAAB0jwIPgFK8yA6wJZ86MPeuCjNqumCUHQCAn3YfEceL2bDsF+4Hd1VE/JodAxr18fAHd++yg+xaMxfvX1EvDODndOV5FYAWUeABUIoqO8AW3E7Hg67MvaN8o+wAAPy04+aFe7mz1RAdAAAgAElEQVQO7kbhnoJ2+hgHd+c9nYv3MszF+1lVdgAAukeBB0Drnd2sR1GviC3ZfUQcZofYgs9R/q8FAJTs02I2vMwOsZG6GHFPQZsdRX2k5ig5x86Zi/fTRpPT1Sg7BADdosADoARVdoAtOJyOB8vsEJuYX68/Rjd+LWi/sneVADyfq8VsWPRu/sbHqGeOQZvtR8RvcXDXu8+quXg/rXefFQCelwIPgBK8yg6woQ/T8eAqO8Qm5tfrNxHRu3kgpPGyCODPltGF3fwHd0dR726CEuxFXeIdZQfZteaY3pdhYdWPKP25FYCWUeABUIKSVzJeTceD99khNjG/Xo8i4jw7BwD03OFiNix7gUO9k8k9BSU6j4O73n12F7PhMiJeh7l436vKDgBAtyjwAGi1s5v1XpRb4C2j8JXy8+u1GTXd9Ut2AAC+23GzG6Zc9dy7L9kxYANHcXD3W/NZ7o3FbHjfzMXrwvG9z63U51YAWkqBB0DbVdkBNnA4HQ/KXilvRk2XjbIDAPBdLpp5VKWzIIgu2I+I//R0Lt6nqHfjlf5886wmp6sqOwMA3aHAA6DtSn04PpmOB0WvlJ9fr4/CjBoAyHTb7Hwp28Hdxyh7URY8Ve8m7edcvKswF++fVNkBAOgOBR4AbVfiIPCL6XjwKTvEJubX6/2od99BhmV2AIAWuI/Cj+KOiGhKjnfZMWDL9qKei9e7++Unc/Euk6O01YvsAAB0hwIPgLarsgP8oNsofD5EM/fuPBxzRZLmxRBA3x0W/+dhfcxg7woOeuVdHNx96elcvMOI+JCdpYWq7AAAdIcCD4DWOrtZl3Z85n1EHHdg7t15lHt0KQB0wUlzVF256kLDgiD6oIr6SM3e3T8vZsP3Ue8ULv35Z5v2Jqer3n0WAHgeCjwA2qzKDvCDujD37l1EvMnOwU54oQrQTpeL2bDoo7gbFgTRJ/tRl3i9u49ezIaXUR+pWfRz0Jb5sw+ArVDgAdBmJc2/+zQdDy6yQ2zC3Lve8WIBoH1uI+I4O8TGDu7ehwVB9M9eRHxuPv+9spgNb8NcvKdKeo4FoMUUeAC0WSkFw+10POjC3Lsv2TkAoMfuI+J4MRuWfRTdwV0VEb9mx4BEv8bB3XmP5+J1YQfxpkp5jgWg5RR4ALTS2c16FBGj5Bjf4z7quQ+l+xyOVKRdltkBAHbsuNnFUq6Du1HU9xTQd0dRH6k5Ss6xc4vZ8CTqncRlL0bYzP7kdOXZCoCNKfAAaKtSVi0eTseDZXaITcyv1++jvHmDdN8yOwDADn1q5kiVq95tZEEQPNqPiN+aXam9spgNL6I+UnOZmyRVlR0AgPIp8ABoqxLmBnyYjgdX2SE2Mb9evwnHXAFApqtmx0rpPkY5C7BgV+pj6g/ujrKD7Fqzo/hlRFwlR8niz0MANqbAA6CtquwA/+BqOh68zw6xifn1ehQR59k5AKDHltGFo7jrcuIoOQW02Xkc3PXuvruZi/c6+jkXr4QFqQC0nAIPgLZq84rFZXThZZtjrnpvfr2usjMA9NzhYjYse07Uwd1+WBAE3+MoDu5+a46b7ZUnc/H6pMoOAED5FHgAtM7ZTetLhcPpeFD0y7b59fo82l2SAkDXHTdHzJWrLiK+ZMeAguxHxH+a4rtXmrl4LyOi6OeoHzE5XVXZGQAomwIPgDaqsgN8w8l0PCj6Zdv8en0Ujrmi/XrzcgfopYvmZXbp7OaHH7cXEb/1eC7evyKi6OepH9C7ohaA7VLgAdBGbZ0XcDEdD4qe3zC/Xu9HxMfsHPAd7rIDADyT28VsWP5Rcgd3H6Pdi66g7c6b30e90szFexkRF9lZdqCtz7UAFEKBB0AbtXGl4m1EnGSH2MT8er0X9YwaK+UBIMd9dGGObr1z6F12DOiAd3Fw96Wnc/GOo/tz8dr4XAtAQRR4ALTK2c16P9pXMN1HxHHpc++iLu88RAJAnsPFbLjMDrGRenZX73YNwTOqoj5Ss3f36T2YizeanK5G2SEAKJcCD4C2aeODaxfm3r2LiDfZOWidNv5+A+iqk8VseJUdYiP1LiG7+WH7RhHxJQ7uene/3oO5eFV2AADKpcADoG3aNifg03Q8uMgOsQlz7/gGL2ABduNyMRsWPUe3YTc/PJ+9iPgcB3fvs4Ps2mI2vI+I19HNuXgvsgMAUC4FHgBtU2UHeOJ2Oh50Ye7dl+wcANBjt9GFOU91qdC73UH8/+zdP3IbWZ4u7BcRn5kRlzu4nA0QpK1ADNUuHHEFIHwZotlWSVaaYjDaJ7gC0YGb4g1G20WsYHh3wBvRPj8jUTPV1V1VkvDnIDOfx5nuKol8WyMCyPOec34U8FOmqy9Dm4vX1NXLei5ep5+//o3z0gEA6C4FHgAH429/fz1Ke33MIXhJclE6xBZ8iVNWdNND6QAAW/CSZL4+XdJd09V5kp9Kx4ABeZf2Ss3j0kH2bX1a+W36Mxfv9C9//YfnMQB+iAIPgENyXjrAr8zfvxk9lw6xibvH1485rD9TABia+Xq+U3e1BcKX0jFggE6T/Lwu0AdlPS/0LP2Zi+fqYQB+iAIPgENyKA82n96/Gd2XDrGJu8fXd7FTHgBKum7qqtOfJ9ZX+DnND+W01+FPVx9KB9m3pq6e05+5eOelAwDQTQo8AA7Jf5YOkOTh/ZvRx9IhNnH3+Hqc5LZ0DjphXDoAQE89NHXVhzlOn3M4G6xgyD5nuhrc5/tfzcX7VDrLhg7hOReADlLgAXBIzgt/f3PvGBp/TwC27zl9+DwxXV0muSycAvgfl5mufl6fjB2Upq4+pn1d7epcPBshAPghCjwADsLf/v56XjpDkrfv34y6+lCYJLl7fL2NB0QAKOmiqatOf57IdHUap/nhEJ0m+a/1z+igrK8kfptuzsU7+stf/zG4/58BsDkFHgCHovQDzdX7N6MuPgz+t7vH18vYKU9/dPrnERiseVNX3X79ak/3fC0dA/hdR0l+Xp+SHZT16+vbJF2cL3peOgAA3aPAA+BQlJwLcP/+zei64Pff2N3j62naOTXQC50/vQIM0aKpq0XpEFvgKm7ohtsBz8W7SPfm4pk9DcB3U+ABcCjOC33fpyTzQt97K+4eX4/SXnNlsQ0Aynhq6qrTnyeSJNPV5zglAl1ymenq64Dn4s3Tnbl456UDANA9CjwAivvb31+PU6Z8ekky7/rcu7TlXekrSOmm49IBAHrgJclF6RAba6/j+1A6BvDdztNeqTm454H1qee3SZ7LJvkmx3/56z8GV7QCsBkFHgCH4LzQ9+3D3LsPSd6VzkFnHZcOANADF01dPZcOsZF24d9V3NBdx0m+Dngu3lmSh8JRvsV56QAAdIsCD4BDUGIewOL9m9GiwPfdGnPvAKC4q6auHkqH2Eh79Z6ruKH72p/l6epj6SD7tp6L9zbJoc81Lzn3HYAOUuABcAjO9/z9nt6/GXV6Ts167t2X0jlgxzp9Qhbovfumrg59sfhbuIob+uWnTFdfBjoX7yqHPRfPay0A30WBB0BRf/v761H2+yDTjzk1bXl3XDoE7NihLr4APKVdJO629qSOq7ihf96lvVJzcIXRgc/FOy8dAIBuUeABUNq+Hyrn79+Mnvf8Pbfq7vH1Yzz8AUApL0nmTV11e5PBdHWe5KfSMYCdOU1b4p2XDrJvv5qLd3C3Ofzlr/84L50BgO5Q4AFQ2vkev9en929G93v8flt39/h6HottbNH6OlYAvt18vTjcXdPVcVzFDUNwlLbE+1A6yL6t5+KdJVmUzvIb56UDANAdCjwAStvXIO+H929GH/f0vXbi7vH1OBbb2L7BXa0EsIHrpq46vRloPRfrS9qFfWAYPme6uh3oXLx5DuvK43HpAAB0hwIPgNLO9/A9+jT3bnAP3QBwIB6auroqHWILPsfmDRiiy7Sn8Qb3PLGei3eWw5ivfF46AADdocADoJi//f11X4tHb9+/GR3Cw9oPu3t8tdjGED2XDgCw9pw+bAaari7TLuIDw3Sa5L8yXQ3uuWJ99fF/pPxcvKO//PUfx4UzANARCjwASjrfw/e4ev9mVPohbSN3j6+XSQY3twKS/N/SAQDWLpq66vRmoPWC/W3pGEBxR0l+Xhf6g3JAc/HOC39/ADpCgQdASbu+///+/ZvR9Y6/x07dPb6epr3qCgAoY74+udFd7ZV5X0vHAA7KbaarQZb667l4Ja9E3tcceAA6ToEHQEnnO/zaTzmsYeXf7e7x9SjtTvnBzakAgAOxWM9O6jpzdIF/5zLT1c8DnYt3neRtyszFG9wVpgD8GAUeAEX87e+vx0mOd/TlX5LMuz73Lu3JOw937Np56QAAB+ppfUqj26arz/FaD/y+07RXag7uuaOpq4ckZ9n/XLzTv/z1H4MrTQH4fgo8AErZ5QNiH+befUhyWToHAAzUS5KL0iE21s64MkcX+DPHSb4OdC7ec9qTeIs9f+vzPX8/ADpIgQdAKbu693/x/s1osaOvvRfm3sF/6/opWqC7LtaLut3VnqbxeQL4Vu31/e2p3UFp6uqlwFy8wZ14BOD7KfAAKGUXDyxP79+MOn3V1Xru3ZfSOeBAdPokLdBZV+tr1bqrnWdlji7wIz5kuvoy4Ll4F9nPJrJdbWgFoEcUeACUcr7lr9ePq67a8u64dAgAGKj79QJu193G6Q7gx71Le6Xm4F5Hmrq6T3ul5q43kp3v+OsD0AMKPAD27m9/fz3fwZedv38zet7B192bu8fXj/EgBwClPCXp9En+JMl09THt4jvAJk7TlniDez1p6uopbYl3v8vv85e//mNwBSkA30eBB0AJ51v+ep/evxnt9OFq1+4eX8+T/FQ6B4Pk+h6A9iT/vKmrbs/enK7O4/MEsD3t9f7T1YfSQfZtPRfvIsmnHX6b8x1+bQB6QIEHQAnjLX6th/dvRh+3+PX27u7x9Tjm3gFASfP1iYvumq6O4/MEsBufM13dDnQu3sfsbi6ejXQA/CEFHgAlnG/p6/Rp7t3gHoYB4EBcr2cedVe7qO7zBLBLl2mv1DwunGPvdjgXzxWaAPwhBR4Ae/W3v7+eZnuLSxfv34w6fdXV3ePr53hwg3+rqauH0hmA3nto6uqqdIgt8HkC2IfTJD9nuhrc682v5uI9bPHLHv/lr/843uLXA6BnFHgA7Nu2Hvau3r8ZPWzpaxVx9/h6mWRw8yQA4EA8pw8n+aery7QnYwD24ShtiXdZOsi+refivU1yvcUvO7gyFIBvp8ADYN+2cc///fs3o20+NO3d3ePradrd8gBAGRdNXXX6JP/6FMxt6RjAIN1muhrk68/65PY825mLZw4eAL9LgQfAvm26w/A57cNSZ909vh6lXWwzp4ZDYNcvMETz9XVo3dXOvftaOgYwaJeZrn5evx4NSlNXi7RXaj5v+KXON80CQH8p8ADYm7/9/fUom5UFL+nB3LuYU8NhGdyCCzB4i/XCa9d9iddwoLyhz8U7y2Zz8Qb35wbAt1PgAbBP5xv+/qv3b0ad3i1/9/j6IebUAEApT01ddfokf5JkuvocpzaAw3Gc5OvA5+ItfvRr/OWv/zjfWiAAekWBB8A+bbK7cPH+zWixrSAlmHsHP+ShdACgN16SXJQOsbF2gfxD6RgAv9GOCWg3GAzOenPIj24QOd9iFAB6RIEHwD796IDupyRX2wyyb+u5d19K5wCAAbto6uq5dIiNtFfUDXJxHOiMD5muvg54Lt5Z2g0j3+NHn5MB6DkFHgD7dP4Dv6cvc+++pL1aBgDYv6umrh5Kh9hIuxh+G3PvgMN3nvZKzcHNd1vPxfuPtJtQv9Xg/pwA+DYKPAD24m9/fz3/wd86f/9m9LzFKHt39/j6Ma5F4YDdPb4el84AsEP3TV1dlw6xBbexyAt0x2naEu9d6SD7tp6Ld5Zvn4t39Je//sPrOwD/QoEHwL78yAPJ9fs3o/utJ9mju8fX8yQ/lc4Bf+K4dACAHXnKj88kOhzT1cckg1sEBzqvHSPQvoYNznfOxVPgAfAvFHgA7Mv33uv/8P7NyNw7AOBHvSSZN3XV7Wu4p6vz2AwEdNtPma5uBzwX723+fC6eOXgA/AsFHgD78j07Cl+SXOwqyB59jTk1sKnvmR8C8Gvz9Syi7pqujmMzENAPl2mv1DwunGPv1jNYz/LHn2vP9xIGgE5R4AGwc3/7++txvu+Kvov3b0ad3i1/9/j6Oa5BgW34f6UDAJ103dRVp6/hXp9U+RKbgYD+OE3y8/pk8aA0dfWc9iTe4nd+yfFf/voPr/cA/BMFHgD7cP4dv/bq/ZvRw45y7MXd4+u7JB9K5wCAgXpo6qrT13Cv2QwE9NFR2pN4l6WD7FtTVy/ruXi/9x51vsc4AHSAAg+AfRh/46+7f/9mdL3TJDt29/h6muS2dA74Tnb7An3xnD5cw90ubF8WTgGwS7eZrgb53NTU1XX+/Vw8mzYA+CcKPAD24fwbfs1zkvluY+zW3ePrUdryThlC11gsAPrioqmrTl/DnenKZiBgKC4zXf28vjJ4UH5nLt5/lkkDwKFS4AGwD39WDrykB3Pv4qorAChp3tTV05//sgPWLmJ/LR0DYI9Ok/zXevPCoPxqLt4vM1vPi4UB4CAp8ADYqb/9/fX8G37Z1fs3o04vuN09vl7GVVewC8+lAwCdsGjqalE6xBZ8iZP8wPAMfS7eRZJPSfKXv/7jvGwiAA6JAg+AXTv/k3+/eP9mtNhDjp0x9w526rl0AODgPTV11elruJMk09XnOH0BDFc7jqB9LRycpq4+pp3helw2CQCH5P8rHQCA3vuje/yfklztK8gurOfefSmdAwAG6iXtgme3tadOPpSOAXAAPqyv07zIctz1EQvfpamr+z//VQAMiRN4AOza780y6Mvcu9vYJUn3/a/SAQB+0MV6hlB3tQvVgzxxAvA7zpP8PMS5eADwawo8AHbmb39/Pc3vz3GZv38zet5jnK27e3z9mORd6RywBRZHgC66aurqoXSIjUxX7ZVx5t4B/NZx2rl4nrcAGCwFHgC7dP47//z6/ZtRp68HuXt8PU/yU+kcADBQ901dXZcOsQW3sYkC4Pe04wqmq4+lgwBACQo8AHZp/G/+2cP7NyNz74Bv1fVrdoHte0oyLx1iY+2CtJMlAH/up0xXX9anlgFgMBR4AOzS+W/++0uSiwI5tu1rXHUFe9HU1VPpDMBBeUkyb+qq2+X+dHUeJ/kBvse7tFdqHpcOAgD7osADYCf+9vfXo7RzC37t4v2bUacX3O4eXz/HVVcAUMq888V+u/jsJD/A9ztN8vN6EwQA9J4CD4BdOf/Nf796/2b0UCDH1tw9vr5L8qF0DgAYqOumrjo9Q3d9/duXOMkP8KOO0p7E81wGQO8p8ADYlf/81X++f/9mdF0syRbcPb6eJrktnQN25Lx0AIA/8dDUVadn6K45yQ+wHZ8zXXk+A6DXFHgA7Movi1PPSeYFc2zs7vH1KG15Z7c8AOzfc/owQ3e6ukxyWTgFQJ9cZrr6eX26GQB6R4EHwK6cr/9v5+fexW55KK3rryHAZi6auur268B05SQ/wG6cJvmv9essAPSKAg+Arfvb31/P1/9x/v7N6Klklk3dPb5exm55KK3TryPARuZNXXX7NaA9GfK1dAyAHjtK8vP6pDMA9IYCD4BdOE+yeP9mtCicYyPm3gFAUYumrhalQ2zBl7iGG2AfbjNdfS4dAgC2RYEHwK5clQ6wifXcuy+lcwDAQD01ddXpGbpJsl5IPi8dA2BAPmS6+mouHgB9oMADYOvevxl97MHcu9skx6VDwL6sT5wCHIKXJBelQ2ysvcrtQ+kYAAN0nvZKTZ9vAeg0BR4A/Mbd4+vHJO9K54A9s0sZOBQXTV09lw6xkXbR2DVuAOUcJ/lqLh4AXabAA4BfuXt8PU/yU+kcADBQV01dPZQOsZH22rbb2BgBUFr7ejxdfSwdBAB+hAIPANbMvYOD9X9KBwD24r6pq+vSIbbgNolr2wAOx0+Zrr6YiwdA1yjwAOB/fI3d8gBQwlOSeekQG2tPebiGG+DwvEt7paYNFgB0hgIPAJLcPb5+jt3yAFDCS5J5U1cvpYNsZLo6j2u4AQ7ZadoS77x0EAD4Fgo8AAbv7vH1XZIPpXNAYcelAwCDNW/q6ql0iI1MV8dxDTdAFxylLfE8/wFw8BR4AAza3ePrcdpZNTB0x6UDAIN03dTVfekQG2lnKn2Ja7gBuuRzpqtbc/EAOGQKPAAG6+7x1YIbAJTz0NTVVekQW+AaboBuukx7Gs/zIAAHSYEHwJBZcINu6PbVesC/85zkonSIjU1Xl2kXgAHoptMk/5XpynMhAAdHgQfAIN09vl7Gght0xUvpAMDWXTR11e2f7Xax1zXcAN13lOTn9aYMADgYCjwABufu8fU07ek7AGD/5k1ddftkbXvd2tfSMQDYqttMVzZmAHAwFHgADIq5d/C7/nfpAMAgLJq6WpQOsQU+SwD002WmK3PxADgICjwAhuY2yXHpEHCAjksHAHrvqamreekQG5uuPic5Lx0DgJ05T3ulprl4ABSlwANgMO4eXz8keVc6BwAM0EuSi9IhNtbOR/pQOgYAO3ec5Ku5eACUpMADYBDuHl/PY+4ddNVz6QDAxi6aunouHWIj7UkMnyUAhuMo7Vw8r/0AFKHAA6D3fjX3Duigzi/6A1dNXT2UDrGRdhbSbcy9AxiiD5muvpiLB8C+KfAAGIIvseAGACXcN3V1XTrEFtwmMQsJYLjepb1S03sBAHujwAOg1+4eXz+nHUIO/DElN7BtT0nmpUNsbLr6GDN0AWg3cnzNdOU9AYC9UOAB0Ft3j6/vknwonQM6wm5iYJteksybunopHWQj09V5kp9KxwDgYLTjGaYrz5kA7JwCD4Beunt8PU573RUAsH/zpq6eSofYyHR1HDN0Afj3Pme6ujUXD4BdUuAB0Dt3j6/trkhXAkKfPJcOAHyz66au7kuH2Ei7IOuzBAB/5DLtlZrHhXMA0FMKPAD66HNcBwh981w6APBNHpq6uiodYgt8lgDgW5wm+TnTlfcMALZOgQdAr9w9vl6m3QkJAOzXc5KL0iE2Nl1dxmcJAL7dUdoS77J0EAD6RYEHQG/cPb6ept0xDwDs30VTVy+lQ2ykPUFhhi4AP+I205X3EAC2RoEHQC+Yewebu3t8PS+dAeiseVNXT6VDbKSde/e1dAwAOu0y09XP6/cUANiIAg+AvrhNclw6BAAM0KKpq0XpEFtgIxAA22AuHgBbocADoPPuHl8/JHlXOgewU92+lg/666mpq3npEBubrj4nOS8dA4DeOE7y1Vw8ADahwAOg09ZX/pl7B/23Kh0A+BcvSS5Kh9hYu7j6oXQMAHrnKO1cPM+rAPwQBR4AnfWruXcAwP5dNHX1XDrERtrrzSysArBLHzJdfTUXD4DvpcADoMvMqgGAMq6aunooHWIj7ULqbXyWAGD3ztNeqWkuHgDfTIEHQCfdPb6aVQPbZ0EB+Bb3TV1dlw6xBbfxugfA/pymLfHMbwfgmyjwAOicu8fXdzGrBnbBKRTgzzwlmZcOsbHp6mMSC6gA7Fs7BqJ9HwKAP6TAA6BT7h5fj9PumAcA9uslybypq5fSQTYyXZ0n+al0DAAG7adMV55rAfhDCjwAOuPu8bXdreiUEAzRQ+kAQOZNXT2VDrGR6eo47WcJAACAg6bAA6BLPsesGgAo4bqpq/vSITYyXdkIBMCheEpyVToEAIdNgQdAJ9w9vl4muSwcAwCG6KGpqz4sMtoIBMAheElykeW421dSA7BzCjwADt7d4+tp2kU3YLfGpQMAB+c5yUXpEBubri5jIxAAh+Eiy/Fz6RAAHD4FHgAHbT337jauu4J98HMG/NZFU1fdPiEwXZ2m/SwBAKVdZTl+KB0CgG5Q4AFw6G7juisAKGHe1NVT6RAbaefefS0dAwCSLLIcX5cOAUB3KPAAOFh3j68fkrwrnQM4CN0uEaB7Fk1dLUqH2IIvcboYgPKekvRhniwAe6TAA+AgmXsH/Frnr/CDbnlq6mpeOsTGpqvPSc5LxwBg8F7Szr3zeRaA76LAA+DgrOfeue4KAPavXWTsuunqMsmH0jEAIG1591w6BADdo8AD4BC57grKOC4dACjuoqmr59IhNjJdOcUPwKG4ynL8UDoEAN2kwAPgELlaBMo4Lh0AKOqqqauH0iE2Ml0dJbmNjUAAlLfIcnxdOgQA3aXAA+AQzdMO+QYA9uO+qas+LDLeJjktHQKAwXtKclU6BADdpsAD4ODMJqOXtCWek3jAryn2YTee0r7vdtt09THJu9IxABi8dp7scux5FoCNKPAAOEizyagfi4nANlkEge17STJv6qrbP1/T1XmSn0rHAIC05d1z6RAAdJ8CD4CDNZuM7pN8Kp0DAHps3tRVt0+3TlfHSb6UjgEASa6yHD+UDgFAPyjwADhos8noY5L70jlgKO4eX49KZwD25rqpq26/x05XR2nLO69dAJS2yHLch3myABwIBR4AXTCP2VewL6elAwB78dDU1VXpEFvwOV63ACjvKUkf3lcBOCAKPAAO3mwyeklb4nV7Pg8AHIbnJBelQ2xsurpMclk4BQC0z6vLsedVALZKgQdAJ8wmo6e0JR4wXM+lA0BPXDR11e1FxunqNMlt6RgAkLa8c2MMAFunwAOgM2aT0X2ST6VzAMX839IBoAfmTV11e5GxnXv3tXQMAEjyKctxt+fJAnCwFHgAdMpsMvqY5KFwDADookVTV4vSIbbgS5Kj0iEAGLz7LMcfS4cAoL8UeAB00UVcpQcA3+OpqavuX0U9XX1Ocl46BgCDZ8QDADunwAOgc2aT0UvaEq/b83vgMJ2XDgBs3S/vm902XV0m+VA6BgCD95J27p3nUQB2SoEHQCfNJqOnJFelcwBAB1w0dfVcOsRGpqvTJJ9LxwCAtOVdt+fJAtAJCjwAOhcSFQMAACAASURBVGs2GS2SXJfOAeyNXc7w/a6aunooHWIj09VRktuYewdAeZ+yHN+XDgHAMCjwAOi02WR0leShdA5gL+x0hu9z39RVHza63CY5LR0CgMG7z3L8sXQIAIZDgQdAH1wkeS4dAgAOyFOSeekQG5uuPiZ5VzoGAIPXj/dVADpFgQdA580mo5e0JZ7r9QCgfT+cN3XV7ffF6eo8yU+lYwAweC9p5951+30VgM5R4AHQC7PJ6CnJVekc0AP/WToAsLF5U1fdvnJ2ujpO8qV0DABIW951+30VgE5S4AHQG7PJaJGkD7N+AOBHXTd1dV86xEamq6O05d1R6SgADN6nLMfdfl8FoLMUeAD0ymwyukryUDoHABTw0NRVH06jf05yWjoEAIN3n+X4Y+kQAAyXAg+APrpI8lw6BLBdTV09lM4AB+w57ftft01Xl0kuC6cAgKck89IhABg2BR4AvTObjF7SLmIaMg7AUFw0ddXt973p6jTJbekYAAzeS9q5d91+XwWg8xR4APTSbDJ6StKHa8QA4M/Mm7p6Kh1iI+3cu6+lYwBA2vKu2++rAPSCAg+A3ppNRosk16VzQMeYOwXdsmjqalE6xBZ8SXJUOgQAg/cpy/F96RAAkCjwAOi52WR0leShdA7oEAvo0B1PTV11fz7PdPU5yXnpGAAM3n2W44+lQwDALxR4AAzBRZLn0iEAYIt+mffabdPVZZIPpWMAMHjPSbq/KQaAXlHgAdB7s8nol0VOQ8ih+x5KB4ADcdHU1XPpEBuZrk6TfC4dA4DBa58Xl2PPiwAcFAUeAIMwm4yeklyVzgEAW3DV1NVD6RAbma6OktzGtb0AlHeV5fipdAgA+C0FHgCDMZuMFkmuS+cAgA3cN3XVh/ey2ySnpUMAMHjXWY4XpUMAwL+jwANgUGaT0VUSuyvhD9w9vh6XzgD8W0/pw3ye6epjknelYwAweA9Zjt3SAsDBUuABMERvYx4e/JHj0gGAf/GSZN7UVbffv6ar8yQ/lY4BwOA9p52TDgAHS4EHwODMJqOXtCUeAHTFvKmrbp8gn66Ok3wpHQOAwXtJcpHluNubYgDoPQUeAIM0m4z6cQ0ZDE+3Cwz4MddNXd2XDrGR6eoobXl3VDoKAIN3leXYZ0oADp4CD4DBmk1GiySLwjGA7/P/SgeAPXto6qoP83k+JzktHQKAwbvOcrwoHQIAvoUCD4BBm01G8zjRA8Bhek4f5vNMV5dJLgunAICHLMd92BQDwEAo8ACgnYdn/gH8D1fcwWG4aOqq2+9P09VpktvSMQAYvOf0YVMMAIOiwANg8GaT0UvaEg9oueYOyps3ddXtE+Lt3LuvpWMAMHgvSS6yHHd7UwwAg6PAA4Aks8noKcm8dA4ASLJo6mpROsQWfIkTvQCUd5XluNubYgAYJAUeAKzNJqNFkkXhGMAfey4dAHbsqamr7m8oma4+JzkvHQOAwbvOcrwoHQIAfoQCDwB+ZTYZzZPYnQmH67l0ANih9oqvrpuuLpN8KB0DgMF7yHJ8VToEAPwoBR4A/Ku3aRdRAWCfLpq6ei4dYiPT1WmSz6VjADB4z+nDphgABk2BBwC/MZuMXtKWeDBU/6t0ABigq6auHkqH2Mh0dZTkNubeAVBWe6J9ObYpE4BOU+ABwL8xm4yeknR/BhH8mNPSAWBg7pu6ui4dYgtu4/UDgPKushwbiwBA5ynwAOB3zCajRZJF4RgA9Fs/NoxMVx+TvCsdA4DBu85yvCgdAgC2QYEHAH9gNhnN0y6uAofBVUj0yUuSeVNX3f57PV29S/JT6RgADN5DluOr0iEAYFsUeADw595GaQAHoakrhTp9Mu/83+np6jjt1ZkAUFI79w4AekSBBwB/YjYZvaQt8QBgW66burovHWIj09VRki9JjkpHAWDw3mY5tukSgF5R4AHAN5hNRv2YUQTAIXho6qoPV3x9TnJaOgQAgzfPctztE+0A8G8o8ADgG80mo0WSReEYsA/npQNAjz2nD1d8TVcfklyWjgHA4C2yHC9KhwCAXVDgAcD3uUpidycAP+qiqatuX/E1XZ2mPX0HACU9ZTl2SwoAvaXAA4DvsJ6Hd5F2SDpQhp8/umre1FW3N4G0c+++lo4BwOCZUw5A7ynwAOA7zSaj5/Th+jPorm4XIAzVoqmrRekQW/A1yVHpEAAM3tssxzZ1AdBrCjwA+AGzyegh7XWaAPBnnpq66v4VX9PV5ySnpWMAMHjzLMc2dAHQewo8APhBs8noOsmidA4ADtovVy9323R1meRD6RgADN4iy/GidAgA2AcFHgBs5iqu86OH7h5fnbKB7bho6uq5dIiNTFenST6XjgHA4D1lOe7+iXYA+EYKPADYwGwy+uVkhfkL9I0ZV7C5q6auHkqH2Mh0dZTkS7wmAFDWS5K3pUMAwD4p8ABgQ7PJ6Dl9uB4NgG26b+rqunSILbhNclw6BACD9zbLsU2TAAyKAg8AtmA2GT2kvU4T2L3/UzoA/ImnJN2/4mu6+pjkXekYAAzePMuxsQUADI4CDwC2ZDYZXSdZlM4BQFEvSeZNXXX7lMB09S7JT6VjADB4iyzHi9IhAKAEBR4AbNdV2pMXAAzTvKmrbr8PTFfHaa/OBICSnrIcd/9EOwD8IAUeAGzRbDJ6STsPr9snL8DMK/gR101d3ZcOsZHp6ijJlyRHpaMAMGgvSd6WDgEAJSnwAGDLZpPRc9oSD7rsuHQA6JiHpq76MAv1c5LT0iEAGLy3WY5tigRg0BR4ALADs8noIe11mgD033P6sHFjuvqQ5LJ0DAAGb57luNvXUQPAFijwAGBHZpPRdZJF6RzQQxZ0ODQXTV11+5TAdHWa9vQdAJS0yHK8KB0CAA6BAg8AdusqygbYtm4XJfTNvKmrbr/Ot3PvvpaOAcDgPWU5npcOAQCHQoEHADs0m4xe0l6rpnAA6J9FU1eL0iG24GuSo9IhABi0X56bAIA1BR4A7NhsMnqOh1G653+XDgAH7qmpq+6fEpiuPic5LR0DgMG7yHL8XDoEABwSBR4A7MFsMnpIe50mdMVx6QBwwPpxSmC6ukzyoXQMAAbvKsvxQ+kQAHBoFHgAsCezyeg6yX3pHABs7KKpq+fSITYyXZ0m+Vw6BgCDt8hyfF06BAAcIgUeAOzXPMlT6RDQcc+lAzBoV01dPZQOsZHp6ijJl5h7B0BZT3FLCQD8LgUeAOzRbDJ6SVvivZTOAl3V+ZNPdNl9U1d9OCVwG9fkAlBWex31cuy5CAB+hwIPAPZsNhk9pS3xAOiOfrx2T1cfk7wrHQOAwbvIcvxcOgQAHDIFHgAUMJuM7pN8Kp0D/oCr9eB/vCSZN3XV7VMC09W7JD+VjgHA4F1lOX4oHQIADp0CDwAKmU1GH5Pcl84Bv+O0dAA4IPOmrro9v3S6Ok57dSYAlLTIctyH66gBYOcUeABQ1jzttWwAHKbrpq66vdliujpK8iVO1gJQ1lOSq9IhAKArFHgAUNBsMnpJW+J1+1o22L/n0gEYhIemrvqw0Pg5TtUCUNZL2rl3nnsA4Bsp8ACgsNlk9JS2xAO+3XPpAPTec5KL0iE2Nl19SHJZOgYAg3eR5fi5dAgA6BIFHgAcgNlkdJ/kU+kcAPy3i6auun1KYLo6TXv6DgBKuspy/FA6BAB0jQIPAA7EbDL6mKTbc5YA+mHe1FW355O2c+++lo4BwOAtshxflw4BAF2kwAOAwzJPO9wdirt7fD0vnQEKWDR1tSgdYgu+JjkqHQKAQXtK0odZsgBQhAIPAA7IbDJ6SVvidfvaNoBuemrqqvszSaerz0lOS8cAYNBe0s6981wDAD9IgQcAB2Y2GT2lLfGA32cxiG1rFxq7brq6TPKhdAwABu8iy/Fz6RAA0GUKPAA4QLPJ6D7Jp9I54ICtSgegdy6aunouHWIL/rN0AAAG7yrL8UPpEADQdQo8ADhQs8noY5L70jkABuCqqauH0iG2YjmeJ1mUjgHAYC2yHF+XDgEAfaDAA4DDNk87/B2A3bhv6qpfC41KPADKeEpyVToEAPSFAg8ADthsMnpJW+KZ90UJp6UDwI71d+ZoW+L1838bAIeofW5Zjj23AMCWKPAA4MDNJqP+LjBz6I5KB4Adekkyb+qqvwuNy/Ei3j8A2I95lmM3hwDAFinwAKADZpPRfZJPpXMA9Mi8qav+LzS2Jd7bOMkNwO58ynJsdjcAbJkCDwA6YjYZfUzyUDgGHIqH0gHotOumroaz0LgcP0SJB8Bu3Gc5/lg6BAD0kQIPALrlIslz6RAAHfbQ1NVV6RB7115rdpZ27h8AbIOr/gFghxR4ANAhs8noJW2J5xQFwPd7TvsaOkzL8XPak3hKPAA29ZJ27p3nEgDYEQUeAHTMbDJ6SjK80yOUMC4dALbsoqmrYS80tgutb5MM5wpRAHZhvj7dDQDsiAIPADpoNhktklyXzkHvHZUOAFs0b+rKQmPSlnjL8UWSRekoAHTSpyzHNoIAwI4p8ACgo2aT0VWSh9I5ADpg0dTVonSIg7Mcz2MzCADf5z7L8cfSIQBgCBR4ANBtF2lnOsHQOEnFt3pq6mpeOsTBWo6vkvjzAeBbPMV7BgDsjQIPADpsNhm9pC3xhj3TicEZ/BwzvtUvr5H8keV4EQuyAPyxl7Rz73wGA4A9UeABQMfNJqOnJFelcwAcoIumrp5Lh+iEtsQ7iw0hAPx78yzHbkAAgD1S4AFAD8wmo0XMMWL7jksHgA1cNXX1UDpEp7QLs2+jxAPgn33KcnxfOgQADI0CDwB6YjYZXSV5KJ2DXjkuHQB+0H1TVzY1/Ii2xDuLOZMAtO6zHH8sHQIAhkiBBwD9cpHkuXQIgIKeYp7bZpbj57Qn8ZR4AMPmPRUAClLgAUCPzCajl7QlnuvPGALlAr/1kmTe1JXXwE0txy9pSzxXpgEM00vauXfeUwGgEAUeAPTMbDJ6SnJVOgfsgQUlfmve1JVid1uW45csxxdJFqWjALB38/W1ygBAIQo8AOih2WS0SGL+EzAk101dOS22C8vxPN5TAIbkU5Zj76kAUJgCDwB6ajYZXSV5KJ2Dbrt7fD0qnQG+wUNTV04e79JyfBVzkACG4D7L8cfSIQAABR4A9N1FkufSIei009IB4E88p32tY9eW40WUeAB99hyv8wBwMBR4ANBjs8noJe3CtllhQF9dNHXlNW5f2hLvLN5XAPqmfW5Yjr2+A8CBUOABQM/NJqOnJK6Wo4+eSweguHlTV0+lQwzOcvyU5G2UeAB9crV+fQcADoQCDwAGYDYZLZJcl84BW/Z/SwegqEVTV4vSIQarXeT9jyQWewG673p9whoAOCAKPAAYiNlkdBULrUA/PDV1ZUZPae01a2/jvQWgyx6yHLutAwAOkAIPAIbFlWdA1/0y25ND8D8l3qJwEgC+33O8pwLAwVLgAcCAzCajXxZa4Vudlw4Av3HR1NVz6RD8ynL8kuV4HiUeQJe0G2LajRgAwAFS4AHAwMwmo6ckrp4DuuiqqauH0iH4HW2J96l0DAC+ydV6nikAcKAUeAAwQLPJaBEnJeg+O8aH5b6pq+vSIfgTy/HH2CQCcOiusxwvSocAAP6YAg8ABmo2Gc2T2HVLl/n7Oxy9ODl8cnbz4eTs5rJ0jp1rF4XnUbIDHKKHLMdXpUMAAH9OgQcAw/Y2FliBw/aSZN7UVadfq07Obt4l+Zzk9uTs5kPpPDvXlnjeYwAOy3OSi9IhAIBvo8ADgAGbTUYvaRdYAQ7VvKmrTp+2PDm7OU5y+6t/9Pnk7Ob2d355f7SzlZR4AIfhJclFlmOvyQDQEQo8ABi42WTUi6vp2Jn/LB2AQbtu6uq+dIhNnJzdHCX5kuToN//qckAl3n/ElbcApV2tX5MBgI5Q4AEAmU1GiySLwjEAfu2hqas+zOj5nOT0d/7d5cnZzc/rkq+/2tMeb6PEAyjlen21MQDQIQo8ACBJMpuM5rG4ChyG5/RgRs961t3ln/yy0yRfB1TiLQonARiahyzHfdgQAwCDo8ADAH7NrCI6o6mrh9IZ2JmLpq46/Vp0cnZzmvb03bc4TfLz+vf013L8kuV4HiUewL48pwcbYgBgqBR4AMB/m01Gv5yQAChl3tRVp08Dr0/Tff3O33ac9iRev0u8JOsS71PpGAA995LkYn0CGgDoIAUeAPBPZpPRU5J56RzAIC2aulqUDrEFX5P8yJWYR2lLvHdbznN4luOP8V4DsEtXWY47vSEGAIZOgQcA/IvZZLSIK85o9f80EIfiqamrzhc6J2c3n7PZz81Rki8nZzeX20l0wJbjRdoSz+kQgO26Xr/GAgAdpsADAP6t2WQ0T2LXLj9yigi+V3vNV8etS7cPW/pytydnN9v6WoerXWA2fxVgex6yHF+VDgEAbE6BBwD8EYuqwD5cNHX1XDrEJtaz6z5v+ct+Pjm7ud3y1zw87RVvb5M8F04C0HW92BADALQUeADA75pNRi9pF1XhUD2UDsDGrpq6eigdYhMnZzdHSb5kNydWL0/Obm7X36O/2hLvLE5+A2zibZZjm+8AoCcUeADAH5pNRk9pZxQBbNt9U1fXpUNswW2S4x1+/cskXwdQ4v2yaUSJB/D95uvNEABATyjwAIA/NZuMFkkWhWMA/dKLzQEnZzcfk7zbw7c6zVBKvOX4LN5zAL7HYj1TFADoEQUeAPCtruJUxCDdPb4el85A77wkmTd11elrvk7Obt4l+WmP3/I0yX+t5+3123I8jxIP4Fs8rV8zAYCeUeABAN9kPQ/vIu3CO8NyXDoAvTNv6qrTGwJOzm6O016duW9HaU/iDaXEuyodA+CAmVcNAD2mwAMAvtlsMnpOW+IB/Kjrpq7uS4fYxPoayy9py7QSfinxLgt9//1Zjq/Tg6tWAXbk7Xp+KADQQwo8AOC7zCajhzgRweHo9CmuAXpo6qoPrx+f015nWdJRktuBlHiLOAEO8FvzLMc+BwFAjynwAIDvNpuMrmM2EYfh/5UOwDd7Tg9O8J6c3XxIclk6x6/cnpzdfCwdYueW4/u018Qp8QCSxXpzAwDQYwo8AOBHXcXpJ+DbXTR11enyZT137nPpHP/GTydnNyXm8e1Xe9LkbdoyGGContYzQgGAnlPgAQA/ZDYZvcSVZkNRas4X/TFv6qrThf967t3X0jn+wOXJ2c3tOmd/tSXeWWwgAYbpJe1GBgBgABR4AMAPm01Gz+nBlXj8qdKzvui2RVNXi9IhtuBrDr/MvkzydQAl3i8L2Eo8YGjerl8DAYABUOABABuZTUYPaa/TBPitp6auOn/N18nZzed0p8g+zVBKvOX4LOaxAsMxX59CBgAGQoEHAGxsNhldxyIqZTyXDsDv+uWa3U47Obu5TPKhdI7vdJrkv9Yz+/qtnQO1KB0DYMcWWY4XpUMAAPulwAMAtuUqrjNj/55LB+B3XTR19Vw6xCbWBdjn0jl+0FHak3hDKfGcBAf66mn9OgcADIwCDwDYitlk9MtpG3M5gKumrh5Kh9jE+grKLzn8uXd/5JcS77J0kJ1bjq+TWOAG+uaXmZ8AwAAp8ACArZlNRs/pwZV5/Iv/VToAnXLf1NV16RBbcJvkuHSILThKcjuQEm8RG0mAfnmb5dhrGgAMlAIPANiq2WT0EFeZ9U3/r+BjW57Sg1NQJ2c3H5O8K51jy27X/7v6bTm+T3taxYI30HXzLMeupweAAVPgAQBbN5uMrpMsSucA9uolybypq04XJydnN++S/FQ6x478dHJ2c1s6xM61C95vYy4r0F2L9aliAGDAFHgAwK5cxeIpu9fpsqhn5k1ddfpn/uTs5jjt1Zl9dnlydvNlPeOvv5R4QHc9ZTnu/Gl2AGBzCjwAYCdmk9FLzCJix7peGPXIdVNX96VDbGJdaH1JOzOu794l+TqAEu8lbYn3UDgJwLf65fMzAIACDwDYndlk9ByLENB3D01d9WHu5ecMa97jadoS77h0kJ1ajl+yHL+Na52BbrjIcvxcOgQAcBgUeADATs0mo4e012kC/fOcHpT0J2c3H5Jcls5RwGmSn0/ObvpfXLbX0S1KxwD4A1dZjh9KhwAADocCDwDYudlkdJ2k09frDdx56QAcrIumrjp9Te66vPpcOkdBR2lP4g2lxDNXCjhEiyzH16VDAACHRYEHAOzLPIl5ZdAf867PIFzPgPtaOscBOEp7Eu+ydJCdW44XUeIBh+UpbqsAAP4NBR4AsBezyegl7aJpp0/rcJD8ndq/RVNXi9IhtuBr2vKK1u2ASry38doBlPeSdu6d1yMA4F8o8ACAvZlNRk9x8oHt6/QpsA56auqq8z/HJ2c3n9POgOOf3a7/bPqtnTOlxANKu8hy/Fw6BABwmBR4AMBezSaj+ySfSucAfkh7UqDj1qfMPpTOccA+nJzd3JYOsXPL8VPaEs8mAKCEq/VmAgCAf0uBBwDs3Wwy+pjkvnQO4LtdNHX1XDrEJk7Obk6T9P+E2eYuT85uvqznBPaXEg8oY5Hl+Lp0CADgsCnwAIBS5rFg2hl3j6+uGuSqqauH0iE2sS6jvsTcu2/1LsnXAZR4L2lLvIfCSYBheEpyVToEAHD4FHgAQBGzyeglbYln/lA39HsBnz9z39RVH04K3CY5Lh2iY07TlnjHpYPs1HL8kuX4bZJF6ShAr7VXUbcbBwAA/pACDwAoZjYZPaUt8YDD1Yuf05Ozm49pT5Tx/U6T/Ly+frTfluN5lHjA7lxkOX4uHQIA6AYFHgBQ1Gwyuk/yqXQOOu3/lA7QYy9J5k1ddfqkwMnZzbskP5XO0XFHaU/iDaXE63xpDRycqyzHD6VDAADdocADAIqbTUYfk9yXzgH8i3lTV52eVbm++vG2dI6eOEp7Eu+ydJCdW44XUeIB27PIctyHq6gBgD1S4AEAh2Ke9qo+4DBcN3XV6WL95OzmKMmXmOG4bbcDKvHexqxWYDNPSa5KhwAAukeBBwAchNlk9JK2xLNQepiOSwdgrx6auurDYuPntPPb2L7bk7Obz6VD7Fx73Z0SD/hRL2nn3nkNAQC+mwIPADgYs8noKa4sO1THpQOwN89JLkqH2NTJ2c2HJJelc/Tch5Ozm/5fT7ocPyU5i1PiwPe7yHL8XDoEANBNCjwA4KDMJqP7JJ9K54ABu2jqqtMnBU7Obk7Tnr5j9y5Pzm6+rq8r7a92Af5tlHjAt7tan+IFAPghCjwA4ODMJqOPSTo9e4u9sqC+PfOmrjr957kukr6WzjEw50mGUOK9pC3xvD8Bf2aR5fi6dAgAoNsUeADAoZpHMcO36fRpsQOyaOpqUTrEFnxN0u8i6TCdpi3x+j1zcDl+yXJ8kWRROgpwsJ6S9GGOLABQmAIPADhIs8noJW2Jp5yB3Xtq6qrz8ydPzm4+py2SKGMYJV6SLMfzJE7XAL/Vfn5tT+wCAGxEgQcAHKzZZPSUtsSjvP9dOgA785LkonSITZ2c3Vwm+VA6BzlKW+Kdlw6yc8vxVbxHAf9snuXYDRIAwFYo8ACAgzabjO6TfCqdgxyXDsDOXDR19Vw6xCbWJ74+l87Bf/ulxLssHWTnluNFlHhA61OWYzMyAYCtUeABAAdvNhl9TPJQOAb00VVTVw+lQ2zi5OzmKMmXmHt3iG4HVOKdxZXPMGT3WY4/lg4BAPSLAg8A6IqLJM+lQ3CQnksH6Kj7pq76MMPrNk6IHrLbk7Ob29Ihdq69Mu9tlHgwRK58BwB2QoEHAHTCbDL6ZU6XxVH+SdevfyykF4uNJ2c3H5O8K52DP3U5oBLvLO3PFzAML2nn3vl8CgBsnQIPAOiM2WT0lOSqdA7ouJck86auOr3YeHJ28y7JT6Vz8M0uT85uvq6vPO2v5fg57Uk8JR4Mw3xd3gMAbJ0CDwDolNlktEjSh2v/uqbfi+7DMm/qqtOLjSdnN8dpr86kW86TDKHEe0lb4t2XjgLs1Kcsx37OAYCdUeABAJ0zm4yukjyUzjEwp6UDsBXXTV11erFxXf58iVK5q07Tlnj9fk1Zjl+yHF8kWZSOAuzEfZbjj6VDAAD9psADALrqIslz6RDQIQ9NXfXhCtrPUSh33TBKvCRZjudxahz6phdzZAGAw6fAAwA6aTYZvaQt8To9x4uteS4d4MA9p/156bSTs5sPSS5L52ArjtKWeOelg+zccnwVi/3QFy9p5975/AkA7JwCDwDorNlk9JSkDyeK2Nxz6QAH7qKpq04vNq5Pa30unYOt+qXEuywdZOeW40WUeNAH8yzHnZ4jCwB0hwIPAOi02WS0iOvJ4I/Mm7rq9GLjeu7d19I52JnbAZV4Z3FyHLrqU5bjTs+RBQC6RYEHAHTebDK6SvJQOgccoEVTV4vSIbbga9rTWvTX7cnZzW3pEDvXntx5GyUedM19luOPpUMAAMOiwAMA+uIirlHcqbvH1/PSGfguT01ddf7KvpOzm89JTkvnYC8uB1Ti/UeSTp+MhQF5iitwAYACFHgAQC/MJqOXtCWeUw3Q/hxclA6xqfW1ih9K52CvLk/Obn5eX5vaX8vxS9qTeEo8OGwvaefe+XwJAOydAg8A6I3ZZPSU5Kp0DoqwsPbPLpq6ei4dYhMnZzenST6XzkERp0m+DqjEWxROAvy++frULADA3inwAIBemU1GiyTXpXOwd6vSAQ7IVVNXD6VDbGJd3HyJuXdDdprk53WR21/L8UuW43mUeHCIPmU5vi8dAgAYLgUeANA7s8noKslD6RxQwH1TV30osG+THJcOQXHHaU/i9bvES7Iu8T6VjgH8t/ssxx9LhwAAhk2BBwD01UWS59IhYI+eksxLh9jUydnNxyTvSufgYBylLfH6/3eiLQs6/zMMPfAcP4sAwAFQ4AEAvTSbjF7Slnhmo21P/0/BdNdLknlTV53++74uaX4qnYODc5Tky8nZzWXpIDu3HC/SFged/lmGDms/P7YzKgEAilLgAQC9NZuMA/0nVwAAIABJREFUnpJclc7RI+aRHa55U1dPpUNs4uTs5jjt1Znwe25Pzm4+lA6xc22J9zZKPCjhKstxp99PAYD+UOABAL02m4wWSfowEwx+z3VTV/elQ2zi5OzmKMmXKIn5c59Pzm76X/S2BYISD/brel2gAwAcBAUeANB7s8noKu18MPrroXSAQh6auurDKdPPcUUr3+5yQCXef8T7F+zDQ5bjPryfAgA9osADAIbCSQb65jntnMdOW1+JeFk6B51zeXJ28/P69GZ/tXO43kaJB7v0nB68nwIA/aPAAwAGYTYZ/bIICn1x0dRVp0vpk7Ob07Sn7+BHnCb5OqASb1E4CfTRS5KL9c8ZAMBBUeABAIMxm4yeksxL5+iwcekA/Ld5U1edPpGzLl2+ls5B550m+XldBvfXcvyS5XgeJR5s29X6uloAgIOjwAMABmU2GS1iAfRH9fuUS3csmrpalA6xBV/j7xTbcZz2JF6/S7wk6xLvU+kY0BPXWY4XpUMAAPweBR4AMDizyWge84Topqemrjp/ivTk7OZz2pNTsC1HaUu8d6WD7Nxy/DFOk8OmHrIcX5UOAQD8/+zdQVIbeb4u7JcTd6iIw7eCy92AhBZANDA9g4YVCCY57DZDRnaNNMSlIRPUK7DPQFPBibMA072B4qzgciOY9zfIpMpV7SobI+mvzHyeCIerXC7xGgTC+ebv/+OPKPAAgL46Sr33hG7oQyFb7+lpueF4dpbkTekcdNJukg/Nc6zb6qmh83gdg+/xkA68ngIA3afAAwB6aXKw85i6xKMDltNBHy5iny6ng4fSIV6jOeLwqnQOOu9mOJ51vySuSzw3o8DL1DfDLEY+bwCArafAAwB6a3Kwcx/HkNEOF8vp4K50iNcYjme7ST7E3js242o4nt2UDrF2i9F96hLvoXASaIuL5vMGAGDrKfAAgF6bHOzMk8wLx2iLvdIBeurjcjp4XzrECtzEc4jNOhuOZzdNedxddRkxTj+OEobXeN9MrgIAtIICDwDovcnBznlc+PwWe6UD9FAnpkSH49m7JCelc9BLZ0lue1DiPR8L7bUMvuwui9FF6RAAAC+hwAMAqNkjxLZ5THLe9v1+w/HsJMnb0jnotf30pcRbjMYxVQ6/9ZDktHQIAICXUuABACSZHOw8Ty/QXl2bPDlfTget/jMNx7O91EdnQmn7SX4ajmf7pYOs3WJ0HiUePHtMctpMqQIAtIoCDwCgMTnY6cRxhT3WpYtz75fTwcfSIV6jmXb6kKTbU0+0yW7qSby+lHiOC4TkotkTCQDQOgo8AIDPTA525jG5QFl3y+mgCxfer1JPPcE2eS7xzkoHWbvF6H3clEK/vc9iNC8dAgDgeynwAAB+Y3Kwc57uHce4En/773+aplqvh3RgT89wPHuT5Kx0Dvgdu0luelLizVN/TenShDJ8i7ssRl24GQYA6DEFHgDAlx3FBc8vMVG1XqfL6aDVz7vmeMKr0jngG9wMx7N3pUOs3WL0MV7T6Jd67x0AQMsp8AAAvmBysPOY+oInbMr5cjpo9eRns/futnQOeIG3w/HspnSItat3gB2lnvKFrjvKYqSwBgBaT4EHAPA7Jgc797E/qE0eSgd4hflyOpiXDrECt6mPJ4Q2ORuOZzdNAd1ddYk3jiOi6bbz5rkOANB6CjwAgD8wOdiZJ5kXjsG3+Z/SAb7T/XI6aH1RPBzPruKIVdrrLMltD0q85+lyBQddNG/2PgIAdIICDwDg6y7iYifr0Yk9PcPx7CzJm9I54JX205cSbzEax80pdMt9FqPW3wwDAPA5BR4AwFc0+/BOU5ctsEqny+ngoXSI1xiOZ/tJrkrngBXZT/JT87zutrrsmJeOAStgbzEA0EkKPACAbzA52HlIByalVuCwdIAOuVhOB3elQ7xGM6n0Ifbe0S27qSfx+lLiXZSOAa901BwPCwDQKQo8AIBvNDnYuYsLnazGx+V08L50iBW4SbJXOgSswXOJd1Y6yNotRu+TOHqQtjrPYuSYcwCgkxR4AAAvMDnYeR9Hjm2rttx9f58OXCwfjmfvkpyUzgFrtJvkpicl3jyOiqZ95s1zFwCgkxR4AAAvd5G6hGG7tOFj8pjkfDkdtPoi+XA8O0nytnQO2JCbprDutsXoY+o9Yq3++kRv3DdHwAIAdJYCDwDghSYHO48xqcD3OV9OB20oGn/XcDzbS310JvTJ2+F41v3nfX0U4VHacUME/fWY+nkKANBpCjwAgO8wOdh5SF3iwbd6v5wOPpYO8RrD8Ww3yYfURwtC35wNx7MPzedBdynx2H5HWYzcRAUAdJ4CDwDgO00Odu5SH6fZJ38qHaCl7pbTQReeK1dJ9kuHgIJOktz2oMR7nnC6K5wEfuu8KZkBADpPgQcA8AqTg533Sealc7DVHtKBac3hePYmyVnpHLAF9lOXeHulg6zVYvSYxegoXuPYHvMsRvPSIQAANkWBBwDwehdx1Bi/73Q5HbT6qK/heLafevoOqO0n+dR8bnTbYnQeJR7l3TfPRQCA3lDgAQC80uRg5zH1hFWrS5q2W04Hd6UzfMH5cjpodbnbHBV4WzoHbKHd1JN4fSnxlCeU8nykKwBAryjwAABWYHKw85AOHJPISs2X08G8dIgVuE1dVAD/ajf1JN5Z6SBrVx9dqMSjhKNmLyMAQK8o8AAAVmRysHOX+jhNuF9OB62/0D0cz65SHxUI/LGbHpV4RzFxzuacZzFq9SQ7AMD3UuABAKzQ5GDnfbq9K0iZ83XPR6q2WlNGvCmdA1rkpim9u20xuosSj82YN6UxAEAvKfAAAFbvIklX7xZ3lOLXnS6ng4fSIV6j2enV/SICVu/NcDy7KR1i7eqJqKN097WO8u6b3YsAAL2lwAMAWLHJwc7zBJbphP65WE4Hd6VDvMZwPNtN8iHKWvheZ8Px7EPzudRdSjzWpxOT7AAAr6XAAwBYg8nBzkNcfCrhruDb/ricDt4XfPurcpNkr3QIaLmTJLc9KPEeU5d4d4WT0C2nWYweSocAAChNgQcAsCaTg5271Mdp0n33SVp/1NdwPHuXungAXm8/dYm3VzrIWi1Gj1mMjtLt/a9szkWzZxEAoPcUeAAAazQ52Hmf5GPpHKzVY5Lz5XTQ6iNTh+PZSZK3pXNAx+wn+dTsley2el/ZvHQMWm2exagLk+wAACuhwAMAWL/zdGhH0N/++597pTNsmfPldNDqj28zIXRTOgd01G7qSby+lHitn0amiPs4tQAA4FcUeAAAazY52HlMfUGz1RNan9krHWCLvF9OB62esGx2dH1IXTIA67GbehLvrHSQtVuM5lHi8TKPqffedeX7JACAlVDgAQBswORgpxM70viVu+V00IVpgavUx/wB63fToxLvKN25cYX1Os1i9FA6BADAtlHgAQBsyORg52OSH0rn6LhNHWX5kOR0Q29rbYbj2ZskZ6VzQM/cDMezq9Ih1m4xuosSj6+7aJ4rAAD8hgIPAGCDJgc775K0+sjFLff/NvR2TpfTQasvSjf7uLpfIsB2ejMcz7q/d3Ixuk9d4rV6TyhrM89i9L50CACAbaXAAwDYvPO4mNlm58vpoNUfv2bv3W3pHNBzZ8Px7Lb5fOwuJR5fdp+kC8dQAwCsjQIPAGDDJgc7j6lLvLZOcHX7YvMfmy+ng3npECtwm35/HGFbHCbpQ4n3mLrEM4FOUn//c9o8LwAA+B0KPACAAiYHO/epS7w22i8doJD75XTQ1o/Zz5rdW339GMI22k9d4nX783IxesxidJpkXjoKxZ1mMXooHQIAYNsp8AAACpkc7HxM8kPpHHyTelqg5Ybj2VmSN6VzAP+iHyVekixG50nsPeuviyxGd6VDAAC0gQIPAKCgycHOuzhSbJUe1vS4p8vpYF2PvRFNMXBVOgfwu3ZTl3iHpYOs3WJ0kfZOofP95lmMlLcAAN9IgQcAUN55kvvSITriYQ2PebGcDu7W8Lgb0+zX+hB772DbPZd4Z6WDrN1iNI8Sr0/uk1yUDgEA0CYKPACAwiYHO4+pL2I+ls7Cv/i4nA66MC1wk2SvdAjgm930qMQbx+tf19XHUC9GPs4AAC+gwAMA2AKTg537tGcS4d9LB9iQNn1MftdwPHuX5KR0DuDFbobj2U3pEGu3GN0nOYoSr8tOsxg9lA4BANA2CjwAgC0xOdj5mOSH0jm+wX7pABvwmOR8OR20+oLycDw7SfK2dA7gu531qMQbx3HSXXSRxeiudAgAgDZS4AEAbJHJwc67JB9L5yDny+mg1ReSh+PZXuqjM4F2OxuOZ7fNLsvuqie0jqLE65J5FqMuHEMNAFCEAg8AYPucxwXM77WKibn3y+mg1SVqc6H/Q5JuX/CH/jhM0ocS7zF1idfqr8Ekqb+PuSgdAgCgzRR4AABbZnKw85i6xGv18Y0lrGBq7m45HXThguNV+nHUKfTJfuoSr9uf24vRYxaj0yTz0lH4bvX3MXUhCwDAd1LgAQBsocnBzn3qEo/NeUhyWjrEaw3HszdJzkrnANaiHyVekixG50kcv9hO581eQwAAXkGBBwCwpSYHOx+T/FA6R4+cLqeDVk8LNBf1r0rnANZqN3WJd1g6yNotRhdxM0vb/JDFyBGoAAAroMADANhik4Odd0nuCsf4rcPSAdbgfAXHbxbV7Ma6LZ0D2IjnEu+sdJC1W4zmUeK1xccsRu9KhwAA6AoFHgDA9jtNfbwj6zFfTgfz0iFW4Db1RX2gP256VOKNYzfsNnP0NwDAiinwAAC23ORg5zF1iefC5bd5yfvpfjkdtP6C43A8u0q9Gwvon5vheHZTOsTa1TvVjuK1cBs9pt5752MDALBCCjwAgBaYHOzcJ7konaMlvvUozOditNWa6Zs3pXMARZ31qMQb59u/zrMZ583HBgCAFVLgAQC0xORgZ57kfekcHXK6nA4eSod4jeF4tp/kqnQOYCucDcezT80+zO5ajB5ST+IpjLbDD1mMPpYOAQDQRQo8AIAWmRzsXCS5K52jAy6W08Fd6RCv0Vyk/xB774Bf7Ce57UGJ95i6xJsXTtJ3H7MYvSsdAgCgqxR4AADtc5rkoWSAv/33P9u8b+3jcjrowiTjTZK90iGArbOf5FMzodtdi9FjFqPzKPFKuU/S+h2yAADbTIEHANAyk4Od591tjwVjtHW6oxMXHIfj2bskJ6VzAFtrL/UkXrdLvCRNifdD6Rg985h6713J70MAADpPgQcA0EKTg537JBelc7TMY5Lz5XTQ6guOw/HsJMnb0jmArbebusTrftlfH+PY+pszWuQ8i5EdhAAAa6bAAwBoqcnBzjxJF46CXLX/+p1fP19OB62+4Dgcz/ZSH50J8C12k3wYjmdnpYOs3WI0T13itfomjRb4IYvRx9IhAAD6QIEHANBik4OdiyR3pXO0wPvldNDqC47D8Ww3yYe09/hSoJyb4Xj2pnSItatLvKMo8dblYzPtCADABijwAADa7zTJQ+kQW+xuOR104bjRqyTd32cFrMvVcDzr/gRvfbSjEm/1OrFDFgCgTRR4AAAtNznYeUxd4m3yYuXeBt/Wazykft+0WjM5c1Y6B9B6Zz0q8f5P6tKJ13tMvfdOKQoAsEEKPACADpgc7Nwn2eSU2d4G39ZrnC6ng1ZfcByOZ/upp+8AVuFsOJ59ao7l7a66bDqKEm8VzptSFACADVLgAQB0xORgZ57kfekcW+R8OR20+oJjc4H9tnQOoHP2k9z2qMSbF07SZj9kMWr1DlkAgLZS4AEAdMjkYOciyV3pHIXdJ5kvp4N56SArcJuk2xfYgVL2k3xqpny7azF6zGJ0HiXe9/iYxehd6RAAAH2lwAMA6J7T1Lvf+up+OR2clw7xWsPx7Cr1BXaAddlLPYnX/a81dYn3Q+kYLfKQpPWvpQAAbabAAwDomMnBzmPqEq/Vu9++13I6eCid4bWG49lZkjelcwC9sJu6xDspHWTt6mkypdTX1d9H1EeQAgBQiAIPAKCDJgc790ku1vgm/vcaH7vXmkmYq9I5gF7ZTfKhuXmg2xajeeoSTzn1+y6yGLV6hywAQBco8AAAOmpysDNP8n5ND7+3psftteF4tpvkQ+y9A8q4GY5n3Z/+rUu8oyjxvuR98/4BAKAwBR4AQIdNDnYukriLvj1uohwFyroajmc3pUOsXT1hpsT7tbssRuuc3gcA4AUUeAAA3ecCZQsMx7N3Sbq/gwpog7PheHbTTAV3V13i/Z+40SVJHlLvzwUAYEso8AAAOm5ysPOYusRjSw3Hs5Mkb0vnAPjMWZLbHpR4z6+RfS7xHpOcNu8LAAC2hAIPAKAHJgc790nOS+fgXw3Hs73UR2cCbJv99KXEW4zGSealoxRy0UwjAgCwRRR4AAA9MTnYmWd1Fye7fTF3Q5qL4h/i/Qlsr/0kPw3Hs/3SQdZuMTpP/0q891mM5qVDAADwrxR4AAA9MjnYOc9qjgnr/oXczbiK9yWw/XZTT+J1/+tVXeJdlI6xIXdZjPryZwUAaB0FHgBA/xyl3ndDQcPx7E3qHVMAbfBc4p2VDrJ2i9H7dP/Y6Yckp6VDAADw+xR4AAA9MznYeUxd4lFIM8VyVToHwAvtJrnpSYk3T11wdfGGl8ckp1mMuvhnAwDoDAUeAEAPTQ527tP96YKt1Oy9uy2dA+AVbobj2bvSIdZuMfqYbk6tX2QxWsVx2gAArJECDwCgpyYHO/Mk88Ix+ug29RQLQJu9HY5nN6VDrF1ddB2lPnKyC94304UAAGy5ndIBAAAo62///c9PSfZf+v9NDnZ8L/lCw/HsKsmb0jkAVmie5OIfn/7StSm1X/uPvz9PT7/49XKL3GUxcoQ2AEBLmMADAOC7jgf723//83D1Ubqr2RmlvAO65izJbXM8cHfV++KOkrT16MmH1Dv9AABoCQUeAEDPTQ52ni9KsibD8Ww/yVXpHABrsp++lHiL0TjtO376MclpU0ICANASCjwAADI52LlPcl46Rxc1F7Q/xN47oNv2k/zU3LDQbYvRedpV4l00u/wAAGgRBR4AAEmSycHOPO26INkWN0n2SocA2IDd1JN4fSnxLkrH+AbvsxjNS4cAAODlFHgAAPxscrBznvbu99k6w/HsXZKT0jkANui5xDsrHWTtFqP32e7p9bssRm0oGQEA+AIFHgAAv3WUel8OrzAcz06SvC2dA6CA3SQ3PSnx5klOs32vm/XeOwAAWkuBBwDAr0wOdh5Tl3hf0/0j0r7TcDzbS310JkCf3TSTyN22GH3M9t38cpTFaJvyAADwQgo8AAD+xeRg5z5fPxZsdxNZ2mY4nu0m+RDvH4AkeTscz7p/Q8NidJ+6xHsonCRJzps8AAC0mAIPAIAvmhzszJPMC8doo6uYTgT43NlwPPvQ3ODQXXVpNk7ZXbLz5lhPAABaToEHAMAfuUjZC5GtMhzP3iQ5K50DYAudJLntQYn3fAz1XYG3fp/F6GvT8wAAtIQCDwCA39XswzvNdu312UrD8Ww/9fQdAF+2n7rE2ysdZK0Wo8csRkfZ7BT7t+6vBQCgJRR4AAD8ocnBzkPqEo/f0UyU3JbOAdAC+0k+NTc9dFs9DTff0Fs7aqb/AADoCAUeAABfNTnYuUt9nObnRgWibKvbJN0+Fg5gdXZTT+L1pcRb97GW583+PQAAOkSBBwDAN5kc7LzPrycJFFZJhuPZVeqJEgC+3W7qSbyz0kHWbjGaZ30l3rx5fAAAOkaBBwDAS1wkcZd/o7nw/KZ0DoAWu+lRiXeU1e6UvW8m/AAA6CAFHgAA32xysPOYeh9e7/fsNEe/XZXOAdABN800c7ctRndZXYn32DwWAAAdpcADAOBFJgc7D6lLvN4ajme7ST7EMaIAq/JmOJ7dlA6xdvWuuqO8fpr9KItR72+mAQDoMgUeAAAvNjnYuUt9nGZf3STZKx0CoGPOhuPZh+Ymie56fYl33jwGAAAdtlM6AAAAtMlwPHuX5G3pHAAddp/k6B+f/tLtCbP/+PvzNPfhC/6vub13AAD9oMADAIBvNBzPTlJfbAVgve6TnP7j018eSgdZu//4+02Ss2/4nfdZjMZrTgMAwJZwhCYAAHyD4Xi2l/roTADWbz/Jp+F4tl86yNrVE3Xzr/yux9THbgIA0BMKPAAA+IpmH9OHJN3eywSwXXaT3PaoxPujozGPshh1+0hRAAB+RYEHAABfd5V6GgSAzdpNPYl3VjrI2i1G83y5xDvPYnS/4TQAABSmwAMAgD8wHM/e5Nt2EwGwPjc9KvGOUh+ZmSTz5tcAAOiZndIBAABgWzXHtn0qnQOAn73/x6e/XJQOsXb/8ff9JG+zGJ2WjgIAQBkKPAAA+IJm791PsfcOYNvM//HpL3+0Lw4AAFpPgQcAAF8wHM8+xd47gG11l+T0H5/+8vi13wgAAG1kBx4AAPzGcDy7ivIOYJsdJrltpqUBAKBzFHgAAPCZ4Xh2luRN6RwAfNV+6hLPDRcAAHSOIzQBAKDRXAS+jb13AG3ymOToH5/+cl86CAAArIoCDwAAkjTHsH1Kslc4CgAv95h6J95d6SAAALAKjtAEAIDaTZR3AG21m/o4zbPSQQAAYBUUeAAA9N5wPHuX5KR0DgBe7UaJBwBAFzhCEwCAXhuOZydJPpTOAcBKzf/x6S/npUMAAMD3UuABANBbw/FsL/Xeu93CUQBYPSUeAACtpcADAKCXhuPZbpLbJPulswCwNndJTv/x6S+PpYMAAMBL2IEHAEBfXUV5B9B1h0lum5s2AACgNRR4AAD0znA8e5PkrHQOADZiP3WJ56YNAABaQ4EHAECvNBdwr0rnAGCjtqLEO758UiICAPBNFHgAAPTGZ3vvAOif3dQl3mGJN358+fQmyUOJtw0AQPso8AAA6JPb1BdwAein5xLvbJNv9Pjy6SrJx+V08LjJtwsAQHvtlA4AAACbMBzPTpL8tXQOALbGxT8+/eV+3W/k+PLpMEmW08Hdut8WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9ip3QAAIA+O7582ktyVjjGd1tOB+9KZwCgnKqq9pLsfeE//d6vv9Td9fX13Qoe54uqqjrLanKWsNb3DQAAZf2v0gEAAHpuL8nb0iFe4V3pAACsXlVV+0l2kzz/PGp+TpLDDce5W+NjT7L5P8+q3JUOAADA+ijwAAAAoKeaCbr95sefsrrJuVUZlQ4AAAAlKPAAAACgJ6qqOkw9cfan/DJdt822PR8AAKyFAg8AAAA6qpmwO0ld2J2UTfNd9ksHAACAEhR4AAAA0CGflXaTtL8AM4EHAEAvKfAAAACg5aqq2k1d2v017S/tfqWqqv3r6+v70jkAAGCTFHgAAADQUlVV7acu7U7S3WnPGxhaAAAgAElEQVS1rv65AADgdynwAAAAoGWqqjpLfUTmYdkkG7Gf5K50CAAA2CQFHgAAALREU9y9TbJXNslGmcADAKB3FHgAAACw5Xpa3D37U+kAAACwaQo8AAAA2FJVVR0muUk/izsAAOgtBR4AAABsmaqq9lIXd4dlk2yFw9IBAABg0/6tdAAAAADgF1VVvUvyUxRXAADQWwo8AAAA2AJVVe1XVfUp9a47PtMcJQoAAL2hwAMAKGg5HdyVzgBAeVVVvUnyKcl+6SwAAEB5duABrNjx5dNJkkcX5QEA+JqqqnZT77o7KZ1lyx0muSucAQAANsYEHsAKHV8+7Sf5kOT2+PLp0/Hl01nhSADrdFc6AECbVVW1n+Q2yjsAAOA3TOABrMjx5dNu6vLu2X6Sm+PLp6sk8yQ/LqeDhwLRAADYMp+Vd7uls7TEn0oHAACATTKBB7A6N0n2vvDru0neJPnp+PLpQ3PEJgAAPVVV1UmUdy/lfQUAQK+YwINXOL58uk29i6EL/r/ldPBYOkRbHV8+vcm3HX10kuTk+PLpIcmPSebe7wAA/VFV1VnqG794mf3SAQAAYJNM4AFJEiXS92v23r194f+2l+Qqyf89vny6aR4DAIAOU969TlVVpvAAAOgNBR7AKzR7727yuiN9zpJ8Or58+nR8+XS2ilwAAGwX5d1KuOkNAIDecIQmwOtcZXUXEvaT3BxfPl0lmSf5cTkdPKzosQEAKKSqqv3U3zfyOibwAADoDRN4AN+pmZY7W8ND7yZ5k+Sn48unD8eXT9+yWw8AgC3UlHe3UT6tggk8AAB6wwQewHc4vnzay2buoj5JcnJ8+fSQ5Mckc/sKAQDaodnZ9trj1vnFv6/hMR/W8JgAAPBqJvAAvs+HbPZCzF7qwvCn48unm+PLJ3cfAwBsvw8xNbZK63hf/s8aHhMAAF5NgQfwQs2OulIXYnZTH9v56fjy6bY5xhMAgC1TVdW7JIeFY3SNSUYAAHrDEZoAL9Dso3tTOkfjMMlhUyg+H6/5UDQRAACpquowydvSOTrINCMAAL1hAg/gGzV7725K5/iC3dQXiH46vnz6cHz5dFg4DwBAb3229441qKpqr3QGAADYBBN4AN9u03vvvsdJkpPjy6eH/DKV91g2EgBAr7xNvb+Y9dhL8lA4AwAArJ0JPIBvUHjv3ffYS3KVeirv5vjyqU3ZAQBaqaqq/WzPcetdtVc6AAAAbIICD+Artmzv3UvtJjlL8un48un2+PLprGwcAIBOuyodoAf2SgcAAIBNcIQmwB/Y4r133+MwyWEzTfh8vOZD0UQAAB1RVdVZ6u+3WK//XToAAABsggIP4I+1Ye/dS+2m3s3y9vjy6WOSH5fTwV3ZSAAArfe2dIAt9ND8eEzy989+/b75te9hvzMAAL2gwAP4HS3ce/c9TlJP5Y1N4wEAfJ9m+m6vcIySHpPcpS7p7pM8XF9f3xdNBAAALafAA/iClu+9e4nHJEfKOwCAV/lr6QAFfEzyX0k+Xl9fPxTOAgAAnaPAA/iNju29+5qL5XTg7mgAgO9UVdVhun9qw7P71LuUP15fXzvKEgAA1kiBB/Cvurj37kt+WE4H89IhAABablI6wAbMk/zoWEwAANgcBR68zkPpAKxWT/beJcl8OR28Kx0CAKDNqqraTXJWOscazZP84IhMAADYPAUevM7/lA7A6vRo7919kovSIQAAOuCkdIA1uU9ycX19fVc6CAAA9JUCDyC92nv3mORoOR3YWQIA8Hp/Lh1gxR5TH5X5rnQQAADoOwUeQK0Pe++UdwAAK9Icn9mlCbz7JKeOywQAgO2gwAN6r0d77y6W08F96RAAAB3RpfJufn19fV46BAAA8It/Kx0AoKQe7b37YTkdzEuHAADokD+VDrAiyrv2cnMeAECHKfCA3urR3rv5cjp4VzoEAEDHHJYOsALKuxa7vr52ND4AQIcp8IA+68Peu/skF6VDAAB0SVVVe0n2Csd4LeUdAABsMQUe0Es92Xv3mORoOR24MxcAYLUOSwd4JTd5AQDAllPgAb3Tk713yjsAgPUZlQ7wCo9JTh2/CAAA202BB/RKj/beXSynA0vtAQDWo80nOfxwfX39UDoEAADwxxR4QG8cXz7tph97735YTgfz0iEAADqsrQXe3fX19fvSIQAAgK9T4AF90oe9d/PldPCudAgAgK6qqmo37b0hzN47AABoCQUe0AvHl09nSc4Kx1i3+7goAwCwbm29IWx+fX3tiHUAAGgJBR7QeceXT/upp++67DHJ6XI6eCwdBACg4/ZKB/hOP5YOAAAAfDsFHtBpzd67m7T3mKNvdbScDh5KhwB6x00DQB/tlQ7wHe5N3wEAQLso8ICu68Peu/PldOCCDLRbW4uwv5cOAFDAv5cO8B3+VjoAAADwMgo8oLOOL5/epPt7794vp4N56RDAqynhAdqjjTeHfSwdAAAAeBkFHtBJPdl7d7ecDi5KhwAAYKvdX19fP5QOAQAAvIwCD+icZu/dh9I51uw+yWnpEAAAbD1T3gAA0EIKPKCLbpLslQ6xRo+p9961dWcWAECb7ZYO8EL2lQIAQAsp8IBOOb58epfkpHSONTtfTgfupAYAKKNtO/B83wgAAC2kwAOS5KF0gFU4vnw6TPK2dI41u1hOBx9LhwAAAAAAYH0UeEDSgQKvJ3vv5svp4H3pEAAAtMf19fVd6QwAAMDLKfCArrhN+/aRvMR9kovSIQAAAAAAWL//VToAwGsdXz5dpX27SF7iMcnpcjp4LB0EAPi65mSAl35v8mjHLUD3VVW1n5fffPp4fX3tNQIAekaBB7Ta8eXTSZI3pXOs2elyOngoHQIAqB1fPu0l2UtymOTf80tZd/jKx/38X++an++T/L/m5wclH8D2+qycO8wKXx+ax/78X++anz9/jXh0ZG6/VFW1l+QkyZ+S/Of19fW8aCDIz8/L/evr64+ls0AXKPCA1jq+fNpPclM6x5qdL6eDu9IhAKCvmrLuMMko9YXYww296cPf/PycJ2nKvCT/leTe9woAm1dV1WHq14Xn14dNngpz+JufnzMl9evDQ5rXiCT319fXD5sKxvpUVfVcDv+5+Xnvs/+8l2S+4UjwJX9N8qb5enSX+mvRnRsM4Pso8IBWao6mukm3997Nl9PBvHQIAOiTzwq7P6e+GLtXMM7veb5QfJL8XOrdpblAotADWL2msHt+bTgsGuaP7eWXKfEkSVVVD/n1hfSHjafiuzRTnc9Tdod/8Fv3q6ra87FlC5x89s+HzY+3nxV6/5n665BTJeAbKPCAtur63rv75XRwXjrEunznbqCt0YcLo58dD9dG9kgBL9JM9U9SX2Bo6+vTYfPj7fHl02OSj6kv1H7s8h7d79wl1StN6dB2Dy5Ks2m/OZ7w5I9/99bbS3LW/Hgu9D6mPnbxrlAmvqB53h3mlym7l7zGHcYUHgU1z9+9P/gth82PVFX1mF/fWODv8PAFCjx4HS8uBRxfPr1J8xePjnpMclQ6xJrtJ7ktHeIVdkoH2ICzJG9Lh/hOd+n+59C2mBxfPv3ps39/3sPyuYfmx8//bq8n2+Cz0u4k7b1h4ffs5pcLtTfHl0/zJP+5nA66uIvkKts9CbMN2vw917MfkrwrHYLu+6y0m6S9N3R8i73Uu+TfNBfRn8u8Lr5ObL2qqj6fsHvN8+7PUeBR1ktudthtfv9JYlIYfo8CD16ns3czb6vmYttV6RxrdtTlO+WBTtnLr4uPw2/5n5rj/pJfl3vP5d9j888mKVm5Zrr4LPWF2b2SWTbsLMnZ8eXTQ5K/JXnvew2AX1RVdZa6/Gj7pN33+Pmmj88m83508Xx9munxw/wyZbcqJ1VV7V5fX/f2NX5LJvPve/wxmLzi/93Lv04K36U5UaLH71N6ToEHtEZz7OKH0jnW7NwFa6BH9vJLiXL42//YFH3Phd5Dkv95/mdfK3mJ48unwyR/TT8vzH5uL/V09dtmKu8HE7FAXzXTdn9NfbG49AX/bbGXXybz7lIXeabyXqmqqudJo+cpu701vrmT9HsK7zblP58vkrwvnGHjmq+pq5xc3stnJ0pUVXWfX0/oKfToBQUe0CYf0u275efL6WBeOgTAltnN75d7z8Xe31P/Ze7eVBGfO758OktdWO2VTbKVzlJP5c2jyAN6pNkLOUm31zKswmGSw2YK5ofr6+t50TQt0zzPnifsNnkc65/S0wKvOYq0dHmX1F9felfgZf03yu03P94kyWeFnl2edJoCD2iF48und+n2fpP75XRwXjoEQMs8/yXuJM3OxuaIwLs0d2YqJfpJcfciZ1HkAT3QFCpv0+2/V67DXurpl7dR5P2uz/YnPk/ZlSqSTpL09drCa45vXKX9qqr2engM7Z83/PZ+LvSqqkp+PZ13t+EssDYKPGDrHV8+/XxhtqMekxyVDrFhJmRYJ8+vftvLZ7sTFHr9orh7lbMkJ8eXTz8up4N3hbMArEyzE+sqirvX2osi72fNsZiH+WXKbq9gnM/tVlV10rejTz87pnRbnKRHU3iffT6UdNj8eNsUeh/zS6Fn/QKtpcADttrx5dNekpvSOdbsqG9Hvi2ng/vm+DtYh7+XDsBW2cuvC73no1b+Zo9edzQ77m6yPRfP2mo39X68Seq9vHeF8wB8t2Yi6m0clblqe6mLvL8muejTpEtTBp+kLu02eSzmS/05dXnRJ9tU3iX9O0Zz297/SZ3pJEmqqnrMryf0/D2Q1lDgAVvr+PJpN/Xeu204w3xdzl1ABtion49a+Ww67z+X00HfLnJ0QnOjz1W286JBm+0luT2+fHqf+ljNXt1oBLRfVVXvkvw13f67ZGn7SW6rqpqnLvI691rRlMCH+WXKri3Pp8PSAQrY9PGNX9O3YzS37f3/W88Tms+F3kN+Xeg9lAoGX/NvpQMA/IGrbPddba81X04H89IhAHpsL/Vd+R+OL5/+7/Hl09Xx5VOXX3c65fjy6U2ST1HerdOb1EWezwugFaqqOqyq6lPqybu2lC1td5bkp6qqzgrnWImqqk6qqrqqquqnJD+lnvA/SbueT3vNtGAvbOHxmc8OSwfYhC1+//+RvdRfu25Sf/36qaqqrp/+RUuZwAO2UnNR7qx0jjW6X04HfV0sDbCNdlOXFc+TeT8m+Whn3vb57Hjtw7JJemM/dYl34cYjYFs1F5Dfpn4tZ/N2Ux+rOUly2tZpvKaE7MpF/EmSvpz2s63l0Z+TzEuH2IDD0gFWYC/tKunpERN4wNZp7vK+Kp1jjR6THJUOAcDv2kv9OvTT8eXTh2a/Glvg+PLpLPXU3WHZJL2zm+Tm+PKpKxc1gQ5pJo1uo7zbBoepp1m2tVD5mo+p/77eBW39GHyPbT2+8aS5uaDrtvX9/1J/Kx0AvkSBB2yVZu/dbekca3ZklwxAa5yknj766fjy6ax5naKApjy6ibtjSzo7vny69XkAbIuqqp6PU+7NcYEtsJvkQ1VVrbspt5kc7Mpe5L1mh1+nteD4xm3Otipd+DM+XF9fd+Vzn45R4AHb5jbdvjB3vpwO+nKMBUCX7KXZkXB8+fROgbE5x5dPu8eXT5/S7aO12+QwdantcwAopqqq3aqqPqTbJ7e03Zuqqj61cALpx9IBVqgLxcrXbPufsSvTaV/UTNu27XP8S0zfsbUUeMDWOL58ukq375yc2x0D0HrPO3YUeRvQHKv9U7r9/UEbPe/F8/wHNu6zIzO3/cI99evFT83HrBWur6/vkzyUzrEik9IBNmDbC7KuH6O57e//bzUvHQB+jwIP2ArNTpsu7yy4X04H56VDALAyirw1O758Okn3J/PbTIkHbFxVVYf5/9m7l+S2jqxd2OucqCYiPp4RFDwC0yMwhAmUNAKTnd211ERLUgtNyd3dITwC0ROA4BGYNYJCjeDnF4EB/A0ky7RKF4C45GU/T0SFbJdNLgIg9ka+uVZurw3VBELERUT80XXdVe5C9tBKF95ly2M0089WQ5BfQ41P1cLPdtv3/Tp3EfAlAjwgu7S7vuXRJ/cR8Sx3ERzNUM4vHMrPCYcS5J1A2tjzIYR3pRPiAWeTAiAbO+p103Xdm9xF7GiRu4AjmuQu4IRqCY9a6VL7i9RZ28L7sfGZFE2AB2SVFnxaX6B7sZyPhCHtGMoZhkP5OeFYHoK8P1L4xBOlx+8mdx3sTIgHnFwK71wb6ve667rin8e+7+8j4jZ3HUfSZHiU1DIitJagcV+1PP5fs+77vpXfdRolwANyu4mIce4iTujVcj5a5S4CgLMZR8TNdLb5VxoByR6Ed9V6OI8K4OhS4OPa0I6rGkK8aKcrp8kz2NL4zGpG6XZd1+LnghZ+plZ+z2mYAA/IZjrbvIk2LvhfsljOR+9zFwFAFuOI+DCdbT5OZ5tx5lqqILyr3uV0tvH8AUeVgp6r3HVwdMWHeKkrZ527jiNpcd2ltp+pqU7IND5znLuOI1jkLgC+RYAHZJG6El7nruOE7iLiVe4iAMhuEs7H+ybhXTOuprPNy9xFAG0Q3jWv+BAv2hmj+WPuAk6gtvGNtQWO39LCz3Pb9/06dxHwLQI84OxSJ0LpN+qHuA/n3gHwVw/n401yF1Ka6WxzGRHvctfB0bzzOgcOJbwbjNJDvF9yF3AkLYQt/1Hb+MzkorExmi10FBqfSRUEeMBZpe6DDxHRchfC9XI+WucuAoDijCPi43S2eacbbyuFdx+j7fuCIfrgNQ48Vdd1L0N4NyRXXdcVuZEndeesMpdxDK2FR7X+LC2EXrUGqJ9apzG5UDwBHnBu76L+C/3XvF3OR24CdrPKXQBAJi9j243X8vXwmwayqWeoHp5bgL10XXcVurKH6GV67kvUSpdOE+FRUtv4zAe1Bo+fauHnaOX3mgEQ4AFnk85EucpdxwndLuejN7mLAKAK49iGeEM+L+xjbB8H2jQZ+Osb2FPqECp5nCKndVNol9htbI/JqN0kdwHHUHn3VyudkLUGqI8tchcAuxLgAWcxgPNt1hFxnbsIAKrzbjrb3Axt3OB0trmJehdfdnUX227zz/3vLktF5/c6nX0M8FVd112G8I5tiFfU/UHf9/exDfFqNy7tsX2i2gOwqjshKw9QH9ym8bhQhb/lLgBoX1qU/Ji7jhO6j4gXy/mohV15AJzfVURcTmebF0M4Q3U621xFWx3597EN5f6Z/rzb9Z4g3SNdxnZX/Pfpz5bC3IvYLsg/y10IUK6u6x4+L7b0/sfTXETEh67rfkjBWSl+iTbuXX6K+jcR/Zy7gAM9j7o3f09yF3AEv+UuAPYhwAPOofUPY6+W81HtN8EA5HUZ25Gaz1q+pqSO/BY6LB524/92yNm3KehbxaNzYaezzfPY7s6+OqjCckyms81zZwQDX9H650X2M47tOarFbP7o+/6u67p11D/6+3lEvMpdxFOlDsJx7joOdNF13WXf97Xe71fdQRgR933fL3IXAfswQhM4qels8y7qb6//mvfL+WiRuwgAmnARER+ns80kdyGnkLrNPuSu40D3EfE2Ir5bzkfXpwillvPR7XI+uo6I/5e+V0kdCE/1bmhjYoHddF3X+udFnmbSdd2b3EV84pfcBRxB7WM0Wzh7LaLSnyN1S9c+wnSRuwDYlwAPOJk0Iutl7jpOaLWcj6rdvQYNq3U3I0T8GeJd5S7kBG6i3l3Tj4O7N+cYm72cj+6X89GbiPguIt6f+vud2DjavicEnqDruufhvYEve9113SR3EY+00kk+yV3AAWoPjx7U+nPUWvdjLQTxDIwADziJNCLrXe46TmgdES9yFwF8VgvdKnDTUoiXfpZaP/TfRsQP5wruPpWCvFcR8UPUvUHh5+lsM85dBFCGruvG0cZIZU7rJnX9ZNf3/TraCPFq7f5qYXzmg1o7IWsfn7lKv8dQFQEecHSPRmQVcaN9Ii9yLOIBMChNhHgptKl1U8+r5Xz0YjkfrXMXks5GfBb1jv65iIjXuYsAinETbX9e3MU6/jwH9Uv/G7pxlHUP8WvuAo7gMgXotakyePyKGn+eSe4CDtTC7y8D9LfcBQBN+hDt7Iz6nOu0iAYAp3YznW3Wy/lolbuQA9S4SHsfEc9Ku96nzUPX09nm31FnGHY1nW3elhCIAvl0Xfcy6l8I3tddRPyW/lz3fb/z9SV1oF3G9jH7Pv1Z23X1EFdd1/3W93327re+72+7rruP+h//51HfeO5aJzl8yfOIqOZIljTyuObX/X3f94vcRcBTCPCAo5rONm+i7Q9ji+V8tMhdBEBm69htB+P/xHbB6cFl1P3BL5cP09mmuDBpF6mDcJK5jH3dxbbTfp27kC9ZzkdvprPNOuocP/c6Iq5zFwHkkTp/atyA8BSr2N4v3fZ9/+TpLem/XcWjjry0mP6P2IYAQ7i3etd13eqQx/GIFlH/2Y0/RkUBXmPjMx+Mu6673CfMz6z28ZnZNwDAUwnwgKOZzjbPo+0PY3fL+ciCE0NRwodjyrVezkdvnvofp1HLD8HeJP4M+gR8n3cRER+ns813NY1vTs9zSWOvdnEX28674h/n5Xy0mM4230d9i4jPp7PNqyM+xq/ivO8bP0XE1Rm/3zE9y13AAda5C+BoauzK3tciIt6e8qyl1I12GxHXXdddRcTP8ddNU60Zx3atoYSOpV+jvmvvp553XXdRSCC6ixrHTe7ip6jnfOPaOyB/yV0APJUADziK6WxzGXXuAt/VfdS96AF7Wc5Hd9PZJncZNCot3K/S364e/3/pvLTL2O4MnkTbi1H7eAjxqgiXktdR1yLtOioJ7x4s56NXKSi9yl3LHi5iu/D55hhf7Nw717uum5zz+x1T3/er3DUwbClommQu45RWEfHq3O9LaSzcIr0/3UR7nUoPXnZd92vujqW+7++6rruL+u9Rn0c95+rWHh59ySR3AbtoYHzmXe73DTjE/81dAFC/tHDU+k7Kqhb0AGq1nI/Wy/nodjkfvVrORz9ExP+LiBexXWAY+vvwZVTS0ZaC2Jp2p9/Hdmxmja+xV1HP7u0Hre6kB74gneNWxTXsCe5jG9w9y7lI3Pf9qu/772J7XajxeraLUl5DLXTzVDESMQXT48xlnMplGitcuh9zF3CgFn5fGTABHnAM76L+3Wdfc13juUMALVjOR/cp0LtezkePw7yhukrnypWutq78aq/1KXSsbcT3OI1eB4bjZbS54fMuIn7o+76Y88RSLT9EfZs7djFJ3UC5tXCe1iR3ATtqfdNPCa/nb6mhxi+5jzZ+XxkwAR5wkOls8zLqGtu0r8VyPlrkLgKArYcwL7adea9imOcivUujq4s0nW0mUc+iUETE2+V8VPUH+xQ+vs1dx55aX5ADktRh0uJZ6YuIeHbKs+6equ/7dd/3P0Sbm56yd+Gls+MWues40EUhYei31FDjIYq+H+q67jLq7oC8reisR/gsAR7wZGmBLvvN8wndpUVieGyduwDgP51575fz0Xex7cpbZS7pnB5GV5eqpkXau+V89CZ3EceQfo515jL28TyNYQfaV9N1YVfv+76/Ln1huO/766ivS/tbxuk8xdx+y13AERQ9RrOBs9d2UfoYzaIDxh38mrsAOJQAD3iStODyIXcdJ3QfEc9yF0GR/p27AOCvUlfes9i+b68yl3Mul9PZ5k3uIj5VYfdda4uatf08re+qh8FLC9NXmcs4tuu+71/lLmJXfd8vor7rw7dkD4X7vr+NujbOfE7p1+GiA8YjKvl5KLm2b1n3fb/KXQQcSoAHPNXHaHsn1LN0pgwAlVjOR6uBBXmvCxylmX1BbQ9vaz337kuW89Eq6nrt/5y7AODkarou7OI6BWJVaTDEK6ULr+oR3LEdo1naveRjNYdH+yiyyy1twBhnLuMQv+QuAI5BgAfsbTrb3EREyTd5h7pubUGvUOvcBQBtehTkXce2o7plxYyyTmHiJHcdO7qPiPe5iziRms7CuzRGE9rVYPfd2xrDuwep9pquEd9SQjjcQkBQang0hPGZD0odo1l7gLrIXQAcgwAP2Mt0trmKtj6Efer9cj5a5C5iIIyiBE4qvZ9/F/Xvjv6aSbo2l6Cmbqq3rXbapy68deYy9lH74hDwZTVdF75l0ff9m9xFHCr9DIvMZRzLuOu6Sc4C+r5fR12d759T6nV4KOMzH5T4PBQZ7u7otvQzSmFXAjxgZ2ln/U3uOk5otZyPqjnLAIBvW85H98v56EW03Y33OncXU/r+Vzlr2MN6OR+12n33oKYOi6Et0MEgdF1X03XhW+76vm9p/OSriGhl4kwJXXi/5i7gQONCx2iWGGid0o+5C3gsdQSW+LrYVe2/l/AfAjxgJ2lh7kPuOk5oHREvchcBwGmkbrxn0c6C1WPjiHiZuYarzN9/H0P4QF9T1+kkdwHASbQy/u4+tvcPzUhdKa1sbJoUMHrwNup/LCe5C3hsYOMzHzxPGx9KUXOAuu77vqZ7YfgqAR6wqw9R9+G1X3MfES9aHaUFwFY63/RZ1D/q6HN+ztyFV8uYtJbPvvuPdE+zyF3Hji6ms80kdxHA0dVyXfiW6xbHsPV9fxd1dWt/TdbXWnp91B4WlDYqcajd+SWFZjU/B7X/PsJfCPCAb5rONu+isB1ZR3adFnUBaFwaqfks6gk3dnURmbrw0ojtcY7v/QS3A9qw81vuAvYwyV0AcDxpHF/No9ce3LbcxdH3/ftoY1NTCaFH7d39lwV0MkbEf8bvlvCc5lBEaJaeg0nuOg7wS+4C4JgEeMBXTWeb55F/LNcpvVrOR81+KAPg85bz0XW0F+Ll6sIrbdf21wzpA/0qdwF7KOrcF+BgNV0XvuRhzGTrWjgDfpxGLmbT9/0qtsdy1KyU0GyI4zMflDJGs5TXwlOs+r5f5y4CjkmAB3xR2lF/k7uOE1os56Pmx2gBnEATHUwNhngXkecsulo+5K+H1HGfOg1XuevY0SR3AcBRXeUu4I3N0ccAACAASURBVAh+aXF05qfSKM0WPhOX0LlUexdeKZtpSngucyrhvrrm56D230P4LwI84LPSDv6baHfn011auAVgf//MXcCxpGvBKncdR3TWc2BqG5+Zu4AMfs9dwK7SawmoXOqEqv0z5DraCLV29Tbq35xVQuixyF3AgbJ3fw18fOaDrOFZ5c9BC+dRwn8R4AFfchNtnFvwOXcR8Sx3EQAU40Vsrw0tGKfx1+dS0wf8Ie7IXeUuYA+T3AUAR1Fz58aDt0PovnuQftbaR0xfFDBGcx11XXc/J/d9Xe7vX4LcQeok4/c+1O2Q3rsZDgEe8F+ms82baPfG6T4irtNYKQB4GDV4HfXvPn9wzrOHShm39C33Qxqf+UhNP/P3uQsAjmKSu4ADDbWDY5G7gCMoITyufbNQ7scw9/cvRc71uJqfg9o3IsBnCfCAv5jONpOIeJ27jhN6NdAFPAC+Il0bWhmt/DyNwj6p9D0mp/4+R7LKXUAOKZxe565jR61OfoDB6LquprHKXzKIs+8+lbrHFpnLONQkdwGxDX9rfv1Mcn3jykc3HlvODXK1PgfrdKYnNEeAB/zHdLYZR8SH3HWc2LtzLGoCUJ/lfHQb9S9ePTjHh+/JGb7HsVRzFtwJrHMXsCMBHtRvkruAI1jkLiCj2rtXxilEziaFvzV3cOYcRVprcHQKWR6Lys8wrf39C75IgAdExH920X+Iei/Wu7qIiI9CPAC+4FXUvXP6wTnG39QUuKxyF5BRNeHldLap6TUF/LeaR69FbM9PWucuIpfUvVJ7B8skdwFhjGZt37dEuYLUmp+DmoNz+CoBHvDgKupaiDvEZQjxAPiMNHLwVe46juAcYzRrOf8ujM+uxjh3AcBBJrkLOFDtwcsx1P4YZL836ft+FfV0v3/O2YMj4zM/K0eYVutzMOjNF7RPgAc8WEUbHQe7uoyId7mLAKA8y/loEW10bJ36Q/jkxF//WFa5C8hslbuAPQxlMxk0p+u6Se4aDnTf970Ojvq7WCa5C0hqDkIvMowirTU4OqWzPibpOa91k3vNv2/wTX/LXQBQhuV8dDedbZ5FxMeo96K9r6vpbBPL+eg6dyEAFOdtlLMI9FQ/xonO8qls1OHldLb5mLuIjGq6r/t77gKAJ6vpuvA5tQdXR9H3/brruruo9/m86LruMo0DzWkREa8z13CIn+K841R/PuP3qsVF13XPz7ix4KczfZ9js/mC5gnwgP8YcIj3e+q2AICIiFjOR6vpbLOKukO85xFxqk0qNS3sXUTdz+OQjHMXADxZ9tGFB/otdwEFWUVd1/lPXUbms/xSELqKeu8/nseZRsp3XTeOul9vp/SPON/mglq7IBe5C4BTM0IT+It0RsyzGNY4zZvpbHOVuwgAilP7OJaLE3bKjU/0dRm2ce4CgCerfQF+lbuAgtQeZn6fu4Ck5vvI8RnHaNYaHJ3DWR6b9FyPz/G9TqDm3zPYiQAP+C+PQrwheVfZODAATix1Z9e+oeVU17baOy0o0zh3AcCTjXMXcIBV3/e1X++Ppu/7VdR9/1PK5/rbqPtxnJzp+5Q0uvE+Ita5i3jk4kzni9Yaot4VMC4XTk6AB3xWCvGGdDbcRUR8FOIB8IlF7gIOdKqgbSijtjmz6Wwzzl0DsJ8zLTCf0u+5CyhQzYvik9wFRESkULjms7lOHqwVOD7zNiJe5C7iE/9o5Hucwi+5C4BzEOABX5Q6D4YW4t1MZxuLknzN/+QuADir2seyjE/0dUtabKEt49wFAHsb5y7gQKvcBRSo6lAzBUMlqHkc6eUZHsfSOr9+Sx1d69yFPHLSx6jAEHUfNQfksDMBHvBVKcR7m7uOM7qMiI+5i6Botd7cAk+QOtKNP3rERhcAPjHOXcAh0shI/mqVu4ADjXMXEBHR9/1tlBUG7evUAVtR4zPT8xVRVjB06vMISwtRd7Uw+pihEOAB37Scj95E/SPE9nE5nW1uchcBQDFWuQs4xAnGQ9vIwCl5fUF9vs9dwAFWuQsoUQOhZknXkpLCoH2d7MzjAju/Fo/+urQJHKcMOksKUfdRc3cr7EWAB+xkOR9dx7BCvKvpbPMudxGNO9mHAYAjq3qMVDivjrp4vUJ9av69rfmst1Or+bEp6TVZ8zldz7uuO9VjWVrn139Cu6GM0SwwRN3V+lG3JDRPgAfsLIV4Nd/E7+vldLa5yl0EANnVfu2bFP71AKjbJHcBB/h37gIKts5dwAGK6Qrt+34ddd9LnipoK6nza51Cu8dK6sI71RjNyQm+5jkI7xgUAR6wr2dR983nvm6ms80kdxEA5LOcj1a5a4AB+XvuAoBBGdJn2339M3cBByipAy+i7i68fxz7CxbY+fW552dx7iK+4RSB59Gf2zOp+fcJ9ibAA/aynI/uYxvirTOXck4fTnB+EAB1qXmBr5hd6LCDce4CgN2lhfia1Xx9P7WaH5tx7gI+UXPH0OQEX/PnE3zNQ/zX81Ng5+RROyHTaNTSxpju4i49NzAYAjxgbynEexER97lrOZOLiPg4nW1K28UHwPnUfM079vVLIAjAg3HuAg7R933N1/dTq/mxGecu4LH0Oqs1xLvouu7YQU9JwdHXAqGWx2iW9BzsQ/cdgyPAA55kOR/dxbYTr+ab+n0I8QCGraQduLm5FgLQglXuAgrn3ue4SgqD9nW0UYsphBof6+sdwdcCodJC18kRv1at4zNLe07g5AR4wJOlEO86dx1ndBkRN7mLACCL/81dwAHGuQsAAOpSe3diGhFYjL7vb6PeDdDH7NY6xVluh/hiIFTgGM1jPnaTI36tc1nU/r4ETyHAAw6ynI9uY1gh3vPpbCPEA6Am49wFANCsSe4CDlDSwnyp1rkLOECJ59jX2j10ccTxjSWNbrzdIRAqqXPy8hjnjqaRqEUF3Dv6LXcBkIMADzjYcj5aRMTb3HWc0dV0tnmZuwgAgAaVuOAKtKnm7vpzWecuoDE1n991cPdXgeMzdwmESgtdjxGA1jg+8z51scLgCPCAo1jOR28iYpG5jHN6N51trnIXAcDZGNcC51HjjnAA+Ka+7++i3lD0GMFRSeMz7/u+X3zrX0pjNEsKjo7xGJbUBbmrRe4CIBcBHnA0y/noOoZ1UX03nW3sEgcYBgEeAACHqrULb3yEMZolBUf7hHIljW48aIxmxeMzSxplCmclwAOO7VUM5yyBi4j4OJ1txrkLAeDkxrkLAACgeiV1c+1r8tT/sMDxmfsEQqU9Z4cEoT8erYrzuUvdqzBIAjzgqJbz0X1EPIthhXgfprNNjTuYAAAA4Et+z11Aa9JIxlXmMp7qkPGNJY3PXPd9v9r1X+77/j7KCvEOeSxL6oLcle47Bu1vuQsA2rOcj+6ns82LiPgj6mzN39dlRHyMiB9yFwIAfNFqOR89y10EADB4v8YB3WwZXXZdN04h5L6ujlzLIZ4Sxv0W5YRfl13XXaRgcWcFdkHuapG7AMhJBx5wEsv5aB3bTryhnBl0OZ1tbnIXAQAAABStpG6ufe0dYhV47tpTOrpKe86eEiaW1AW5q9t9g0pojQAPOJnlfHQXES9y13FGV9PZ5k3uIgDgE+vcBRTiMncBAFCZv+cuoEUpkFjkruOJnnKG2j+OXsXTPek8tQLHaD7lMS2lg3Afv+UuAHIT4AEntZyPVhFxnbuOM3o9nW2uchcBwNHVeOD7g3XuAgpR0s5vAKjBOHcBDas1mHjedd2+91QlBUeHnKdW0nO21/PQdd046vt9vu/7fpG7CMhNgAec3HI+WkTEq9x1nNHNdLaxyx+AVv2eu4Cnms42QjwAILu+72+j3iNHdg7kChyf+eQuuhQmlfSc7ROMlhSi7qqkjkfIRoAHnMVyPnof9Y6IeIqPQjyApnhPb4PnEeC49h5FB/zHIncBT7TP+MaSxmeu+r5fH/g1SgqV9nlsazz/7pfcBUAJBHjA2Szno+uo9wZ1XxcR8cFOf4Bm1Px+fuyOuZJ2Hu9LgAdwXDVfE2oej30u1d7/9H2/yl3DDg4Z55jTZI9/t6TOr2M83tWN0UzjM2u7B14/5axCaJEADzi3VzGcXZrj2HbiVfuh58Q8LkAVprPNJHcNhan5Ov597gIAoCK1LfpXJQUU69x1PMFFGo35VS2Nz3xQ4OjTXQLSkkLUXdUabsPRCfCAs1rOR/cR8SzqXvzbx2VEvMtdRKF8GARqUfv71frIX6+kRYt91f5cApRmnbuAA5QULDBctY4J3GV8Y0njMxd93x/rHra2MZolPQ+7WuQuAEohwAPOLoV4L6LuBcB9XE1nGyEeQL1q79paH/OLLeejmjfhXOqMBzieI5wnlZNNHV/Rdd0kdw0HWOUuYA8lhUH7qK3z65ijL4sao/m1/zON2Jycp5Sjuav82gJHJcADsljOR+vYduINJcR7OZ1trnIXAcCT1L7Ad4rAbX2Cr3kuJS0mAZBROhuKz7Ph5QxSUFHj5qiLruu+eI9c2PjM+zT68ihKG6P5jXGmNd731tqVCichwAOySTv4X+Su44xuprNNjTdPAIOVurWqDvBS5/uxrU/wNc/lx9wFADRmlbuAA4xzF1Cwmu9/agvEag0sfnri/3dup+hyLKlz8msjMmscn1nSYwvZCfCArJbz0SoirnPXcUY309mm5g9CAENT+8aL1Ym+7u8n+rrn8NwYTYCjKqYT5Ql8NvuymkeI/2/uAvZUa2Dx2fvkNLaxpHvoUwSkxY/RLPB52MXtEc8qhCYI8IDslvPRIiJe5a7jTC4i4uN0thnnLoQns+gLw1J7t9b6RF+3tp3tj9W4mAFQsn/mLuAAf89dQMFqDjeruk9JgUWNId74C2M0S7rPWvd9f/TXQxqjuT72132iiy+M0Zycu5Aj+DV3AVAaAR5QhOV89D4iFrnrOJOLiPhg93+1av4gC+yvpAWIpzjVompVC2OfUdJYJ4DarXMXcAD39p+ROnfGues4wDp3AU9QUkfXPiaf+WcljW08ZTBaUuj6uce8pOdhF0c9qxBaIcADirGcj66jrBugU7qMiA+5iwDgy6azzVXU33W7OsUXXc5H66hzcezBxEhrgKNZ5y7gAJPcBRRqkruAQ5yi4+rU+r5fRJ3jaP+yKarAsY2nPF+wpG6xzz3mJT0PuxjKeiDsRYAHlOY66t/Vv6vJdLa5yV0EAF9UfZfWcj465TV1dcKvfQ4/5y4AoAV9369y13CIrusmuWsoUM0jxGteT6gxwLjsum786O9LCo3u+r5fn+qLp6D4ZF9/T38Zo5n+uraNiCUFolAMAR5QlOV8dB8Rz6Kcm6BTu5rONm9yFwHAX6WzSieZyzjU6sRf//cTf/1Tu3ImLcDR1ByaTHIXUKBJ7gIOUPNrsdYxmo9Du5LGNp4jECopdP3HF/66BuvaN4PAqQjwgOKkEO9F1Dk+4ilepzFtUAxnNEK8zl3AEZw6YFud+OufQwvPM0AJag5Nau42O7rUTVXzmOlTnf97cun8r3XuOp7gx4gix2cuzvA9Suoamzz665Keh12UFIRCUQR4QJHSyK9nues4o5vpbDPJXQQ8UvOH9hp5vAuSurKuMpdxDKtTfvF0Dl7NC7YR2y68Se4iABpQbWgSdXebncIkdwEHqv3epMYg43mB4d1t3/cn3xRe2BjNcdd1l13XXYbxmdAMAR5QrBTiXeeu44w+TGcbi/gwTLV9wGpdC11Z98v5aHWG73OO73Fq73IXANCAVe4CDvH47CiqG733Fw2M4as1yHgeZb12zjmOtKTQ9aeo7xzvuxSEAp8hwAOKtpyPFhHxKncdZ3IRER+NLgTIJ3VjXWUu4xjOtZBQ6yLTY5fT2eZl7iIAapYWX2s+AqGk4CGbAruo9rXKXcChCuvo2sdNlPPauY/zhmol3Q+/TP+rSUmPHxRHgAcUbzkfvY/zzC4vgRCvAsatQdNa6cY69fl3EfGfbvn1Ob7Xib3WBQ9wsFXuAg5QSvCQW+2Pw1nuf87gl9wFVO4s4zMfVBy6lqKkDkYojgAPqMJyPrqO4VzULyPiQ+4iAIZmOtu8iXbOIxzqruOnuojtebQ20AA8Xc3hyUXXdVe5iyjAz7kLOFArawat/By5nHN85gPP2dOs+r5f5y4CSibAA2pyHfUfSL2ryXS2ucldBF80zl0AcFyps7aFs+8iIm6X89E5x5gtzvi9Tuky2unABMih9gXs2s6NOqqu6y6j7o1M962co5UCjSZ+lgzu+77P8V7Uwoa2HDxu8A0CPKAaaTHyWdR9tsI+rlI3COUZ5y4AOJ7UddVS5/NZPwgv56N11D027bEr5+EBPE0KHdaZyzjEpOu6ce4iMtJ9VxbBxtMscnzTFB4LXffX2u8tHJ0AD6jKAEO819PZ5ip3EfyX73MXAJn9PXcBx5LCu4+xHaHYgvvlfGTX8WHeufYCNei6rsRrV+2Lsa104+8lvZauctdxoJpHuH5O7b9LueS8J23pfvgcznpWIdRKgAdUZzkf3UXEi9x1nNFNGu1GOca5C4DMxrkLOKKbqHtc1KcWOb7pcj5aRN1dF5+6EeIBFSjx+lX7AvbVQLvwWug+byrwSh2tTf1MZ7DOPEbV87Wf2q8XcBYCPKBKy/loFdsz8Ybiw3S2KfED+lB5LqAB6azR57nrOLJfBvq9T0GIB7CntHi+zl3HgQbVhZe676ofn9loJ89vuQuoTNZ7UWcX7iXXWYVQHQEeUK202/997jrO5CIiPqZRbxRAVyTULYV3V7nrOLJFOo8u2/eP9kZcC/FoRtd1NiBxLrUvyl4N7PflddQ/SrzVoKv236VzK+Hx0lW2mxKeK6iCAA+o2nI+ehWZxoVlIMQryyR3AcD+prPNxXS2+SPaC+8iMi8YpHNqW+vCi9iGeO9yF0ExfsxdwAHcQ3IuLSxgD+J9P40LrX185n3f94vcRZxC6ioUdOzmLnXA5eb52k2roTscnQAPaMGrGM6YgsuI+JC7CCKi7gW8r5rONs9jey5YrSa5C6BMaRTxx2hzDO4qjZfO7X2014UXEfFyOtvYRAOwg0bGaE66rqs92NpFzff8D1oPTAQduyliE5kxmjtZG58JuxPgAdVLO/6fRf0fEnc1SaPfyGvS2kLudLYZT2ebD7ENiceZy4GjSsF0q+FdRMTb3AVENN2FF7HdHPAvI5QBdtLCteB1y6M0u657Hm1sfGvhtfZFqbuwxc1Rx1ZSINRCF/IplfRcQfEEeEAT0oLhixjOje3VdLZ5k7sI4nnuAo4hjRR8ExF/RCM/EzxIr+93sQ2mmwrdHyml+y4iIpbz0Ztod1PNwzjrd61t4gA4skXuAo7gIiJuuq5r7v0+jc5sYVPoOnV8tk7g8XW3adxoKTxfXyfghD0I8IBmLOeju9iGeEPxejrbXOUuYuB+zl3AIR4Fd/+KNg6vh79InVJ/RP1nu3zLq9wFfEYRHYEn9DIi/kidnQB8Ii2mL3LXcQSX0eZ5eDfRxr1/6/cbD4zR/LqiHh9jNL9qKKE7HI0AD2hK6kC4zl3HGd0Y5ZXVZY2PfwruXsY22BDc0Zz0Gr+J7cjMceZyTm2RNrAUZTkfLSJilbmMUxtHxId0Nt44cy3A0/09dwENa2W04VVL5+F1Xfcu2hideR8D6XRK54WV1GFWkvs0ZrQ0usw+bxC/s3BMAjygOWnR8H3uOs7ow3S2afZshgq8zl3Arj7puHsX7QcbDMwnr/GrvNWcxX2U2X33oOTajmkS27PxbgR5UKVx7gJalbosVrnrOJJ3Xddd5S7iUOlnaCWM/KWwsYmnJvj4vFIfl1Lryq2VjR1wNgI8oEnL+ehVDOeG6eE8Hl1UeUxK78KbzjbjdAaYUZk0acDjYN+mM2CLlDoDh7Sh5ioEeQCfamnE4U3NIV7XdZfRxrl3Dxa5CzgzwcfnFdnpZozmZ92lxwXYgwAPaNl1DOeGqcYQb5W7gCO6KfGxn842kzRG8F+x3WlbXI1wiIGH03fL+aiGcOxtRKxzF3FmV7EN8j44Iw8Yur7vV9HWZ7IqQ7wU3n3MXccRLYYWBKSO1nXuOgqzTu8xpSoyXMzI4wFPIMADmpW6Ep7FcGbFt/ahrCbjKOhw++lsczWdbf6I7evhKnM5cFSp2+5qOtt8jGGH01Wc95quxVXUegLPYzvm+l/T2eaNrjxgwFrrHKoqxOu67nlsPxe0dL/UUmfnPoYyZWhXpT8epdd3bh4PeAIBHtC0IYZ4qeOK87vK+dhPZ5vL6Wzzbjrb/H+xHY3jXESakTrtrqazzYeIeHiNT/JWldWrNJ6yCsv5aBXDGqX5qXFsO0T/NZ1t/pjONi+FecCQ9H2/iLamb0RUEuJ1XfcyIj5EW+Hd+6F13z2ig+mvin48jNH8i9WAf2/hIH/LXQDAqS3no7vpbPMq2pr3/zVX09nmPp0DWLLfo70F+Ks0SvP6HOdSpQXg5xHxUwjsaMh0trmM7Wv6x9i+T4xz1lOYVSWjMz/1NrbP5dDfqx5e2++ms81dRPwWEbc1BbIAT/RwHWjJTdd1P0bEq77vi9ow2nXdRWyDu0nmUo7tPobbfRd93991XbcO98YR2/PUarh/+jXc/0YUHrZCyQR4wCAs56NFClaKGXN4Yi+ns80/l/PRInchA/Q8IibT2ebVKR7/FGw8j4h/hA8CVC69Lz8EGn9/9Nct7RI/pvuIeJG7iKdYzkf309nmOiL+yF1LQR5e76+ns819bLtTfo/t+YarjHUBHF3f96uu61bRXqB0FRGTruuuSzmLK3UGvos276d+KS0szeA2tiPkh66WQOg2hrMO9TXGZ8ITCfDgMBbPK7Kcj95PZ5vvYzhngt1MZ5soOMSrYbfcU13E9vF/Hdsb1V+f0l3xKNyYRMT36c8WP4jToNQhOk5/+/ivf0x/Ts5ZTyNenKO791RSR/x1DKcjfh8Xsd2c8TwiYjrbRGyvk3cR8c+Hv675+QeIiFfR5kaOcUR87LpuERFvc42J67puEtugoNV1inXf929yF1GAX0KAF1FJINT3/brrurto9/dyF7eCd3g6AR4cxkJ6ZZbz0fWj0WxD8G4629wVOpprnbuAMxjH9sPVy9Rd8bAY+7/p/1/F9n3k8evx+0f/zHsMpbqczjYfH/99eL2e2qsWurJSR/yPMZzNNIf4r/uVFOyt0t/+nv58+Pv7Uq73nwT4jwkhYcDS+L/30W74cBURVynI++Vc4/1Sx93P0f5n3NKPiDgLgVBE1Hee2tDHaP6WuwComQAPGKJnsd35Oc5cxzlcRMTH6WzzrJRFvQepEyN3Ged0EduOo8mjf/Y6SyVwuIfXM+exqPTcuy95FZ8Jp9jZ5JM//3Mt+eS6uvrCf38f266+L/mf2P25Gcce91PL+ej/7PrvAs16G9ugq+WNP1exDfLuYrtwf3vssCF12/0U287tlh/LB7d931fRcXUmQw+Eahmf+WDIYzTvo5JuSSiVAA8YnHQOz4uI+BjD+LDzMM7xWYG73oe+cxDgW+6W89F17iKOKV2Hn0XEv2IY1+FcJl/5/56fq4hHSrsHATLo+/6+67rriPiQu5YzeNis8q7runU8Out03+68FNhdxnYU+SSGdf28D913nxpyIBRRWSA08K5J4zPhQAI8YJBS99dDiDcEl/FnJ15JN09DvYkF2MVdbLvGm/MoxBvKZhraPvsW2EPf97dd191Gns0EuYwjdeZFRHRdF7E9UmD96N95GI3846N/Zkx5xnMFSyUQqjIQGmrXpPGZcKD/m7sAgFzSWUJNdTV8w2VE3OQu4hO/f/tfARik+4gobdPFUaXRzk0GlHzWOncBQFGuQ2fuOP4csT+J7Ujk15/8s6GHd7d937c0RvyYahsjeSy1/txVdQ0eyb3Rt3A4AR4waMv5aBERi8xlnNPz6WxTUoi3yl0AQIGaD+8epBBvSJtphuzfuQsAypE6aLz/8zVeI183xGCk2kAodZEObRpBlc8VlEaABwxeOltolbuOM7qazjYvcxcREbGcj9ZhRz7AYw/h3WA+4KfNNBbo2jeY1zSwm7QQv8hdB8V6UemoxLNIgdDQApLaf95auwefamg/L5yEAA9g60UMa2Hp3XS2ucpdRLLKXQBAIQYX3j0Q4g2CRVjgc17FsD6HsZu3fd+vchdRgaGdL/ZL7gIOVHsAuY+132E4DgEeQESkMWVDO4fhZjrbTHIXEcP70AHwOXcR8cMQw7sHQry2pbOHAf7i0SjNIX0O4+tWfd+/yV1EJYYWCFV9nzywMZpDem3CSQnwAJK0aPoidx1n9mE621zmLGA5H92GD+zAsN3FtvNunbuQ3FKI90O4LrTG8wl8UVqUt4GDiO3xCkP7TP5kKQAfSlDSys85lLGSQ/k54eQEeEBExEXuAkqRdocP6cPjRUR8nM42uV8DrdyMA+xrEdvwTsCRpA01z0Lo05Kh7DYHniidh/c2dx1kdR/OvXuKoUy0qX185oMhrH1U3y0JJRHgARERWTuwSpN2/y8yl3FOJYR4dmcBQ/R2OR9dC+/+WwrxvgvBTyvWuQsAypfGJi4yl0E+Lyz6P8kQAqG7NH6yegMZo2l9B45IgAfwGcv56DoiVrnrOKPLiPiY65unzsd1ru8PcGb3EfFiOR+9yV1IyVKw+Sws5rbg37kLAOrQ9/3QPoexdd33/Sp3ETUayBjN1gKh1n6eTy1yFwAtEeABfNmLGFaodDmdbW4yfn8jcxik3OdQcnYP5921vtByFMv56D5tqnmVuxYO0vpOc+C4XoT3jSG57vt+kbuIyrU+RrO1++bWfp7HmumWhFII8AC+IO38fxHDOoPnKmOIdxvDeqzhQe4zKDmf98v56Ic0HpI9LOej9xHxQwxrY01LXN+BnaWOomchxBsC4d1xtPxZ+ra1QKjxMZqtdxfC2QnwAL4iLbJe567jzK6ms83Vub9pCkxbOZga4LF1bLvudJEdIF2TfwhjeWrU6iIVcCJCnbINPwAADyRJREFUvEF4K7w7jsbHaLbaXdhq0NXq6xCyEeABfEMacza0RdebHCFeRLyPdncOAsP0PiJ+SGd9cqBHIzWH1iFftbRJB2AvQrymXfd9/yZ3EY1pNehqNRBq8ecyPhNOQIAHsIM0umuRu44zuzn32VxpgW9oYSnQpnWkrjvhxfGlzTXfxfCuzTVa5S4AqJcQr0nGZp5A3/ctjtFcpPeA5qSga525jGMzUQlOQIAHsLtXMbwPjh8zhHiLGN7jDLTjPiLeLuej73Tdndajbrxn0d4CSEuaXHgDzudRiLfIXAqHE96dVmtdXa12FT5o7flq7eeBIgjwAHaUOiiexXAWotYR8TbyLIoO7dzBEq1i+/wDu1tExHfL+ehN5joGZTkfrZbz0Xexfc8ayjW6Jv/MXQBQv77v7/u+vw4hXq3uI+KZ8O7kWgq87lNXYctaOgfvttVuSchNgAewh4GEeLexHfv23XI+ep9j9NtyProL4VEu64i4Xs5Hz8LYM9jVbWyDu2vjMvNJwamxmuVZ5y4AaEcK8Wz2q8tdbMO7Ve5CWtfYGM3Ww7vo+/4u2rlPaik8hqII8AD2lMKl1s5pu49tYPbdcj56UcLYt7QQa5Tm+axjG9x9l8aYAt+2iu2GhxfL+WiduRbiL2M1BXnlWOcuAGhL6uL6IdoJKlq2im1453Pd+bQSfLXUnfY1rTxfrfwcUJy/5S4AoEbL+WgxnW2+j4iXuWs50Coifi04sHkREX9ExEXuQhq2ju15XYvMdUBNFrH9vVlnroMvSM/N9XS2eRsRryPiKmtBw2bRFji6vu/vuq77LiI+RMQkczl83tu+79/kLmKAfov673vWA+rY/DXqX1cyPhNOSAcewBMt56NXUecuo/vYLj7/sJyPnpUc3KQF2Ge562jUOnTcwT7uI+J9/Dkqc525HnawnI/WOvLyMlYWOJV0Lt6zMHq/NA/n3b3JXcgQNTJGs8Z1lidpZIym8ZlwQgI8gMNcRz07y9exHf35sPhcRd2pTudcHM9dCO5gHw/vQd8t56NXgrs6fRLkvY36F7ZqscpdANC+FBT9EPV8LmvZbUR8N6DuqVLVHoANZXzmg9qfr9rrh6IZoQlwgOV8dD+dba4j4mOUO+bxNiJ+KeFcu6dKI0sjIm5y11KxVWxH/q0y13EOf89dANV76FT+tZbNDuwmBbBvIuLNdLa5ioifI+IyY0mtE5QCZ5G6WH7ouu5NbEcnc173EXGdur/Ir+YxmncDPDOx5jGaxmfCienAg8P8mLsA8kuLuy9y1/GJ+9h2GHy3nI9etBDapG4xnXj7W8Sf41JXmWs5l3HuAqjSQ2j3Yjkf/b/UbTe0xYNBWc5Hi+V89ENsuzbeh7DpFP6ZuwBgWFI33nehA/ic3se26054V4jKx2gOrfuu9jGag3u+4Nx04AEcwXI+Wk1nm1cR8S5zKavYdowsMtdxEjrxdnYfEb9ExMK4P/iq+9h2Kf+2nI8sOg1UCmrvIuLVdLZ5HhH/iIjnUW5nfU3WuQsAhqfv+3VEPOu67nlsP5+NsxbUrlVEvDUus1i3UWcX3lDvyVdR3/N1L7iH0xPgARzJcj56P51tvo88N12L2I7JbL5bJIV497EN8Syu/tU6tp2Xt8v5qNYdl3Bqd7EdK3Q7hPdM9pOC3NuIuBbmHcU6dwHAcKWF5duu617Gdqym9/LjWMc2uFtkroOvq3GM5l0K4IeoxudLeAdnIMADOK5XsT1L5xzn6azjzy6rQYU1y/nodjrbrGMb4jm76M+zulaZ64ASrWO7o/X3EG6zh0/CvMuI+CkiJuG6sw8hOZBd3/fvu65bxPaMqZ9DkPdU6xDcVaPv+9uu6+6jrtf7YMcxVvp8/Za7ABgCAR7AES3no/vpbPMsIv4Vp7vxuo1tWDPo3U7L+eguPdavo94Dnw+xju0HHGMy4a9WsQ0Nfo+IO78fHMOjMZsxnW0uYtuV92NsA71xtsIKJzAHStH3/X1EvOm67n1s38Nfh/fvXa1DcFerVWxf77VY5C4gs5rGnhqfCWciwAM4skch3h9H/LL38eeYzPURv27V0sLgq+ls81tsu/HGeSs6CwEu/GkV21Dl37EN61ZZq2EQ0rVnkf73EOhNYtuZ9xDqsf39BChKCvIWEbFIZ+T9HN63v2QVEb9YpK/ab1FPgHebfj+HrKYxmt4X4EwEeAAnkLrDrmMbKh3iLrah3eLwqtqVFu2/m842b6LNsTjr0G3HsK1i+3vw74e/9rtAKVKg9zBuMyIi0sjNy9huLPkx/XVr16ZvGfoiHJzDZQjLn+zRGXnj2C6a/xTD2BD4NevYXs9+GfBZZC25jcPXJM7FOMa63s9/z10ADIUAD4iI7e5xY46OazkfLaazzY/xtB1Ui9gGd86O2cNyPnoznW3eRxvnWzwsCHsdMASr9OddRPxv+vNeRx21ejxy80Hq1HsI9cYR8X1sr1OT81Z3Nv/MXQAMQM33usVIQdWb2I7YvIw/u/LG2Yo6r4fPHb/ptmtL3/f3XdfdRh1deIN/7Xm+gM/5P7kLAGjddLb5GLstzq0j4pfYdlkJUw+UFkqvYvsBfJy1mN2tY3sj/LsRmcMxnW0mEfExdx1Hdhd/dt/cx58L+ffxZ6ihiw4eSe8FEX926/1P+utIf3/5mf8st8e/6xF/dspGRKyE8EDNUpj3U/w5Jrkl60ifO4R2AFAuAR7AiaUg6Y/4cojkTLMTS6PMfortTrZx3mr+y21sx0+sdNoN03S2Gcd/d+o+dObksI4/F+A/Z/WZf3Zn4wGcz6Nuvk8dEvQ9Dtg/R+gODFYaszmJP886Heer5knWsX2P/z22Z42ts1YDAOxEgAdwBilA+hh/Lsg/HJ7+i8Ww80rPxfP488P3Oa3jzw/OdzoTAACgPl3XPYxAvozt54pxlBPqPWzI+D39eSewA4A6CfAAzmQ621zFdpzjL8v5aJG3Gh6kQO/hTKIf4zhjyh5Git3FtpPpLnQoAQBA07qum8SfYd7f05+nGIO8Tv97GFX+8Pd3fd/7zAEAjRDgAcAXPDqPaBf3RmACAABfkjr3nhrmCecAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v/24IAEAAAAQND/1+0IVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AlHxsDwoTtjWwAAAABJRU5ErkJggg== mediatype: image/png install: spec: clusterPermissions: - rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' serviceAccountName: kubeflow-operator deployments: - name: kubeflow-operator spec: replicas: 1 selector: matchLabels: name: kubeflow-operator strategy: {} template: metadata: labels: name: kubeflow-operator spec: containers: - command: - kfctl env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: kubeflow-operator image: aipipeline/kubeflow-operator:v0.1.0 imagePullPolicy: Always name: kubeflow-operator resources: {} serviceAccountName: kubeflow-operator strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - supported: false type: MultiNamespace - supported: true type: AllNamespaces maturity: alpha links: - name: Kubeflow url: https://www.kubeflow.org/ provider: name: Kubeflow maintainers: - name: Animesh Singh email: singhan@us.ibm.com - name: Tommy Li email: tommy.chaoping.li@ibm.com - name: Weiqiang Zhuang email: wzhuang@us.ibm.com keywords: - Kubeflow - Operator - IBMCloud - GCP - OpenShift version: 0.1.0 selector: matchLabels: component: kubeflow-operator ================================================ FILE: deploy/olm-catalog/kubeflow/1.0.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/1.0.0/kubeflow.v1.0.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", "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": "namespace", "value": "istio-system" } ], "repoRef": { "name": "manifests", "path": "istio/cluster-local-gateway" } }, "name": "cluster-local-gateway" }, { "kustomizeConfig": { "parameters": [ { "name": "clusterRbacConfig", "value": "OFF" } ], "repoRef": { "name": "manifests", "path": "istio/istio" } }, "name": "istio" }, { "kustomizeConfig": { "parameters": [ { "name": "namespace", "value": "istio-system" } ], "repoRef": { "name": "manifests", "path": "istio/add-anonymous-user-filter" } }, "name": "add-anonymous-user-filter" }, { "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" ], "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" ], "parameters": [ { "name": "userid-header", "value": "kubeflow-userid" } ], "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", "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": "" }, { "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" ], "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": "johnDoe@acme.com" } ], "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/v1.0.0.tar.gz" } ], "version": "v1.0.0" } }]' 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-03-19T00:00:00Z' containerImage: aipipeline/kubeflow-operator:v1.0.0 certified: 'False' name: kubeflow.v1.0.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 1.0 and above. Check [Kubeflow Operator documentation](https://github.com/kubeflow/kfctl/blob/master/operator.md) for more details." displayName: Kubeflow icon: - base64data: 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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v/24IAEAAAAQND/1+0IVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AlHxsDwoTtjWwAAAABJRU5ErkJggg== mediatype: image/png install: spec: clusterPermissions: - rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' serviceAccountName: kubeflow-operator deployments: - name: kubeflow-operator spec: replicas: 1 selector: matchLabels: name: kubeflow-operator strategy: {} template: metadata: labels: name: kubeflow-operator spec: containers: - command: - kfctl env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: kubeflow-operator image: aipipeline/kubeflow-operator:v1.0.0 imagePullPolicy: Always name: kubeflow-operator resources: {} serviceAccountName: kubeflow-operator strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - supported: false type: MultiNamespace - supported: true type: AllNamespaces maturity: alpha links: - name: Kubeflow url: https://www.kubeflow.org/ provider: name: Kubeflow maintainers: - name: Animesh Singh email: singhan@us.ibm.com - name: Tommy Li email: tommy.chaoping.li@ibm.com - name: Weiqiang Zhuang email: wzhuang@us.ibm.com keywords: - Kubeflow - Operator - IBMCloud - GCP - OpenShift version: 1.0.0 replaces: kubeflow.v0.1.0 selector: matchLabels: component: kubeflow-operator ================================================ FILE: deploy/olm-catalog/kubeflow/1.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/1.1.0/kubeflow.v1.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", "namespace": "kubeflow" }, "spec": { "applications": [ { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/istio-stack" } }, "name": "istio-stack" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cluster-local-gateway" } }, "name": "cluster-local-gateway" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/istio" } }, "name": "istio" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/add-anonymous-user-filter" } }, "name": "add-anonymous-user-filter" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "application/v3" } }, "name": "application" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/bootstrap" } }, "name": "bootstrap" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cert-manager-crds" } }, "name": "cert-manager-crds" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cert-manager-kube-system-resources" } }, "name": "cert-manager-kube-system-resources" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cert-manager" } }, "name": "cert-manager" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm" } }, "name": "kubeflow-apps" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "metacontroller/base" } }, "name": "metacontroller" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/metadata" } }, "name": "metadata" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/spark-operator" } }, "name": "spark-operator" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "knative/installs/generic" } }, "name": "knative" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "kfserving/installs/generic" } }, "name": "kfserving" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/spartakus" } }, "name": "spartakus" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/tensorboard" } }, "name": "tensorboard" } ], "repos": [ { "name": "manifests", "uri": "https://github.com/kubeflow/manifests/archive/v1.1.0.tar.gz" } ], "version": "v1.1.0" } } ] 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-03-19T00:00:00Z' containerImage: aipipeline/kubeflow-operator:v1.1.0 certified: 'False' name: kubeflow.v1.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 1.0 and above. Check [Kubeflow Operator documentation](https://github.com/kubeflow/kfctl/blob/master/operator.md) for more details." displayName: Kubeflow icon: - base64data: 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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v/24IAEAAAAQND/1+0IVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AlHxsDwoTtjWwAAAABJRU5ErkJggg== mediatype: image/png install: spec: clusterPermissions: - rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' serviceAccountName: kubeflow-operator deployments: - name: kubeflow-operator spec: replicas: 1 selector: matchLabels: name: kubeflow-operator strategy: {} template: metadata: labels: name: kubeflow-operator spec: containers: - command: - kfctl env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: kubeflow-operator image: aipipeline/kubeflow-operator:v1.1.0 imagePullPolicy: Always name: kubeflow-operator resources: {} serviceAccountName: kubeflow-operator strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - supported: false type: MultiNamespace - supported: true type: AllNamespaces maturity: alpha links: - name: Kubeflow url: https://www.kubeflow.org/ provider: name: Kubeflow maintainers: - name: Animesh Singh email: singhan@us.ibm.com - name: Tommy Li email: tommy.chaoping.li@ibm.com - name: Weiqiang Zhuang email: wzhuang@us.ibm.com keywords: - Kubeflow - Operator - IBMCloud - GCP - OpenShift version: 1.1.0 replaces: kubeflow.v1.0.0 selector: matchLabels: component: kubeflow-operator ================================================ FILE: deploy/olm-catalog/kubeflow/1.2.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/1.2.0/kubeflow.v1.2.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", "namespace": "kubeflow" }, "spec": { "applications": [ { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/istio-1-3-1-stack" } }, "name": "istio-stack" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cluster-local-gateway-1-3-1" } }, "name": "cluster-local-gateway" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/istio" } }, "name": "istio" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/add-anonymous-user-filter" } }, "name": "add-anonymous-user-filter" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "application/v3" } }, "name": "application" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/bootstrap" } }, "name": "bootstrap" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cert-manager-crds" } }, "name": "cert-manager-crds" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cert-manager-kube-system-resources" } }, "name": "cert-manager-kube-system-resources" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/cert-manager" } }, "name": "cert-manager" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm" } }, "name": "kubeflow-apps" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "metacontroller/base" } }, "name": "metacontroller" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/metadata" } }, "name": "metadata" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/spark-operator" } }, "name": "spark-operator" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "knative/installs/generic" } }, "name": "knative" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "kfserving/installs/generic" } }, "name": "kfserving" }, { "kustomizeConfig": { "repoRef": { "name": "manifests", "path": "stacks/ibm/application/spartakus" } }, "name": "spartakus" } ], "repos": [ { "name": "manifests", "uri": "https://github.com/kubeflow/manifests/archive/v1.2.0.tar.gz" } ], "version": "v1.2.0" } } ] 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-03-19T00:00:00Z' containerImage: aipipeline/kubeflow-operator:v1.2.0 certified: 'False' name: kubeflow.v1.2.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 1.2.0 and above. Check [Kubeflow Operator documentation](https://github.com/kubeflow/kfctl/blob/master/operator.md) for more details." displayName: Kubeflow icon: - base64data: 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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v/24IAEAAAAQND/1+0IVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AlHxsDwoTtjWwAAAABJRU5ErkJggg== mediatype: image/png install: spec: clusterPermissions: - rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' serviceAccountName: kubeflow-operator deployments: - name: kubeflow-operator spec: replicas: 1 selector: matchLabels: name: kubeflow-operator strategy: {} template: metadata: labels: name: kubeflow-operator spec: containers: - command: - kfctl env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: kubeflow-operator image: aipipeline/kubeflow-operator:v1.2.0 imagePullPolicy: Always name: kubeflow-operator resources: {} serviceAccountName: kubeflow-operator strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - supported: false type: MultiNamespace - supported: true type: AllNamespaces maturity: alpha links: - name: Kubeflow url: https://www.kubeflow.org/ provider: name: Kubeflow maintainers: - name: Animesh Singh email: singhan@us.ibm.com - name: Tommy Li email: tommy.chaoping.li@ibm.com - name: Weiqiang Zhuang email: wzhuang@us.ibm.com - name: Evan Hataishi email: evan.hataishi@ibm.com keywords: - Kubeflow - Operator - IBMCloud - GCP - OpenShift version: 1.2.0 replaces: kubeflow.v1.1.0 selector: matchLabels: component: kubeflow-operator ================================================ FILE: deploy/olm-catalog/kubeflow/kubeflow.package.yaml ================================================ channels: - currentCSV: kubeflow.v1.2.0 name: alpha defaultChannel: alpha packageName: kubeflow ================================================ FILE: deploy/operator.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: kubeflow-operator spec: replicas: 1 selector: matchLabels: name: kubeflow-operator template: metadata: labels: name: kubeflow-operator spec: serviceAccountName: kubeflow-operator containers: - name: kubeflow-operator # Replace this with the built image name image: aipipeline/kubeflow-operator:v1.2.0 command: - kfctl imagePullPolicy: Always env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME valueFrom: fieldRef: fieldPath: metadata.name ================================================ FILE: deploy/params.yaml ================================================ varReference: - path: subjects/namespace kind: ClusterRoleBinding apiGroup: rbac.authorization.k8s.io/v1 ================================================ FILE: deploy/role.yaml ================================================ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: null labels: kubernetes.io/bootstrapping: rbac-defaults name: kubeflow-operator rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' ================================================ FILE: deploy/service_account.yaml ================================================ apiVersion: v1 kind: ServiceAccount metadata: name: kubeflow-operator ================================================ FILE: go.mod ================================================ module github.com/kubeflow/kfctl/v3 require ( cloud.google.com/go v0.57.0 github.com/Azure/go-autorest v13.3.3+incompatible // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Sirupsen/logrus v0.0.0-00010101000000-000000000000 // indirect github.com/aws/aws-sdk-go v1.27.1 github.com/cenkalti/backoff v2.2.1+incompatible github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect github.com/deckarep/golang-set v1.7.1 github.com/docker/docker v1.13.1 // indirect github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c // indirect github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 // indirect github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 // indirect github.com/fatih/color v1.7.0 github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-yaml/yaml v2.1.0+incompatible github.com/gogo/protobuf v1.3.1 github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e github.com/google/go-cmp v0.4.0 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/hashicorp/go-getter v1.0.2 github.com/hashicorp/go-version v1.2.0 github.com/imdario/mergo v0.3.8 github.com/jlewi/cloud-endpoints-controller v0.0.0-20200604211613-aff0aaad5602 github.com/kubernetes-sigs/application v0.8.1 github.com/onrik/logrus v0.5.1 github.com/operator-framework/operator-sdk v0.13.0 github.com/otiai10/copy v1.0.2 github.com/pkg/errors v0.8.1 github.com/prometheus/common v0.7.0 github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.4.0 github.com/tektoncd/pipeline v0.10.1 github.com/tidwall/gjson v1.6.0 github.com/tidwall/pretty v1.0.1 // indirect go.uber.org/zap v1.12.0 // indirect golang.org/x/crypto v0.0.0 golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d google.golang.org/api v0.25.0 google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84 gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect gopkg.in/yaml.v2 v2.2.8 k8s.io/api v0.17.0 k8s.io/apiextensions-apiserver v0.0.0 k8s.io/apimachinery v0.17.1 k8s.io/cli-runtime v0.0.0 k8s.io/client-go v12.0.0+incompatible k8s.io/code-generator v0.18.1 // indirect k8s.io/kubernetes v1.16.2 sigs.k8s.io/controller-runtime v0.4.0 sigs.k8s.io/kustomize/kyaml v0.1.10 // indirect sigs.k8s.io/kustomize/v3 v3.2.0 sigs.k8s.io/yaml v1.1.0 ) replace ( git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999 github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.0.5 github.com/go-openapi/jsonpointer => github.com/go-openapi/jsonpointer v0.17.0 github.com/go-openapi/jsonreference => github.com/go-openapi/jsonreference v0.17.0 github.com/go-openapi/spec => github.com/go-openapi/spec v0.18.0 github.com/go-openapi/swag => github.com/go-openapi/swag v0.17.0 github.com/mitchellh/go-homedir => github.com/mitchellh/go-homedir v1.0.0 github.com/otiai10/copy => github.com/otiai10/copy v1.0.2 github.com/otiai10/mint => github.com/otiai10/mint v1.3.0 github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2-0.20180428102519-11635eb403ff // indirect golang.org/x/crypto => golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 k8s.io/api => k8s.io/api v0.0.0-20190620084959-7cf5895f2711 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20190620085554-14e95df34f1f k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719 k8s.io/apiserver => k8s.io/apiserver v0.0.0-20190620085212-47dc9a115b18 k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20190620085706-2090e6d8f84c k8s.io/client-go => k8s.io/client-go v0.0.0-20190620085101-78d2af792bab k8s.io/cloud-provider => k8s.io/cloud-provider v0.0.0-20190620090043-8301c0bda1f0 k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.0.0-20190620090013-c9a0fc045dc1 k8s.io/code-generator => k8s.io/code-generator v0.0.0-20190612205613-18da4a14b22b k8s.io/component-base => k8s.io/component-base v0.0.0-20190620085130-185d68e6e6ea k8s.io/cri-api => k8s.io/cri-api v0.0.0-20190531030430-6117653b35f1 k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.0.0-20190620090116-299a7b270edc k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.0.0-20190620085325-f29e2b4a4f84 k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.0.0-20190620085942-b7f18460b210 k8s.io/kube-proxy => k8s.io/kube-proxy v0.0.0-20190620085809-589f994ddf7f k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.0.0-20190620085912-4acac5405ec6 k8s.io/kubectl => k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51 k8s.io/kubelet => k8s.io/kubelet v0.0.0-20190620085838-f1cb295a73c9 k8s.io/kubernetes => k8s.io/kubernetes v1.15.0 k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.0.0-20190620090156-2138f2c9de18 k8s.io/metrics => k8s.io/metrics v0.0.0-20190620085625-3b22d835f165 k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.0.0-20190620085408-1aef9010884e github.com/kubernetes-sigs/application => sigs.k8s.io/application v0.0.0-20190404151855-67ae7f915d4e sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.2.0 sigs.k8s.io/kustomize/v3 => sigs.k8s.io/kustomize/v3 v3.2.0 ) go 1.13 ================================================ FILE: go.sum ================================================ bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.47.0 h1:1JUtpcY9E7+eTospEwWS2QXP3DEn7poB3E2j0jN74mM= cloud.google.com/go v0.47.0/go.mod h1:5p3Ky/7f3N10VBkhuR5LFtddroTiMyjZV/Kj5qOQFxU= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg= contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= contrib.go.opencensus.io/exporter/stackdriver v0.12.8 h1:iXI5hr7pUwMx0IwMphpKz5Q3If/G5JiWFVZ5MPPxP9E= contrib.go.opencensus.io/exporter/stackdriver v0.12.8/go.mod h1:XyyafDnFOsqoxHJgTFycKZMrRUrPThLh2iYTJF6uoO0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE= github.com/Azure/azure-sdk-for-go v21.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v28.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest v11.1.2+incompatible h1:viZ3tV5l4gE2Sw0xrasFHytCGtzYCrT+um/rrSQ1BfA= github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v13.3.3+incompatible h1:oYzB8/Ldlo1Bq7By79KO/1nxWuoLnEoGQiToUM2rBZo= github.com/Azure/go-autorest v13.3.3+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3 h1:OZEIaBbMdUE/Js+BQKlpO81XlISgipr6yDJ+PSwsgi4= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.1 h1:pZdL8o72rK+avFWl+p9nE8RWi1JInZrWJYlnpfXJwHk= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/autorest/to v0.1.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.0/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/GoogleCloudPlatform/cloud-builders/gcs-fetcher v0.0.0-20191203181535-308b93ad1f39/go.mod h1:yfGmCjKuUzk9WzubMlW2zwjhCraIc/J+M40cufdemRM= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20181220005116-f8e995905100/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Rican7/retry v0.1.0/go.mod h1:FgOROf8P5bebcC1DS0PdOQiqGUridaZvikzUmkFW6gg= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/ant31/crd-validation v0.0.0-20180702145049-30f8a35d0ac2/go.mod h1:X0noFIik9YqfhGYBLEHg8LJKEwy7QIitLQuFMpKLcPk= github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1 h1:MXnqY6SlWySaZAqNnXThOvjRFdiiOuKtC6i7baFdNdU= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/bazelbuild/bazel-gazelle v0.0.0-20181012220611-c728ce9f663e/go.mod h1:uHBSeeATKpVazAACZBDPL/Nk/UhQDDsJWDlqYJo8/Us= github.com/bazelbuild/buildtools v0.0.0-20180226164855-80c7f0d45d7e/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/brancz/gojsontoyaml v0.0.0-20190425155809-e8bd32d46b3d/go.mod h1:IyUJYN1gvWjtLF5ZuygmxbnsAyP3aJS6cHzIuZY50B0= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/prettybench v0.0.0-20150116022406-03b8cfe5406c/go.mod h1:Xe6ZsFhtM8HrDku0pxJ3/Lr51rwykrzgFwpmTzleatY= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U= github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.0.0-20170928000206-9ce5d979ffda/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudevents/sdk-go v0.0.0-20190509003705-56931988abe3/go.mod h1:j1nZWMLGg3om8SswStBoY6/SHvcLM19MuZqwDtMtmzs= github.com/cloudflare/cfssl v0.0.0-20180726162950-56268a613adf/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/codedellemc/goscaleio v0.0.0-20170830184815-20e2ce2cf885/go.mod h1:JIHmDHNZO4tmA3y3RHp6+Gap6kFsNf55W9Pn/3YS9IY= github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0= github.com/container-storage-interface/spec v1.1.0/go.mod h1:6URME8mwIBbpVyZV93Ce5St17xBiQJQY67NDsuohiy4= github.com/containerd/console v0.0.0-20170925154832-84eeaae905fa/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.0.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containernetworking/cni v0.6.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/prometheus-operator v0.34.0 h1:TF9qaydNeUamLKs0hniaapa4FBz8U8TIlRRtJX987A4= github.com/coreos/prometheus-operator v0.34.0/go.mod h1:Li6rMllG/hYIyXfMuvUwhyC+hqwJVHdsDdP21hypT1M= github.com/coreos/rkt v1.30.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U= github.com/cpuguy83/go-md2man v1.0.4/go.mod h1:N6JayAiVKtlHSnuTCeuLSQVs75hb8q+dYQLjr7cDsKY= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/cyphar/filepath-securejoin v0.0.0-20170720062807-ae69057f2299/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= github.com/cznic/internal v0.0.0-20180608152220-f44710a21d00/go.mod h1:olo7eAdKwJdXxb55TKGLiJ6xt1H0/tiiRCWKVLmtjY4= github.com/cznic/lldb v1.1.0/go.mod h1:FIZVUmYUVhPwRiPzL8nD/mpFcJ/G7SSXjjXYG4uRI3A= github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= github.com/cznic/ql v1.2.0/go.mod h1:FbpzhyZrqr0PVlK6ury+PoW3T0ODUV22OeWIxcaOrSE= github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= github.com/cznic/zappy v0.0.0-20160723133515-2533cb5b45cc/go.mod h1:Y1SNZ4dRUOKXshKUbwUapqNncRrho4mkjQebgEHZLj8= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= github.com/d2g/dhcp4client v0.0.0-20170829104524-6e570ed0a266/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dhui/dktest v0.3.0/go.mod h1:cyzIUfGsBEbZ6BT7tnXqAShHSXCZhSNmFl70sZ7c1yc= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20170726174610-edc3ab29cdff/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.7.3-0.20190103212154-2b7e084dc98b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libnetwork v0.0.0-20180830151422-a9cd636e3789/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 h1:aZtFdDNWY/yH86JPR2WX/PN63635VsE/f/nXNPAbYxY= github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w= github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v0.0.0-20160318181535-f6a740d52f96/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20180820084758-c7ce16629ff4/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v0.1.1 h1:qXBXPDdNncunGs7XeEpsJt8wCjYBygluzfdLO0G5baE= github.com/go-logr/zapr v0.1.1/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonreference v0.17.0 h1:yJW3HCkTHg7NOA+gZ83IPHzUSnUzGXhGmsdiCcMexbA= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.17.2/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/spec v0.18.0 h1:aIjeyG5mo5/FrvDkpKKEGZPmF9MPHahS72mzfVqeQXQ= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48 h1:X+zN6RZXsvnrSJaAIQhZezPfAfvsqihKKR8oiLHid34= github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang-migrate/migrate/v4 v4.6.2/go.mod h1:JYi6reN3+Z734VZ0akNuyOJNcrg45ZL7LDBMW3WGJL0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v0.0.0-20160127222235-bd3c8e81be01/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450 h1:7xqw01UYS+KCI25bMrPxwNYkSns2Db1ziQPpVq99FpE= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995 h1:f5gsjBiF9tRRVomCvrkGMMWI8W1f2OBFar2c5oakAP0= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e h1:KhcknUwkWHKZPbFy2P7jH5LKJ3La+0ZeknkkmrSgqb0= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/cadvisor v0.33.2-0.20190411163913-9db8c7dee20a/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20200115214256-379933c9c22b/go.mod h1:Wtl/v6YdQxv397EREtzwgd9+Ud7Q5D8XMbi3Zazgkrs= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-licenses v0.0.0-20191112164736-212ea350c932/go.mod h1:16wa6pRqNDUIhOtwF0GcROVqMeXHZJ7H6eGDFUh5Pfk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/licenseclassifier v0.0.0-20190926221455-842c0d70d702/go.mod h1:qsqn2hxC+vURpyBRygGUuinTO42MFRLcsmQ/P8v94+M= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s= github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww= github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0= github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8 h1:L9JPKrtsHMQ4VCRQfHvbbHBfB2Urn8xf6QZeXZ+OrN4= github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= github.com/gophercloud/gophercloud v0.2.0 h1:lD2Bce2xBAMNNcFZ0dObTpXkGLlVIb33RPVUNVpw6ic= github.com/gophercloud/gophercloud v0.2.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190203031600-7a902570cb17/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20170330212424-2500245aa611/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.4/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-health-probe v0.2.1-0.20181220223928-2bf0a5b182db/go.mod h1:uBKkC2RbarFsvS5jMJHpVhTLvGlGQj9JJwkaePE3FWI= github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-getter v1.0.2 h1:ba+UwCRuxJ7+rS+cO6JnQZUrweQjmEAkwKu9r7+HCpM= github.com/hashicorp/go-getter v1.0.2/go.mod h1:q+PoBhh16brIKwJS9kt18jEtXHTg2EGkmrA9P7HVS+U= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v0.0.0-20160711231752-d8c773c4cba1/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/heketi/heketi v0.0.0-20181109135656-558b29266ce0/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= github.com/heketi/rest v0.0.0-20180404230133-aa6a65207413/go.mod h1:BeS3M108VzVlmAue3lv2WcGuPAX94/KN63MUURzbYSI= github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= github.com/heketi/utils v0.0.0-20170317161834-435bc5bdfa64/go.mod h1:RYlF4ghFZPPmk2TC5REt5OFwvfb6lzxFWrTWB+qs28s= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/improbable-eng/thanos v0.3.2/go.mod h1:GZewVGILKuJVPNRn7L4Zw+7X96qzFOwj63b22xYGXBE= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jenkins-x/go-scm v1.5.65/go.mod h1:MgGRkJScE/rJ30J/bXYqduN5sDPZqZFITJopsnZmTOw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jlewi/cloud-endpoints-controller v0.0.0-20200604211613-aff0aaad5602 h1:qW4JMBhHsZmvD+YBdnqZZX/T9Jfy3ZXDZBMU112vK/8= github.com/jlewi/cloud-endpoints-controller v0.0.0-20200604211613-aff0aaad5602/go.mod h1:Ny/iFXrdxEFMbbtX5W2xoxmOmug03FX+6Z4G2/0HKuY= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.0.0-20141017032234-72f9bd7c4e0c/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jsonnet-bundler/jsonnet-bundler v0.1.0/go.mod h1:YKsSFc9VFhhLITkJS3X2PrRqWG9u2Jq99udTdDjQLfM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jteeuwen/go-bindata v0.0.0-20151023091102-a0ff2567cfb7/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kardianos/osext v0.0.0-20150410034420-8fef92e41e22/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34= github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.0.0-20131111012553-2788f0dbd169/go.mod h1:glhvuHOU9Hy7/8PwwdtnarXqLagOX0b/TbZx2zLMqEg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.0.0-20140812000539-f31442d60e51/go.mod h1:Bvhd+E3laJ0AVkG0c9rmtZcnhV0HQ3+c3YxxqTvc/gA= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.0.0-20130911015532-6807e777504f/go.mod h1:sjUstKUATFIcff4qlB53Kml0wQPtJVc/3fWrmuUmcfA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE= github.com/kubernetes-sigs/application v0.8.0 h1:NNp+kJrX4P7LkQhN/WZ4mGSTiRs5BBsDkReU1Fz/Kck= github.com/kubernetes-sigs/application v0.8.0/go.mod h1:KqAScqo78PXUrmoFOH8z6P4xQDBdzyJH1FMqrhgJJLE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/libopenstorage/openstorage v0.0.0-20170906232338-093a0c388875/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v0.0.0-20160816085511-61b492c03cf4/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481 h1:IaSjLMT6WvkoZZjspGxy3rdaTEmWLoRm49WbtVUi9sA= github.com/mailru/easyjson v0.0.0-20190620125010-da37f6c1e481/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8= github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a h1:+J2gw7Bw77w/fbK7wnNJJDKmw1IbWft2Ul5BzrG1Qm8= github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v0.0.0-20180605041737-f8471b0a71de/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.1/go.mod h1:F9YacGpnZbLQMzuPI0rR6op21YvNu/RjL705LJJpM3k= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4= github.com/mholt/caddy v0.0.0-20180213163048-2de495001514/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY= github.com/miekg/dns v0.0.0-20160614162101-5d001d020961/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mindprince/gonvml v0.0.0-20171110221305-fee913ce8fb2/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= github.com/mistifyio/go-zfs v0.0.0-20151009155749-1b4ae6fb4e77/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.0.0-20160930181131-4ee1cc9a8058/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20190414153302-2ae31c8b6b30/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mvdan/xurls v0.0.0-20160110113200-1b768d7c393a/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= github.com/nats-io/gnatsd v1.4.1/go.mod h1:nqco77VO78hLCJpIcVfygDP2rPGfsEHkGTUk94uh5DQ= github.com/nats-io/go-nats v1.7.0/go.mod h1:+t7RHT5ApZebkrQdnn6AhQJmhJJiKAvJUio1PiiCtj0= github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nuid v1.0.0/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onrik/logrus v0.2.1 h1:xEYR+opLvr+hNixPPAimuQppFYHaZ0XLO9hZ2G8WPLI= github.com/onrik/logrus v0.2.1/go.mod h1:qfe9NeZVAJfIxviw3cYkZo3kvBtLoPRJriAO8zl7qTk= github.com/onrik/logrus v0.5.1 h1:f+dStGd/hIk6qUb8CUESjczzd4MrdeGHuOLoJ5msr44= github.com/onrik/logrus v0.5.1/go.mod h1:qfe9NeZVAJfIxviw3cYkZo3kvBtLoPRJriAO8zl7qTk= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v0.0.0-20170604055404-372ad780f634/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20181113202123-f000fe11ece1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v0.0.0-20170621221121-4a2974bf1ee9/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= github.com/openshift/client-go v0.0.0-20190923180330-3b6373338c9b/go.mod h1:6rzn+JTr7+WYS2E1TExP4gByoABxMznR6y2SnUIkmxk= github.com/openshift/origin v0.0.0-20160503220234-8f127d736703/go.mod h1:0Rox5r9C8aQn6j1oAOQ0c1uC86mYbUFObzjBRvUKHII= github.com/openshift/prom-label-proxy v0.1.1-0.20191016113035-b8153a7f39f1/go.mod h1:p5MuxzsYP1JPsNGwtjtcgRHHlGziCJJfztff91nNixw= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.0/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/operator-framework/operator-lifecycle-manager v0.0.0-20191115003340-16619cd27fa5/go.mod h1:zL34MNy92LPutBH5gQK+gGhtgTUlZZX03I2G12vWHF4= github.com/operator-framework/operator-registry v1.5.1/go.mod h1:agrQlkWOo1q8U1SAaLSS2WQ+Z9vswNT2M2HFib9iuLY= github.com/operator-framework/operator-sdk v0.13.0 h1:AWiKOl6ZeAyQgbGVoD8fNd+eCbFuRWgr4hciaaOEBmE= github.com/operator-framework/operator-sdk v0.13.0/go.mod h1:XRnicDD4uZCNbJbMXc0B7eyw7hjO4Xzol7FAkWHa1Nc= github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= github.com/otiai10/copy v1.0.2 h1:DDNipYy6RkIkjMwy+AWzgKiNTyj2RUI9yEMeETEpVyc= github.com/otiai10/copy v1.0.2/go.mod h1:c7RpqBkwMom4bYTSkLSym4VSJz/XtncWRAj/J4PEIMY= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776 h1:o59bHXu8Ejas8Kq6pjoVJQ9/neN66SM8AKh6wI42BBs= github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk= github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v0.0.0-20160930220758-4d0e916071f6/go.mod h1:NxmoDg/QLVWluQDUYG7XBZTLUpKeFa8e3aMf1BfjyHk= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/ffjson v0.0.0-20180717144149-af8b230fcd20/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/prometheus v2.3.2+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.8.0/go.mod h1:fSI0j+IUQrDd7+ZtR9WKIGtoYAYAJUKcKhYLG25tN4g= github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA= github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190706150252-9beb055b7962/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/robfig/cron v0.0.0-20170309132418-df38d32658d8/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron v0.0.0-20170526150127-736158dc09e1/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.5.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rubenv/sql-migrate v0.0.0-20191025130928-9355dd04f4b3/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY= github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v1.5.2-0.20180428102519-11635eb403ff h1:bxenFOpdnKzbA1dhcJpgiwjSw7yqvWWY6huCpmsBfv0= github.com/russross/blackfriday v1.5.2-0.20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/seccomp/libseccomp-golang v0.0.0-20150813023252-1b506fc7c24e/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/githubv4 v0.0.0-20190718010115-4ba037080260/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/githubv4 v0.0.0-20191102174205-af46314aec7b/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/shurcooL/sanitized_anchor_name v0.0.0-20151028001915-10ef21a441db/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sigma/go-inotify v0.0.0-20181102212354-c87b6cf5033d/go.mod h1:stlh9OsqBQSdwxTxX73mu41BBtRbIpZLQ7flcAoxAfo= github.com/sirupsen/logrus v1.0.5 h1:8c8b5uO0zS4X6RPl/sd1ENwSkIc0/H2PaHxE3udaE8I= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v0.0.0-20160816080757-b28a7effac97/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v0.0.0-20160730092037-e31f36ffc91a/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.0-20180319062004-c439c4fa0937/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v0.0.0-20160311093646-33c24e77fb80/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v0.0.0-20160820190039-7fb2782df3d8/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/gocapability v0.0.0-20160928074757-e7cb7fa329f4/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245/go.mod h1:O1c8HleITsZqzNZDjSNzirUGsMT0oGu9LhHKoJrqO+A= github.com/tektoncd/pipeline v0.10.1 h1:pDsYK2b70o/Ze/CE1nisELwKVVE54FxwyfLznsW1JiE= github.com/tektoncd/pipeline v0.10.1/go.mod h1:D2X0exT46zYx95BU7ByM8+erpjoN7thmUBvlKThOszU= github.com/tektoncd/plumbing v0.0.0-20191216083742-847dcf196de9/go.mod h1:QZHgU07PRBTRF6N57w4+ApRu8OgfYLFNqCDlfEZaD9Y= github.com/tektoncd/plumbing/pipelinerun-logs v0.0.0-20191206114338-712d544c2c21/go.mod h1:S62EUWtqmejjJgUMOGB1CCCHRp6C706laH06BoALkzU= github.com/tidwall/gjson v1.4.0 h1:w6iOJZt9BJOzz4VD9CSnRCX/oleCsAZWi+1FFzZA+SA= github.com/tidwall/gjson v1.4.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= github.com/vdemeester/k8s-pkg-credentialprovider v1.13.12-1/go.mod h1:Fko0rTxEtDW2kju5Ky7yFJNS3IcNvW8IPsp4/e9oev0= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vmware/govmomi v0.20.1/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/vmware/photon-controller-go-sdk v0.0.0-20170310013346-4a435daef6cc/go.mod h1:e6humHha1ekIwTCm+A5Qed5mG8V4JL+ChHcUOJ+L/8U= github.com/xanzy/go-cloudstack v0.0.0-20160728180336-1e2cbf647e57/go.mod h1:s3eL3z5pNXF5FVybcT+LIVdId8pYn709yv6v5mrkrQE= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50= go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.12.0 h1:dySoUQPFBGj6xwjmBzageVL8jGi8uxc6bEmJQjA06bw= go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190806162312-597adff16ade/go.mod h1:AlhUtkH4DA4asiFC5RgK7ZKmauvtkAVcy9L0epCzlWo= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68= golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 h1:MlY3mEfbnWGmUi4rtHOtNnnnN4UJRGSyLPx+DXA5Sq4= golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181004145325-8469e314837c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190219203350-90b0e4468f99/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190621203818-d432491b9138/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 h1:4y9KwBHBgBNwDbtu44R5o1fdOCQUEXhbk/P4A9WmJq0= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e h1:hq86ru83GdWTlfQFZGO4nZJTU4Bs2wfHl8oFHRaXsfc= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20170824195420-5d2fd3ccab98/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190807223507-b346f7fd45de/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191010171213-8abd42400456/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191018212557-ed542cd5b28a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112005509-a3f652f18032/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200115165105-de0b1760071a h1:bEJ3JL2YUH3tt9KX9dsy0WUF3WOrhjtNjK93o0svepY= golang.org/x/tools v0.0.0-20200115165105-de0b1760071a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d h1:lzLdP95xJmMpwQ6LUHwrc5V7js93hTiY7gkznu0BgmY= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.0.0-20190710053202-4340aa3071a0/go.mod h1:03dgh78c4UvU1WksguQ/lvJQXbezKQGJSrwwRq5MraQ= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.10.0 h1:7tmAxx3oKE98VMZ+SBZzvYYWRQ9HODBxmC8mXUsraSQ= google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.25.0 h1:LodzhlzZEUfhXzNUMIfVlf9Gr6Ua5MMtoFWh7+f47qA= google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03 h1:4HYDjxeNXAOTv3o1N2tjo8UUSlhQgAD52FVkwxnWgM8= google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84 h1:pSLkPbrjnPyLDYUO2VM9mDLqo2V6CFBY84lFSZAfoi4= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= gopkg.in/natefinch/lumberjack.v2 v2.0.0-20150622162204-20b71e5b60d7 h1:986b60BAz5vO2Vaf48yQaq+wb2bU4JsXxKu1+itW6x8= gopkg.in/natefinch/lumberjack.v2 v2.0.0-20150622162204-20b71e5b60d7/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.0.0-20180411045311-89060dee6a84/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.1.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.0.0-20190620084959-7cf5895f2711 h1:BblVYz/wE5WtBsD/Gvu54KyBUTJMflolzc5I2DTvh50= k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= k8s.io/apiextensions-apiserver v0.0.0-20190620085554-14e95df34f1f h1:+pHBUvIpLzm6H8VwRO+jMLcq5MIfaGq5xu/cBV676Ps= k8s.io/apiextensions-apiserver v0.0.0-20190620085554-14e95df34f1f/go.mod h1:++XMkbLSSAutLgulnUnXW4kNbSkyQzlPL8PaW4hjJT4= k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719 h1:uV4S5IB5g4Nvi+TBVNf3e9L4wrirlwYJ6w88jUQxTUw= k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA= k8s.io/apiserver v0.0.0-20190620085212-47dc9a115b18/go.mod h1:Hc9PbFVOsMigd7B7OiY/6bIRkR8y31eIKsr1D+JtKg4= k8s.io/autoscaler v0.0.0-20190607113959-1b4f1855cb8e/go.mod h1:QEXezc9uKPT91dwqhSJq3GNI3B1HxFRQHiku9kmrsSA= k8s.io/cli-runtime v0.0.0-20190620085706-2090e6d8f84c h1:w9/2LqD258mHJmpbLczVn5bnsK6ppTqlA64NTsjXZMY= k8s.io/cli-runtime v0.0.0-20190620085706-2090e6d8f84c/go.mod h1:fkxp0BXLu9gu3r8x8X8gLrfDgWfqusKEJUnMUIqpDcg= k8s.io/client-go v0.0.0-20190620085101-78d2af792bab h1:E8Fecph0qbNsAbijJJQryKu4Oi9QTp5cVpjTE+nqg6g= k8s.io/client-go v0.0.0-20190620085101-78d2af792bab/go.mod h1:E95RaSlHr79aHaX0aGSwcPNfygDiPKOVXdmivCIZT0k= k8s.io/cloud-provider v0.0.0-20190620090043-8301c0bda1f0/go.mod h1:UXU55LeVTrjyQNw86sHjagiYhSZjYxWKXvx0Ml17KvM= k8s.io/cluster-bootstrap v0.0.0-20190620090013-c9a0fc045dc1/go.mod h1:cCRw3eZzlJdySYRtkL/N4cAClxYCzyrBL3V8cblTlUo= k8s.io/code-generator v0.0.0-20190612205613-18da4a14b22b h1:p+PRuwXWwk5e+UYvicGiavEupapqM5NOxUl3y1GkD6c= k8s.io/code-generator v0.0.0-20190612205613-18da4a14b22b/go.mod h1:G8bQwmHm2eafm5bgtX67XDZQ8CWKSGu9DekI+yN4Y5I= k8s.io/component-base v0.0.0-20190620085130-185d68e6e6ea/go.mod h1:VLedAFwENz2swOjm0zmUXpAP2mV55c49xgaOzPBI/QQ= k8s.io/cri-api v0.0.0-20190531030430-6117653b35f1/go.mod h1:K6Ux7uDbzKhacgqW0OJg3rjXk/SR9kprCPfSUDXGB5A= k8s.io/csi-translation-lib v0.0.0-20190620090116-299a7b270edc/go.mod h1:L51Xd2IwQCsOBx41c4YZR9dY1h1IjMk8r3Nnv3L80KM= k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20191108084044-e500ee069b5c h1:iraFntD6FA5K/hBaPW2z/ZItJZEG63uc3ak5S0oDVEo= k8s.io/gengo v0.0.0-20191108084044-e500ee069b5c/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM= k8s.io/helm v2.16.1+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0 h1:Foj74zO6RbjjP4hBEKjnYtjjAhGg4jNynUdYF6fJrok= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/kube-aggregator v0.0.0-20190620085325-f29e2b4a4f84/go.mod h1:S8URgD5o6oGCoLP9lx6oAdxWB9Ovtq9KLU9cYmU08QI= k8s.io/kube-controller-manager v0.0.0-20190620085942-b7f18460b210/go.mod h1:FoQCodL0eAmdwbZuu2/fi7nVEh3xE4SpomwLaGO4V74= k8s.io/kube-openapi v0.0.0-20180731170545-e3762e86a74c/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190320154901-5e45bb682580/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d h1:Xpe6sK+RY4ZgCTyZ3y273UmFmURhjtoJiwOMbQsXitY= k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-proxy v0.0.0-20190620085809-589f994ddf7f/go.mod h1:EP2frUhhC4rizGpCTYCnVS4+XZMh7Hyq40jOUvuAK5g= k8s.io/kube-scheduler v0.0.0-20190620085912-4acac5405ec6/go.mod h1:ktfBNqjRdtYUw2eFNk32TtxiGqOy00eiWua74iNEcLg= k8s.io/kube-state-metrics v1.7.2 h1:6vdtgXrrRRMSgnyDmgua+qvgCYv954JNfxXAtDkeLVQ= k8s.io/kube-state-metrics v1.7.2/go.mod h1:U2Y6DRi07sS85rmVPmBFlmv+2peBcL8IWGjM+IjYA/E= k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51/go.mod h1:gL826ZTIfD4vXTGlmzgTbliCAT9NGiqpCqK2aNYv5MQ= k8s.io/kubelet v0.0.0-20190620085838-f1cb295a73c9/go.mod h1:2gRsvblRTyHIsBazBlnqeAWkWRtnUq6cBnrfdPFr9iY= k8s.io/kubernetes v1.15.0 h1:0P6jAdZ1cF5/wSc14HqHCjWlbnwYzmFJBYeXBezZEE0= k8s.io/kubernetes v1.15.0/go.mod h1:3RE5ikMc73WK+dSxk4pQuQ6ZaJcPXiZX2dj98RcdCuM= k8s.io/legacy-cloud-providers v0.0.0-20190620090156-2138f2c9de18/go.mod h1:cgNZX1LyZbr0mW8MxxlgvFU2D3k1KDTlH/EgMuiQbGc= k8s.io/metrics v0.0.0-20190620085625-3b22d835f165/go.mod h1:98M2pmJXrzr0W4o9N5ptSvZMygAMRVvyPr2vq7aRwT4= k8s.io/repo-infra v0.0.0-20181204233714-00fe14e3d1a3/go.mod h1:+G1xBfZDfVFsm1Tj/HNCvg4QqWx8rJ2Fxpqr1rqp/gQ= k8s.io/sample-apiserver v0.0.0-20190620085408-1aef9010884e/go.mod h1:uGtJFD6/KTth+Ed9NNWF8lMf5m1ued/X6qUuACRrBTs= k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= k8s.io/utils v0.0.0-20190308190857-21c4ce38f2a7/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= k8s.io/utils v0.0.0-20190506122338-8fab8cb257d5/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191030222137-2b95a09bc58d h1:1P0iBJsBzxRmR+dIFnM+Iu4aLxnoa7lBqozW/0uHbT8= k8s.io/utils v0.0.0-20191030222137-2b95a09bc58d/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200529193333-24a76e807f40 h1:4kgN8/a1iSnX2Trptc8nnoXnOGXkrcaF0u4+dmiCRRA= k8s.io/utils v0.0.0-20200529193333-24a76e807f40/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= knative.dev/caching v0.0.0-20190719140829-2032732871ff/go.mod h1:dHXFU6CGlLlbzaWc32g80cR92iuBSpsslDNBWI8C7eg= knative.dev/eventing-contrib v0.6.1-0.20190723221543-5ce18048c08b/go.mod h1:SnXZgSGgMSMLNFTwTnpaOH7hXDzTFtw0J8OmHflNx3g= knative.dev/pkg v0.0.0-20191111150521-6d806b998379 h1:0IbJWfv82eUhoNymvIrTjxVqrAURRK1x39+//IZV7Cc= knative.dev/pkg v0.0.0-20191111150521-6d806b998379/go.mod h1:pgODObA1dTyhNoFxPZTTjNWfx6F0aKsKzn+vaT9XO/Q= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= pack.ag/amqp v0.11.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.2.0 h1:5gL30PXOisGZl+Osi4CmLhvMUj77BO3wJeouKF2va50= sigs.k8s.io/controller-runtime v0.2.0/go.mod h1:ZHqrRDZi3f6BzONcvlUxkqCKgwasGk5FZrnSv9TVZF4= sigs.k8s.io/controller-tools v0.2.2/go.mod h1:8SNGuj163x/sMwydREj7ld5mIMJu1cDanIfnx6xsU70= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0= sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= sigs.k8s.io/kustomize/kyaml v0.1.10 h1:ZZfBnA/kYa9ZxUFIgI9oq3pWKzzA1gGOKgU0Hv/NhVg= sigs.k8s.io/kustomize/kyaml v0.1.10/go.mod h1:mPmeBSRy0LTMv6fSrYSoi2yIFNZVouGKDsTekE5kdhs= sigs.k8s.io/kustomize/kyaml v0.1.11 h1:/VvWxVIgH5gG1K4A7trgbyLgO3tRBiAWNhLFVU1HEmo= sigs.k8s.io/kustomize/kyaml v0.1.11/go.mod h1:72/rLkSi+L/pHM1oCjwrf3ClU+tH5kZQvvdLSqIHwWU= sigs.k8s.io/kustomize/v3 v3.2.0 h1:EKcEubO29vCbigcMoNynfyZH+ANWkML2UHWibt1Do7o= sigs.k8s.io/kustomize/v3 v3.2.0/go.mod h1:ztX4zYc/QIww3gSripwF7TBOarBTm5BvyAMem0kCzOE= sigs.k8s.io/structured-merge-diff v0.0.0-20190302045857-e85c7b244fd2/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/testing_frameworks v0.1.1 h1:cP2l8fkA3O9vekpy5Ks8mmA0NW/F7yBdXf8brkWhVrs= sigs.k8s.io/testing_frameworks v0.1.1/go.mod h1:VVBKrHmJ6Ekkfz284YKhQePcdycOzNH9qL6ht1zEr/U= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= ================================================ FILE: hack/boilerplate.go.txt ================================================ /* 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. */ ================================================ FILE: hack/cp_update.sh ================================================ #!/usr/bin/env bash # # this copies kubeflow/bootstrap/{go.*,cmd/kfctl,pkg} to here and updates all references # github.com/kubeflow/kubeflow/bootstrap -> github.com/kubeflow/kfctl kfctldir=$(dirname $0)/../../kubeflow/bootstrap preclean() { rm $(find config pkg -name 'zz_generated*') rm -rf go.* cmd pkg config } cpdirs() { if [[ ! -d $kfctldir ]]; then echo invalid directory $kfctldir >&2 exit fi if [[ ! -d cmd ]]; then mkdir cmd fi cp -r $kfctldir/cmd/{kfctl,plugins} cmd if [[ ! -d pkg ]]; then mkdir pkg fi cp -r $kfctldir/pkg . if [[ ! -d config ]]; then mkdir config fi cp -r $kfctldir/config/{types.go,doc.go} config cp $kfctldir/go.mod . } findfiles() { cd $kfctldir find go.mod cmd pkg -type f -exec grep -l 'github.com\/kubeflow\/kubeflow\/bootstrap\/' {} \; } updatefiles() { for i in $(findfiles); do ex -s $i <.*$/\1github.com\/kubeflow\/kubeflow\/components\/profile-controller\/v2 => ..\/kubeflow\/components\/profile-controller/g w q EOF1 } preclean && cpdirs && updatefiles && updategomod ================================================ FILE: kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - kustomize/base # only enable this if the k8s cluster is 1.15+ and has resource quota support #- kustomize/include/quota namespace: kubeflow-operator ================================================ FILE: kustomize/base/kustomization.yaml ================================================ bases: - ../../deploy ================================================ FILE: kustomize/include/quota/kfdef_quota.yaml ================================================ apiVersion: v1 kind: ResourceQuota metadata: name: kfdef-quota spec: hard: count/kfdefs.kfdef.apps.kubeflow.org: "1" ================================================ FILE: kustomize/include/quota/kustomization.yaml ================================================ resources: - kfdef_quota.yaml ================================================ FILE: operator.md ================================================ # Kubeflow Operator Kubeflow Operator helps deploy, monitor and manage the lifecycle of Kubeflow. Built using the [Operator Framework](https://coreos.com/blog/introducing-operator-framework) which offers an open source toolkit to build, test, package operators and manage the lifecycle of operators. The Operator is currently in incubation phase and is based on this [design doc](https://docs.google.com/document/d/1vNBZOM-gDMpwTbhx0EDU6lDpyUjc7vhT3bdOWWCRjdk/edit#). It is built on top of _KfDef_ CR, and uses _kfctl_ as the nucleus for Controller. Current roadmap for this Operator is listed [here](https://github.com/kubeflow/kfctl/issues/193). The Operator is also [published on OperatorHub](https://operatorhub.io/operator/kubeflow). ## Prerequisites * Install [kustomize](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/INSTALL.md) ## Deployment Instructions 1. Clone this repository, build the manifests and install the operator ```shell git clone https://github.com/kubeflow/kfctl.git && cd kfctl export OPERATOR_NAMESPACE=operators kubectl create ns ${OPERATOR_NAMESPACE} cd deploy/ kustomize edit set namespace ${OPERATOR_NAMESPACE} # kustomize edit add resource kustomize/include/quota # only deploy this if the k8s cluster is 1.15+ and has resource quota support, which will allow only one _kfdef_ instance or one deployment of Kubeflow on the cluster. This follows the singleton model, and is the current recommended and supported mode. kustomize build | kubectl apply -f - ``` 2. Deploy KfDef _KfDef_ can point to a remote URL or to a local kfdef file. To use the set of default kfdefs from Kubeflow, follow the [Deploy with default kfdefs](#deploy-with-default-kfdefs) section below. ```shell KUBEFLOW_NAMESPACE=kubeflow kubectl create ns ${KUBEFLOW_NAMESPACE} kubectl create -f -n ${KUBEFLOW_NAMESPACE} ``` ### Deploy with default kfdefs To use the set of default kfdefs from Kubeflow, you will have to insert the `metadata.name` field before you can apply it to Kubernetes. Below are the commands for applying the Kubeflow _kfdef_ using Operator. For e.g. for IBM Cloud, commands will be > If you are pointing the kfdef file on the local machine, set the `KFDEF` to the kfdef file path and skip the `curl` command. First point to your Cloud provider kfdef. For e.g. for OpenShift, point to the kfdef in OpenDataHub repo ```shell export KFDEF_URL=https://raw.githubusercontent.com/opendatahub-io/manifests/v0.7-branch-openshift/kfdef/kfctl_openshift.yaml ``` Similary for GCP, IBM Cloud etc. you can point to the respective kfdefs in Kubeflow repository, e.g. ```shell export KFDEF_URL=https://raw.githubusercontent.com/kubeflow/manifests/master/kfdef/kfctl_ibm.yaml ``` Then specify the `KUBEFLOW_DEPLOYMENT_NAME` you want to give to your deployment. Please note that currently multi-user deployments have a hard dependency on using `kubeflow` as the deployment name. ```shell export KUBEFLOW_DEPLOYMENT_NAME=kubeflow export KFDEF=$(echo "${KFDEF_URL}" | rev | cut -d/ -f1 | rev) curl -L ${KFDEF_URL} > ${KFDEF} ``` Next, we need to update the KFDEF file with the KUBEFLOW_DEPLOYMENT_NAME. We strongly recommend to install the [yq](https://github.com/mikefarah/yq) tool and run the `yq` command. However, if you can't install `yq`, you can run the `perl` command to do the same thing assuming you are using one of the kfdefs under the [manifests repository](https://github.com/kubeflow/manifests/tree/master/kfdef). ```shell yq eval '.metadata.name = "'${KUBEFLOW_DEPLOYMENT_NAME}'"' ${KFDEF} > ${KFDEF}.tmp && mv ${KFDEF}.tmp ${KFDEF} # perl -pi -e $'s@metadata:@metadata:\\\n name: '"${KUBEFLOW_DEPLOYMENT_NAME}"'@' ${KFDEF} ``` Lastly, deploy the kfdef resource to the cluster. ```shell kubectl create -f ${KFDEF} -n ${KUBEFLOW_NAMESPACE} ``` ## Testing Watcher and Reconciler One of the major benefits of using kfctl as an Operator is to leverage the functionalities around being able to watch and reconcile your Kubeflow deployments. The Operator is watching on any cluster events for the _KfDef_ instance, as well as the _Delete_ event for all the resources whose owner is the _KfDef_ instance. Each of such events is queued as a request for the _reconciler_ to apply changes to the _KfDef_ instance. For example, if one of the Kubeflow resources is deleted, the _reconciler_ will be triggered to re-apply the _KfDef_ instance, and re-create the deleted resource on the cluster. Therefore, the Kubeflow deployment with this _KfDef_ instance will recover automatically from the unexpected delete event. Try following to see the operator watcher and reconciler in action: 1. Check the tf-job-operator deployment is running ```shell kubectl get deploy -n ${KUBEFLOW_NAMESPACE} tf-job-operator # NAME READY UP-TO-DATE AVAILABLE AGE # tf-job-operator 1/1 1 1 7m15s ``` 2. Delete the tf-job-operator deployment ```shell kubectl delete deploy -n ${KUBEFLOW_NAMESPACE} tf-job-operator # deployment.extensions "tf-job-operator" deleted ``` 3. Wait for 10 to 15 seconds, then check the tf-job-operator deployment again You will be able to see that the deployment is being recreated by the Operator's reconciliation logic. ```Shell kubectl get deploy -n ${KUBEFLOW_NAMESPACE} tf-job-operator # NAME READY UP-TO-DATE AVAILABLE AGE # tf-job-operator 0/1 0 0 10s ``` The Kubeflow operator also support multiple _KfDef_ instances deployment. It watches over all the _KfDef_ instances and handles reconcile requests to all the _KfDef_ instances. To understand more on the operator controller behavior, refer to this [controller-runtime link](https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/doc.go). The operator responds to following events: * When a _KfDef_ instance is created or updated, the operator's _reconciler_ will be notified of the event and invoke the `Apply` function provided by the [`kfctl` package](https://github.com/kubeflow/kfctl/tree/master/pkg) to deploy Kubeflow. The Kubeflow resources specified with the manifests will be added with the following annotation to indicate that they are owned by this _KfDef_ instance. ``` annotations: kfctl.kubeflow.io/kfdef-instance: . ``` * When a _KfDef_ instance is deleted, the operator's _reconciler_ will be notified of the event and invoke the finalizer to run the `Delete` function provided by the [`kfctl` package](https://github.com/kubeflow/kfctl/tree/master/pkg) and go through all applications and components owned by the _KfDef_ instance. * When any resource deployed as part of a _KfDef_ instance is deleted, the operator's _reconciler_ will be notified of the event and invoke the `Apply` function provided by the [`kfctl` package](https://github.com/kubeflow/kfctl/tree/master/pkg) to re-deploy Kubeflow. The deleted resource will be recreated with the same manifest which was specified when the _KfDef_ instance was created. ## Delete Kubeflow * Delete Kubeflow deployment, the _KfDef_ instance ```shell kubectl delete kfdef -n ${KUBEFLOW_NAMESPACE} --all ``` > Note that the users profile namespaces created by `profile-controller` will not be deleted. The `${KUBEFLOW_NAMESPACE}` created outside of the operator will not be deleted either. The delete process usually takes up to 15 minutes because the Operator needs to delete each component sequentially to avoid race conditions such as the [namespace finalizer issue](https://github.com/kubeflow/kfctl/issues/404). * Delete Kubeflow Operator ```shell kubectl delete -f deploy/operator.yaml -n ${OPERATOR_NAMESPACE} kubectl delete clusterrolebinding kubeflow-operator kubectl delete -f deploy/service_account.yaml -n ${OPERATOR_NAMESPACE} kubectl delete -f deploy/crds/kfdef.apps.kubeflow.org_kfdefs_crd.yaml kubectl delete ns ${OPERATOR_NAMESPACE} ``` ## Optional: Registering the Operator to OLM Catalog Please follow the instructions [here](https://github.com/operator-framework/community-operators/blob/master/docs/testing-operators.md#testing-operator-deployment-on-openshift) to register your Operator to OLM if you are using that to install and manage the Operator. If you want to leverage the OperatorHub, please use the default [Kubeflow Operator registered there](https://operatorhub.io/operator/kubeflow) ## Trouble Shooting * When deleting a Kubeflow deployment, some _mutatingwebhookconfigurations_ may not be removed as they are cluster-wide resources and dynamically created by the individual controller. It's a [known issue](https://github.com/kubeflow/manifests/issues/1379) for some of the Kubeflow components. To remove them, run the following: ```shell kubectl delete mutatingwebhookconfigurations katib-mutating-webhook-config kubectl delete mutatingwebhookconfigurations cache-webhook-kubeflow ``` ## Development Instructions ### Prerequisites 1. Install [operator-sdk](https://github.com/operator-framework/operator-sdk/blob/master/doc/user/install-operator-sdk.md) 2. Install [golang](https://golang.org/dl/) 3. Install [kustomize](https://github.com/kubernetes-sigs/kustomize/blob/master/docs/INSTALL.md) ### Build Instructions These steps are based on the [operator-sdk](https://github.com/operator-framework/operator-sdk/blob/master/doc/user-guide.md) with modifications that are specific for this Kubeflow operator. 1. Clone this repository under your `$GOPATH`. (e.g. `~/go/src/github.com/kubeflow/`) ```shell git clone https://github.com/kubeflow/kfctl cd kfctl ``` 2. Build and push the operator ```shell export OPERATOR_IMG= make build-operator make push-operator ``` > Note: replace **** with the image repo name and tag, for example, `docker.io/example/kubeflow-operator:latest`. 3. Follow [Deployment Instructions](#deployment-instructions) section to test the operator with the newly built image ## Current Tested Operators and Pre-built Images Kubeflow Operator controller logic is based on the [`kfctl` package](https://github.com/kubeflow/kfctl/tree/master/pkg), so for each major release of `kfctl`, an operator image is built and tested with that version of [`manifests`](github.com/kubeflow/manifests) to deploy a _KfDef_ instance. Following table shows what releases have been tested. |branch tag|operator image|manifests version|kfdef example|note| |---|---|---|---|---| |[v1.0](https://github.com/kubeflow/kfctl/tree/v1.0)|[aipipeline/kubeflow-operator:v1.0.0](https://hub.docker.com/layers/aipipeline/kubeflow-operator/v1.0.0/images/sha256-63d00b29a61ff5bc9b0527c8a515cd4cb55de474c45d8e0f65742908ede4d88f?context=repo)|[1.0.0](https://github.com/kubeflow/manifests/tree/f56bb47d7dc5378497ad1e38ea99f7b5ebe7a950)|[kfctl_k8s_istio.v1.0.0.yaml](https://github.com/kubeflow/manifests/blob/f56bb47d7dc5378497ad1e38ea99f7b5ebe7a950/kfdef/kfctl_k8s_istio.v1.0.0.yaml)|| |[v1.0.1](https://github.com/kubeflow/kfctl/tree/v1.0.1)|[aipipeline/kubeflow-operator:v1.0.1](https://hub.docker.com/layers/aipipeline/kubeflow-operator/v1.0.1/images/sha256-828024b773040271e4b547ce9219046f705fb7123e05503d5a2d1428dfbcfb6e?context=repo)|[1.0.1](https://github.com/kubeflow/manifests/tree/v1.0.1)|[kfctl_k8s_istio.v1.0.1.yaml](https://github.com/kubeflow/manifests/blob/v1.0.1/kfdef/kfctl_k8s_istio.v1.0.1.yaml)|| |[v1.0.2](https://github.com/kubeflow/kfctl/tree/v1.0.2)|[aipipeline/kubeflow-operator:v1.0.2](https://hub.docker.com/layers/aipipeline/kubeflow-operator/v1.0.2/images/sha256-18d2ca6f19c1204d5654dfc4cc08032c168e89a95dee68572b9e2aaedada4bda?context=repo)|[1.0.2](https://github.com/kubeflow/manifests/tree/v1.0.2)|[kfctl_k8s_istio.v1.0.2.yaml](https://github.com/kubeflow/manifests/blob/v1.0.2/kfdef/kfctl_k8s_istio.v1.0.2.yaml)|| |[master](https://github.com/kubeflow/kfctl)|[aipipeline/kubeflow-operator:master](https://hub.docker.com/layers/aipipeline/kubeflow-operator/master/images/sha256-e81020c426a12237c7cf84316dbbd0efda76e732233ddd57ef33543381dfb8a1?context=repo)|[master](https://github.com/kubeflow/manifests)|[kfctl_k8s_istio.yaml](https://github.com/kubeflow/manifests/blob/master/kfdef/kfctl_k8s_istio.yaml)|as of 05/15/2020| > Note: if building a customized operator for a specific version of Kubeflow is desired, you can run `git checkout` to that specific branch tag. Keep in mind to use the matching version of manifests. ================================================ FILE: pkg/apis/apis.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. // Generate deepcopy for apis // go:generate deepcopy-gen -O zz_generated.deepcopy -i ./... -h ../../hack/boilerplate.go.txt // Package apis contains Kubernetes API groups. package apis import ( "k8s.io/apimachinery/pkg/runtime" ) // AddToSchemes may be used to add all resources defined in the project to a Scheme var AddToSchemes runtime.SchemeBuilder // AddToScheme adds all Resources to the Scheme func AddToScheme(s *runtime.Scheme) error { return AddToSchemes.AddToScheme(s) } ================================================ FILE: pkg/apis/apps/addtoscheme_kfdef_v1.go ================================================ package apps import ( v1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1" ) func init() { // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back AddToSchemes = append(AddToSchemes, v1.SchemeBuilder.AddToScheme) } ================================================ FILE: pkg/apis/apps/apis.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. // Generate deepcopy for apis // go:generate deepcopy-gen -O zz_generated.deepcopy -i ./... -h ../../hack/boilerplate.go.txt // Package apis contains Kubernetes API groups. package apps import ( "k8s.io/apimachinery/pkg/runtime" ) // AddToSchemes may be used to add all resources defined in the project to a Scheme var AddToSchemes runtime.SchemeBuilder // AddToScheme adds all Resources to the Scheme func AddToScheme(s *runtime.Scheme) error { return AddToSchemes.AddToScheme(s) } ================================================ FILE: pkg/apis/apps/group.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 apps contains apps API versions package apps import ( "fmt" "io" "io/ioutil" "os" "path" "path/filepath" "plugin" "regexp" "strings" gogetter "github.com/hashicorp/go-getter" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kfdefs "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" log "github.com/sirupsen/logrus" ext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" crdclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiext "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1" "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) const ( DefaultNamespace = "kubeflow" // TODO: find the latest tag dynamically DefaultVersion = "master" KfConfigFile = "app.yaml" KustomizationFile = "kustomization.yaml" KustomizationParamFile = "params.env" DefaultCacheDir = ".cache" KubeflowRepoName = "kubeflow" ManifestsRepoName = "manifests" KubeflowRepo = "kubeflow" ManifestsRepo = "manifests" DefaultConfigDir = "bootstrap/config" DefaultZone = "us-east1-d" DefaultGkeApiVer = "v1beta1" DefaultAppLabel = "app.kubernetes.io/name" DefaultAppVersion = "app.kubernetes.io/version" DefaultAppType = "kubeflow" KUBEFLOW_USERNAME = "KUBEFLOW_USERNAME" KUBEFLOW_PASSWORD = "KUBEFLOW_PASSWORD" DefaultSwaggerFile = "bootstrap/k8sSpec/v1.11.7/api/openapi-spec/swagger.json" YamlSeparator = "(?m)^---[ \t]*$" Dns1123LabelFmt = "[a-z0-9]([-a-z0-9]*[a-z0-9])?" ProfileNameMaxLen = 30 ) type SupportedResourceType string const ( KFDEF SupportedResourceType = "KfDef" KFUPGRADE SupportedResourceType = "KfUpgrade" ) type ResourceEnum string const ( ALL ResourceEnum = "all" K8S ResourceEnum = "k8s" PLATFORM ResourceEnum = "platform" ) type CliOption string const ( EMAIL CliOption = "email" IPNAME CliOption = "ipName" HOSTNAME CliOption = "hostname" MOUNT_LOCAL CliOption = "mount-local" SKIP_INIT_GCP_PROJECT CliOption = "skip-init-gcp-project" VERBOSE CliOption = "verbose" NAMESPACE CliOption = "namespace" VERSION CliOption = "version" REPO CliOption = "repo" PROJECT CliOption = "project" APPNAME CliOption = "appname" DATA CliOption = "Data" ZONE CliOption = "zone" DELETE_STORAGE CliOption = "delete-storage" DISABLE_USAGE_REPORT CliOption = "disable-usage-report" PACKAGE_MANAGER CliOption = "package-manager" FILE CliOption = "file" FORCE_DELETION CliOption = "force-deletion" DUMP CliOption = "dump" ) // // KfApp provides a common // API for PackageManagers like ksonnet or kustomize // They all implement the API below // type KfApp interface { Apply(resources ResourceEnum) error Delete(resources ResourceEnum) error Dump(resources ResourceEnum) error Generate(resources ResourceEnum) error Init(resources ResourceEnum) error } // // Platform provides a common // API for platforms like gcp or minikube // They all implement the API below // type Platform interface { KfApp } // // This is used in the ksonnet implementation for `ks show` // type KfShow interface { Show(resources ResourceEnum) error } // QuoteItems will place quotes around the string arrays items func QuoteItems(items []string) []string { var withQuotes []string for _, item := range items { withQuote := "\"" + item + "\"" withQuotes = append(withQuotes, withQuote) } return withQuotes } // RemoveItem will remove a string item from the string array func RemoveItem(defaults []string, name string) []string { var pkgs []string for _, pkg := range defaults { if pkg != name { pkgs = append(pkgs, pkg) } } return pkgs } // Platforms const ( AWS = "aws" GCP = "gcp" MINIKUBE = "minikube" EXISTING_ARRIKTO = "existing_arrikto" ) // PackageManagers const ( KSONNET = "ksonnet" KUSTOMIZE = "kustomize" ) // LoadKfApp will load a shared library of the form .so func LoadKfApp(name string, kfdef *kfdefs.KfDef) (KfApp, error) { pluginname := strings.Replace(name, "-", "", -1) plugindir := os.Getenv("PLUGINS_ENVIRONMENT") pluginpath := filepath.Join(plugindir, name+".so") p, err := plugin.Open(pluginpath) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not load plugin %v for platform %v: %v", pluginpath, pluginname, err), } } symName := "GetKfApp" symbol, symbolErr := p.Lookup(symName) if symbolErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not find symbol %v for platform %v: %v", symName, pluginname, symbolErr), } } return symbol.(func(*kfdefs.KfDef) KfApp)(kfdef), nil } // DownloadToCache will download a version of kubeflow github repo or the manifests repo where version can be // master // tag // pull/[/head] // It returns the local file path of where the repo was downloaded func DownloadToCache(appDir string, repo string, version string) (string, error) { if _, err := os.Stat(appDir); os.IsNotExist(err) { appdirErr := os.Mkdir(appDir, os.ModePerm) if appdirErr != nil { log.Errorf("Couldn't create directory %v: %v", appDir, appdirErr) } } cacheDir := path.Join(appDir, DefaultCacheDir) cacheDir = path.Join(cacheDir, repo) // idempotency if _, err := os.Stat(cacheDir); !os.IsNotExist(err) { _ = os.RemoveAll(cacheDir) } cacheDirErr := os.MkdirAll(cacheDir, os.ModePerm) if cacheDirErr != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't create directory %v: %v", cacheDir, cacheDirErr), } } // Version can be // --version master // --version tag // --version pull//head if strings.HasPrefix(version, "pull") { if !strings.HasSuffix(version, "head") { version = version + "/head" } } tarballUrl := "https://github.com/kubeflow/" + repo + "/tarball/" + version + "?archive=tar.gz" tarballUrlErr := gogetter.GetAny(cacheDir, tarballUrl) if tarballUrlErr != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't download kubeflow repo %v: %v", tarballUrl, tarballUrlErr), } } files, filesErr := ioutil.ReadDir(cacheDir) if filesErr != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't read %v: %v", cacheDir, filesErr), } } subdir := files[0].Name() extractedPath := filepath.Join(cacheDir, subdir) newPath := filepath.Join(cacheDir, version) if strings.Contains(version, "/") { parts := strings.Split(version, "/") versionPath := cacheDir for i := 0; i < len(parts)-1; i++ { versionPath = filepath.Join(versionPath, parts[i]) versionPathErr := os.Mkdir(versionPath, os.ModePerm) if versionPathErr != nil { return "", &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't create directory %v: %v", versionPath, versionPathErr), } } } } renameErr := os.Rename(extractedPath, newPath) if renameErr != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't rename %v to %v: %v", extractedPath, newPath, renameErr), } } return newPath, nil } // TODO(#2586): Consolidate kubeconfig and API calls. // KubeConfigPath returns the filepath to the k8 client config file func KubeConfigPath() string { kubeconfigEnv := os.Getenv("KUBECONFIG") if kubeconfigEnv == "" { home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") if home == "" { for _, h := range []string{"HOME", "USERPROFILE"} { if home = os.Getenv(h); home != "" { break } } } kubeconfigPath := filepath.Join(home, ".kube", "config") return kubeconfigPath } return kubeconfigEnv } // GetConfig returns rest.Config using $HOME/.kube/config func GetConfig() *rest.Config { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules.ExplicitPath = KubeConfigPath() overrides := &clientcmd.ConfigOverrides{} config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, overrides).ClientConfig() if err != nil { log.Warnf("Could not open %v: %v", loadingRules.ExplicitPath, err) log.Infof("Trying to load rest.config with inClusterConfig...") config, err = rest.InClusterConfig() if err != nil { log.Warnf("Could not load rest.config with inClusterConfig and %v", loadingRules.ExplicitPath) } } return config } // GetServerVersion returns the verison of the k8 api server func GetServerVersion(c *clientset.Clientset) string { serverVersion, serverVersionErr := c.ServerVersion() if serverVersionErr != nil { log.Fatalf("Couldn't get server version info. Error: %v", serverVersionErr) } re := regexp.MustCompile("^v[0-9]+.[0-9]+.[0-9]+") version := re.FindString(serverVersion.String()) return "version:" + version } // GetKubeConfig returns a representation of $HOME/.kube/config func GetKubeConfig() *clientcmdapi.Config { kubeconfig := KubeConfigPath() config, configErr := clientcmd.LoadFromFile(kubeconfig) if configErr != nil { log.Warnf("Could not load config Error: %v", configErr) } return config } // GetClientset returns a k8s clientset using .kube/config credentials func GetClientset(config *rest.Config) *clientset.Clientset { clientset, err := kubernetes.NewForConfig(config) if err != nil { log.Fatalf("Can not get kubernetes kfdef: %v", err) } return clientset } // GetApiExtClientset returns a client that can query for CRDs func GetApiExtClientset(config *rest.Config) apiext.ApiextensionsV1beta1Interface { v := ext.SchemeGroupVersion config.GroupVersion = &v crdClient, err := crdclientset.NewForConfig(config) if err != nil { log.Fatalf("Can not get apiextensions kfdef: %v", err) } return crdClient.ApiextensionsV1beta1() } // Remove unvalid characters to compile a valid name for default Profile. To prevent // violation to the naming length restriction, ignore everything after `@`. func EmailToDefaultName(email string) string { name := strings.NewReplacer(".", "-").Replace(strings.ToLower(email)) splitted := strings.Split(name, "@") re := regexp.MustCompile(Dns1123LabelFmt) toDns1123 := func(input string) string { result := re.Find([]byte(input)) if result == nil { return "" } if len(result) > ProfileNameMaxLen { result = result[0:ProfileNameMaxLen] } return string(result) } if len(splitted) > 1 { return toDns1123("kubeflow-" + splitted[0]) } else { return toDns1123("kubeflow-" + name) } } // Capture replaces os.Stdout with a writer that buffers any data written // to os.Stdout. Call the returned function to cleanup and get the data // as a string. This is used in cases where the API we're calling writes to stdout // eg ksonnet's show func Capture() func() (string, error) { r, w, err := os.Pipe() if err != nil { panic(err) } done := make(chan error, 1) save := os.Stdout os.Stdout = w var buf strings.Builder go func() { _, err := io.Copy(&buf, r) _ = r.Close() done <- err }() return func() (string, error) { os.Stdout = save _ = w.Close() err := <-done if err == nil { return buf.String(), nil } else { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: err.Error(), } } } } ================================================ FILE: pkg/apis/apps/group_test.go ================================================ package apps import ( "testing" ) func TestEmailToDefaultName(t *testing.T) { testCases := [][]string{ []string{ "EmailToDefaultName", "kubeflow-emailtodefaultname", }, []string{ "very-long-name-very-long-name-very-long-name", "kubeflow-very-long-name-very-l", }, // Strips after @ []string{ "foo@bar.com", "kubeflow-foo", }, // Keep everything if not having @ []string{ "foo", "kubeflow-foo", }, // Doesn't check if it's a valid email address. []string{ "bar@baz", "kubeflow-bar", }, } for _, c := range testCases { o := EmailToDefaultName(c[0]) if o != c[1] { t.Errorf("EmailToDefaultName test case error; input: %v; expect %v; get %v", c[0], c[1], o) } } } ================================================ FILE: pkg/apis/apps/imagemirror/v1alpha1/replication_types.go ================================================ // Copyright 2020 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 v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type Replication struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec ReplicationSpec `json:"spec,omitempty"` } // List of image replication tasks defined by pattern type ReplicationSpec struct { Patterns []Pattern `json:"patterns,omitempty"` Context string `json:"context,omitempty"` } // Application defines an application to install type Pattern struct { Src SrcImages `json:"src,omitempty"` Dest string `json:"dest,omitempty"` } type SrcImages struct { Include string `json:"include,omitempty"` Exclude string `json:"exclude,omitempty"` } ================================================ FILE: pkg/apis/apps/kfconfig/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 v1alpha1 contains API Schema definitions for the kfconfig v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig // +k8s:defaulter-gen=TypeMeta // +groupName=kfconfig.apps.kubeflow.org package kfconfig ================================================ FILE: pkg/apis/apps/kfconfig/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the kfdef v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig // +k8s:defaulter-gen=TypeMeta // +groupName=kfconfig.apps.kubeflow.org package kfconfig import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "kfconfig.apps.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfConfig{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/kfconfig/types.go ================================================ package kfconfig import ( "fmt" "io/ioutil" "os" "path" "strings" "github.com/ghodss/yaml" gogetter "github.com/hashicorp/go-getter" "github.com/hashicorp/go-getter/helper/url" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/pkg/errors" log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) const ( DefaultCacheDir = ".cache" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Internal data structure to hold app related info. // +k8s:openapi-gen=true type KfConfig struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec KfConfigSpec `json:"spec,omitempty"` Status Status `json:"status,omitempty"` } // The spec of kKfConfig type KfConfigSpec struct { // Shared fields among all components. should limit this list. // TODO(gabrielwen): Deprecate AppDir and move it to cache in Status. AppDir string `json:"appDir,omitempty"` // The filename of the config, e.g. app.yaml. // Base name only, as the directory is AppDir above. ConfigFileName string `json:"configFileName,omitempty"` Version string `json:"version,omitempty"` // TODO(gabrielwen): Can we infer this from Applications? UseBasicAuth bool `json:"useBasicAuth,omitempty"` Platform string `json:"platform,omitempty"` // TODO(gabrielwen): Deprecate these fields as they only makes sense to GCP. Project string `json:"project,omitempty"` Email string `json:"email,omitempty"` IpName string `json:"ipName,omitempty"` Hostname string `json:"hostname,omitempty"` SkipInitProject bool `json:"skipInitProject,omitempty"` Zone string `json:"zone,omitempty"` DeleteStorage bool `json:"deleteStorage,omitempty"` Applications []Application `json:"applications,omitempty"` Plugins []Plugin `json:"plugins,omitempty"` Secrets []Secret `json:"secrets,omitempty"` Repos []Repo `json:"repos,omitempty"` } // Application defines an application to install type Application struct { Name string `json:"name,omitempty"` KustomizeConfig *KustomizeConfig `json:"kustomizeConfig,omitempty"` } type KustomizeConfig struct { RepoRef *RepoRef `json:"repoRef,omitempty"` Overlays []string `json:"overlays,omitempty"` Parameters []NameValue `json:"parameters,omitempty"` } type RepoRef struct { Name string `json:"name,omitempty"` Path string `json:"path,omitempty"` } type NameValue struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` } type Plugin struct { Name string `json:"name,omitempty"` Namespace string `json:"namespace,omitempty"` Kind PluginKindType `json:"kind,omitempty"` Spec *runtime.RawExtension `json:"spec,omitempty"` } // Secret provides information about secrets needed to configure Kubeflow. // Secrets can be provided via references. type Secret struct { Name string `json:"name,omitempty"` SecretSource *SecretSource `json:"secretSource,omitempty"` } type SecretSource struct { LiteralSource *LiteralSource `json:"literalSource,omitempty"` HashedSource *HashedSource `json:"hashedSource,omitempty"` EnvSource *EnvSource `json:"envSource,omitempty"` } type LiteralSource struct { Value string `json:"value,omitempty"` } type HashedSource struct { HashedValue string `json:"value,omitempty"` } type EnvSource struct { Name string `json:"name,omitempty"` } // SecretRef is a reference to a secret type SecretRef struct { // Name of the secret Name string `json:"name,omitempty"` } // Repo provides information about a repository providing config (e.g. kustomize packages, // Deployment manager configs, etc...) type Repo struct { // Name is a name to identify the repository. Name string `json:"name,omitempty"` // URI where repository can be obtained. // Can use any URI understood by go-getter: // https://github.com/hashicorp/go-getter/blob/master/README.md#installation-and-usage URI string `json:"uri,omitempty"` } type Status struct { Conditions []Condition `json:"conditions,omitempty"` Caches []Cache `json:"caches,omitempty"` } type Condition struct { // Type of deployment condition. Type ConditionType `json:"type,omitempty"` // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status,omitempty"` // The last time this condition was updated. LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` // Last time the condition transitioned from one status to another. LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` // The reason for the condition's last transition. Reason string `json:"reason,omitempty"` // A human readable message indicating details about the transition. Message string `json:"message,omitempty"` } type Cache struct { Name string `json:"name,omitempty"` LocalPath string `json:"localPath,omitempty"` } type PluginKindType string const ( // Used for populating plugin missing errors and identifying those // errors. pluginNotFoundErrPrefix = "Missing plugin" // Used for populating plugin missing errors and identifying those // errors. conditionNotFoundErrPrefix = "Missing condition" ) // Plugin kind used starting from v1beta1 const ( AWS_PLUGIN_KIND PluginKindType = "KfAwsPlugin" GCP_PLUGIN_KIND PluginKindType = "KfGcpPlugin" MINIKUBE_PLUGIN_KIND PluginKindType = "KfMinikubePlugin" EXISTING_ARRIKTO_PLUGIN_KIND PluginKindType = "KfExistingArriktoPlugin" ) type ConditionType string const ( // Available means Kubeflow is serving. Available ConditionType = "Available" // Degraded means one or more Kubeflow services are not healthy. Degraded ConditionType = "Degraded" // Pending means Kubeflow services is being updated. Pending ConditionType = "Pending" ) // Define plugin related conditions to be the format: // - conditions for successful plugins: ${PluginKind}Succeeded // - conditions for failed plugins: ${PluginKind}Failed func GetPluginSucceededCondition(pluginKind PluginKindType) ConditionType { return ConditionType(fmt.Sprintf("%vSucceeded", pluginKind)) } func GetPluginFailedCondition(pluginKind PluginKindType) ConditionType { return ConditionType(fmt.Sprintf("%vFailed", pluginKind)) } // Returns the repo with the name and true if repo exists. // nil and false otherwise. func (c *KfConfig) GetRepoCache(repoName string) (Cache, bool) { for _, r := range c.Status.Caches { if r.Name == repoName { return r, true } } return Cache{}, false } func (c *KfConfig) GetPluginSpec(pluginKind PluginKindType, s interface{}) error { for _, p := range c.Spec.Plugins { if p.Kind != pluginKind { continue } // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(p.Spec) if err != nil { msg := fmt.Sprintf("Could not marshal plugin %v args; error %v", pluginKind, err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: msg, } } err = yaml.Unmarshal(specBytes, s) if err != nil { msg := fmt.Sprintf("Could not unmarshal plugin %v to the provided type; error %v", pluginKind, err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: msg, } } return nil } return &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("%v %v", pluginNotFoundErrPrefix, pluginKind), } } // SetPluginSpec sets the requested parameter: add the plugin if it doesn't already exist, or replace existing plugin. func (c *KfConfig) SetPluginSpec(pluginKind PluginKindType, spec interface{}) error { // Convert spec to RawExtension r := &runtime.RawExtension{} // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(spec) if err != nil { msg := fmt.Sprintf("Could not marshal spec; error %v", err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: msg, } } err = yaml.Unmarshal(specBytes, r) if err != nil { msg := fmt.Sprintf("Could not unmarshal plugin to RawExtension; error %v", err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: msg, } } index := -1 for i, p := range c.Spec.Plugins { if p.Kind == pluginKind { index = i break } } if index == -1 { // Plugin in doesn't exist so add it log.Infof("Adding plugin %v", pluginKind) p := Plugin{} p.Name = string(pluginKind) p.Kind = pluginKind c.Spec.Plugins = append(c.Spec.Plugins, p) index = len(c.Spec.Plugins) - 1 } c.Spec.Plugins[index].Spec = r return nil } // Sets condition and status to KfConfig. func (c *KfConfig) SetCondition(condType ConditionType, status v1.ConditionStatus, reason string, message string) { now := metav1.Now() cond := Condition{ Type: condType, Status: status, LastUpdateTime: now, LastTransitionTime: now, Reason: reason, Message: message, } for i := range c.Status.Conditions { if c.Status.Conditions[i].Type != condType { continue } if c.Status.Conditions[i].Status == status { cond.LastTransitionTime = c.Status.Conditions[i].LastTransitionTime } c.Status.Conditions[i] = cond return } c.Status.Conditions = append(c.Status.Conditions, cond) } // Gets condition from KfConfig. func (c *KfConfig) GetCondition(condType ConditionType) (*Condition, error) { for i := range c.Status.Conditions { if c.Status.Conditions[i].Type == condType { return &c.Status.Conditions[i], nil } } return nil, &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("%v %v", conditionNotFoundErrPrefix, condType), } } func (c *KfConfig) IsPluginFinished(pluginKind PluginKindType) bool { condType := GetPluginSucceededCondition(pluginKind) cond, err := c.GetCondition(condType) if err != nil { if IsConditionNotFound(err) { return false } log.Warnf("Error when getting condition info: %v", err) return false } return cond.Status == v1.ConditionTrue } func (c *KfConfig) SetPluginFinished(pluginKind PluginKindType, msg string) { succeededCond := GetPluginSucceededCondition(pluginKind) failedCond := GetPluginFailedCondition(pluginKind) if _, err := c.GetCondition(failedCond); err == nil { c.SetCondition(failedCond, v1.ConditionFalse, "", "Reset to false as the plugin is set to be finished.") } c.SetCondition(succeededCond, v1.ConditionTrue, "", msg) } func (c *KfConfig) IsPluginFailed(pluginKind PluginKindType) bool { condType := GetPluginFailedCondition(pluginKind) cond, err := c.GetCondition(condType) if err != nil { if IsConditionNotFound(err) { return false } log.Warnf("Error when getting condition info: %v", err) return false } return cond.Status == v1.ConditionTrue } func (c *KfConfig) SetPluginFailed(pluginKind PluginKindType, msg string) { succeededCond := GetPluginSucceededCondition(pluginKind) failedCond := GetPluginFailedCondition(pluginKind) if _, err := c.GetCondition(succeededCond); err == nil { c.SetCondition(succeededCond, v1.ConditionFalse, "", "Reset to false as the plugin is set to be failed.") } c.SetCondition(failedCond, v1.ConditionTrue, "", msg) } // SyncCache will synchronize the local cache of any repositories. // On success the status is updated with pointers to the cache. // // TODO(jlewi): I'm not sure this handles head references correctly. // e.g. suppose we have a URI like // https://github.com/kubeflow/manifests/tarball/pull/189/head?archive=tar.gz // This gets unpacked to: kubeflow-manifests-e2c1bcb where e2c1bcb is the commit. // I don't think the code is currently setting the local directory for the cache correctly in // that case. // // // Using tarball vs. archive in github links affects the download path // e.g. // https://github.com/kubeflow/manifests/tarball/master?archive=tar.gz // unpacks to kubeflow-manifests-${COMMIT} // https://github.com/kubeflow/manifests/archive/master.tar.gz // unpacks to manifests-master // Always use archive format so that the path is predetermined. // // Instructions: https://github.com/hashicorp/go-getter#protocol-specific-options // // What is the correct syntax for downloading pull requests? // The following doesn't seem to work // https://github.com/kubeflow/manifests/archive/master.tar.gz?ref=pull/188 // * Appears to download master // // This appears to work // https://github.com/kubeflow/manifests/tarball/pull/188/head?archive=tar.gz // But unpacks it into // kubeflow-manifests-${COMMIT} // func (c *KfConfig) SyncCache() error { if c.Spec.AppDir == "" { return fmt.Errorf("AppDir must be specified") } appDir := c.Spec.AppDir // Loop over all the repos and download them. // TODO(https://github.com/kubeflow/kubeflow/issues/3545): We should check if we already have a local copy and // not redownload it. baseCacheDir := path.Join(appDir, DefaultCacheDir) if _, err := os.Stat(baseCacheDir); os.IsNotExist(err) { log.Infof("Creating directory %v", baseCacheDir) appdirErr := os.MkdirAll(baseCacheDir, os.ModePerm) if appdirErr != nil { log.Errorf("Couldn't create directory %v: %v", baseCacheDir, appdirErr) return appdirErr } } for _, r := range c.Spec.Repos { cacheDir := path.Join(baseCacheDir, r.Name) // Can we use a checksum or other mechanism to verify if the existing location is good? // If there was a problem the first time around then removing it might provide a way to recover. if _, err := os.Stat(cacheDir); err == nil { // Check if the cache is up to date. shouldSkip := false for _, cache := range c.Status.Caches { if cache.Name == r.Name && cache.LocalPath != "" { shouldSkip = true break } } if shouldSkip { log.Infof("%v exists; not resyncing ", cacheDir) continue } log.Infof("Deleting cachedir %v because Status.ReposCache is out of date", cacheDir) // TODO(jlewi): The reason the cachedir might exist but not be stored in KfDef.status // is because of a backwards compatibility path in which we download the cache to construct // the KfDef. Specifically coordinator.CreateKfDefFromOptions is calling kftypes.DownloadFromCache // We don't want to rely on that method to set the cache because we have logic // below to set LocalPath that we don't want to duplicate. // Unfortunately this means we end up fetching the repo twice which is very inefficient. if err := os.RemoveAll(cacheDir); err != nil { log.Errorf("There was a problem deleting directory %v; error %v", cacheDir, err) return errors.WithStack(err) } } u, err := url.Parse(r.URI) if err != nil { log.Errorf("Could not parse URI %v; error %v", r.URI, err) return errors.WithStack(err) } log.Infof("Fetching %v to %v", r.URI, cacheDir) tarballUrlErr := gogetter.GetAny(cacheDir, r.URI) if tarballUrlErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't download URI %v: %v", r.URI, tarballUrlErr), } } // This is a bit of a hack to deal with the fact that GitHub tarballs // can unpack to a directory containing the commit. localPath := cacheDir if u.Scheme == "http" || u.Scheme == "https" { files, filesErr := ioutil.ReadDir(cacheDir) if filesErr != nil { log.Errorf("Error reading cachedir; error %v", filesErr) return errors.WithStack(filesErr) } subdir := files[0].Name() localPath = path.Join(cacheDir, subdir) } c.Status.Caches = append(c.Status.Caches, Cache{ Name: r.Name, LocalPath: localPath, }) log.Infof("Fetch succeeded; LocalPath %v", localPath) } return nil } // GetSecret returns the specified secret or an error if the secret isn't specified. func (c *KfConfig) GetSecret(name string) (string, error) { for _, s := range c.Spec.Secrets { if s.Name != name { continue } if s.SecretSource.LiteralSource != nil { return s.SecretSource.LiteralSource.Value, nil } if s.SecretSource.HashedSource != nil { return s.SecretSource.HashedSource.HashedValue, nil } if s.SecretSource.EnvSource != nil { return os.Getenv(s.SecretSource.EnvSource.Name), nil } return "", fmt.Errorf("No secret source provided for secret %v", name) } return "", NewSecretNotFound(name) } // GetSecretSource returns the SecretSource of the specified name or an error if the secret isn't specified. func (c *KfConfig) GetSecretSource(name string) (*SecretSource, error) { for _, s := range c.Spec.Secrets { if s.Name == name { return s.SecretSource, nil } } return nil, NewSecretNotFound(name) } // GetApplicationParameter gets the desired application parameter. func (c *KfConfig) GetApplicationParameter(appName string, paramName string) (string, bool) { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { for _, a := range c.Spec.Applications { if a.Name == appName { return getParameter(a.KustomizeConfig.Parameters, paramName) } } } return "", false } // SetApplicationParameter sets the desired application parameter. func (c *KfConfig) SetApplicationParameter(appName string, paramName string, value string) error { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { appIndex := -1 for i, a := range c.Spec.Applications { if a.Name == appName { appIndex = i } } if appIndex >= 0 { if c.Spec.Applications[appIndex].KustomizeConfig == nil { return errors.WithStack(fmt.Errorf("Application %v doesn't have KustomizeConfig", appName)) } c.Spec.Applications[appIndex].KustomizeConfig.Parameters = setParameter( c.Spec.Applications[appIndex].KustomizeConfig.Parameters, paramName, value) return nil } } log.Warnf("Application %v not found", appName) return nil } // SetSecret sets the specified secret; if a secret with the given name already exists it is overwritten. func (c *KfConfig) SetSecret(newSecret Secret) { for i, s := range c.Spec.Secrets { if s.Name == newSecret.Name { c.Spec.Secrets[i] = newSecret return } } c.Spec.Secrets = append(c.Spec.Secrets, newSecret) } func IsPluginNotFound(e error) bool { if e == nil { return false } err, ok := e.(*kfapis.KfError) return ok && err.Code == int(kfapis.NOT_FOUND) && strings.HasPrefix(err.Message, pluginNotFoundErrPrefix) } func IsConditionNotFound(e error) bool { if e == nil { return false } err, ok := e.(*kfapis.KfError) return ok && err.Code == int(kfapis.NOT_FOUND) && strings.HasPrefix(err.Message, conditionNotFoundErrPrefix) } type SecretNotFound struct { Name string } func (e *SecretNotFound) Error() string { return fmt.Sprintf("Missing secret %v", e.Name) } func NewSecretNotFound(n string) *SecretNotFound { return &SecretNotFound{ Name: n, } } func IsSecretNotFound(e error) bool { if e == nil { return false } _, ok := e.(*SecretNotFound) return ok } type AppNotFound struct { Name string } func (e *AppNotFound) Error() string { return fmt.Sprintf("Application %v is missing", e.Name) } func IsAppNotFound(e error) bool { if e == nil { return false } _, ok := e.(*AppNotFound) return ok } func getParameter(parameters []NameValue, paramName string) (string, bool) { for _, p := range parameters { if p.Name == paramName { return p.Value, true } } return "", false } func setParameter(parameters []NameValue, paramName string, value string) []NameValue { pIndex := -1 for i, p := range parameters { if p.Name == paramName { pIndex = i } } if pIndex < 0 { parameters = append(parameters, NameValue{}) pIndex = len(parameters) - 1 } parameters[pIndex].Name = paramName parameters[pIndex].Value = value return parameters } ================================================ FILE: pkg/apis/apps/kfconfig/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 kfconfig import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AppNotFound) DeepCopyInto(out *AppNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppNotFound. func (in *AppNotFound) DeepCopy() *AppNotFound { if in == nil { return nil } out := new(AppNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Application) DeepCopyInto(out *Application) { *out = *in if in.KustomizeConfig != nil { in, out := &in.KustomizeConfig, &out.KustomizeConfig *out = new(KustomizeConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. func (in *Application) DeepCopy() *Application { if in == nil { return nil } out := new(Application) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Cache) DeepCopyInto(out *Cache) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cache. func (in *Cache) DeepCopy() *Cache { if in == nil { return nil } out := new(Cache) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Condition) DeepCopyInto(out *Condition) { *out = *in in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. func (in *Condition) DeepCopy() *Condition { if in == nil { return nil } out := new(Condition) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvSource) DeepCopyInto(out *EnvSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvSource. func (in *EnvSource) DeepCopy() *EnvSource { if in == nil { return nil } out := new(EnvSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HashedSource) DeepCopyInto(out *HashedSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashedSource. func (in *HashedSource) DeepCopy() *HashedSource { if in == nil { return nil } out := new(HashedSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfConfig) DeepCopyInto(out *KfConfig) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfConfig. func (in *KfConfig) DeepCopy() *KfConfig { if in == nil { return nil } out := new(KfConfig) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfConfig) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfConfigSpec) DeepCopyInto(out *KfConfigSpec) { *out = *in if in.Applications != nil { in, out := &in.Applications, &out.Applications *out = make([]Application, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]Plugin, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Secrets != nil { in, out := &in.Secrets, &out.Secrets *out = make([]Secret, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Repos != nil { in, out := &in.Repos, &out.Repos *out = make([]Repo, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfConfigSpec. func (in *KfConfigSpec) DeepCopy() *KfConfigSpec { if in == nil { return nil } out := new(KfConfigSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(RepoRef) **out = **in } if in.Overlays != nil { in, out := &in.Overlays, &out.Overlays *out = make([]string, len(*in)) copy(*out, *in) } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters *out = make([]NameValue, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeConfig. func (in *KustomizeConfig) DeepCopy() *KustomizeConfig { if in == nil { return nil } out := new(KustomizeConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LiteralSource) DeepCopyInto(out *LiteralSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LiteralSource. func (in *LiteralSource) DeepCopy() *LiteralSource { if in == nil { return nil } out := new(LiteralSource) 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 *Plugin) DeepCopyInto(out *Plugin) { *out = *in if in.Spec != nil { in, out := &in.Spec, &out.Spec *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin. func (in *Plugin) DeepCopy() *Plugin { if in == nil { return nil } out := new(Plugin) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Repo) DeepCopyInto(out *Repo) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repo. func (in *Repo) DeepCopy() *Repo { if in == nil { return nil } out := new(Repo) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoRef) DeepCopyInto(out *RepoRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoRef. func (in *RepoRef) DeepCopy() *RepoRef { if in == nil { return nil } out := new(RepoRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Secret) DeepCopyInto(out *Secret) { *out = *in if in.SecretSource != nil { in, out := &in.SecretSource, &out.SecretSource *out = new(SecretSource) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Secret. func (in *Secret) DeepCopy() *Secret { if in == nil { return nil } out := new(Secret) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretNotFound) DeepCopyInto(out *SecretNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretNotFound. func (in *SecretNotFound) DeepCopy() *SecretNotFound { if in == nil { return nil } out := new(SecretNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. func (in *SecretRef) DeepCopy() *SecretRef { if in == nil { return nil } out := new(SecretRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretSource) DeepCopyInto(out *SecretSource) { *out = *in if in.LiteralSource != nil { in, out := &in.LiteralSource, &out.LiteralSource *out = new(LiteralSource) **out = **in } if in.HashedSource != nil { in, out := &in.HashedSource, &out.HashedSource *out = new(HashedSource) **out = **in } if in.EnvSource != nil { in, out := &in.EnvSource, &out.EnvSource *out = new(EnvSource) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretSource. func (in *SecretSource) DeepCopy() *SecretSource { if in == nil { return nil } out := new(SecretSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Status) DeepCopyInto(out *Status) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Caches != nil { in, out := &in.Caches, &out.Caches *out = make([]Cache, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. func (in *Status) DeepCopy() *Status { if in == nil { return nil } out := new(Status) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/apis/apps/kfdef/kfdef.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 kfdef contains kfdef related types package kfdef ================================================ FILE: pkg/apis/apps/kfdef/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/apis/apps/kfdef/v1/README.md ================================================ ## `KfDef` defines an interface for controlling Kubeflow resources In the following sections we explain what fields in `KfDefSpec` means. ### KfDefSpec.Applications This is the list of applications that Kubeflow cluster will be installed. - Name: Name identifier of the application. - KustomizeConfig: Configurations for Kustomize to find the manifests and additional information to apply to. #### KustomizeConfig - RepoRef: - Name: Name of the repo Kustomize will be looking into. The repo must be on the list of `KfDefSpec.Repos`. - Path: Relative path in the repo to find the manifests. - Overlays: A list of names to be applied as overlays. - Parameters: Name/value pair of parameters to override the parameters defined in manifests. Example: [link](https://github.com/kubeflow/manifests/blob/master/profiles/base/params.env#L3-L4) ### KfDefSpec.Plugins This is the list of plugins that Kubeflow will be run on top of. For example, platforms like GCP/AWS are part of plugins. - Definitions of plugins should go to [plugins folder](https://github.com/kubeflow/kfctl/tree/master/pkg/apis/apps/plugins). - Plugins must have associated [kfapp handler](https://github.com/kubeflow/kfctl/tree/master/pkg/kfapp) for them to be applied. ### KfDefSpec.Secrets This is a set of secrets Kubeflow needs during installation. - LiteralSource: User provides the secret information as literal string into `KfDef` yaml file. This is not recommended and we are planning to deprecate it. - EnvSource: User provides the name of ENV var and we will use the value for create the secret. ### KfDefSpec.Repos This is a list of GIT repositories that we will cache and use as reference during installations. - Name: The name identifier of the repository cached. - URI: The URI to download the repository. ================================================ FILE: pkg/apis/apps/kfdef/v1/application_types.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 v1 import ( "fmt" "github.com/ghodss/yaml" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" valid "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "os" "strings" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfDef is the Schema for the applications API // +k8s:openapi-gen=true type KfDef struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec KfDefSpec `json:"spec,omitempty"` Status KfDefStatus `json:"status,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfDefList contains a list of KfDef type KfDefList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []KfDef `json:"items"` } type KfDefSpec struct { Version string `json:"version,omitempty"` Applications []Application `json:"applications,omitempty"` Plugins []Plugin `json:"plugins,omitempty"` Secrets []Secret `json:"secrets,omitempty"` Repos []Repo `json:"repos,omitempty"` } // Application defines an application to install type Application struct { Name string `json:"name,omitempty"` KustomizeConfig *KustomizeConfig `json:"kustomizeConfig,omitempty"` } type KustomizeConfig struct { RepoRef *RepoRef `json:"repoRef,omitempty"` Overlays []string `json:"overlays,omitempty"` Parameters []NameValue `json:"parameters,omitempty"` } type RepoRef struct { Name string `json:"name,omitempty"` Path string `json:"path,omitempty"` } type NameValue struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` } // Plugin can be used to customize the generation and deployment of Kubeflow type Plugin struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec *runtime.RawExtension `json:"spec,omitempty"` } // Secret provides information about secrets needed to configure Kubeflow. // Secrets can be provided via references. type Secret struct { Name string `json:"name,omitempty"` SecretSource *SecretSource `json:"secretSource,omitempty"` } type SecretSource struct { LiteralSource *LiteralSource `json:"literalSource,omitempty"` EnvSource *EnvSource `json:"envSource,omitempty"` } type LiteralSource struct { Value string `json:"value,omitempty"` } type EnvSource struct { Name string `json:"name,omitempty"` } // SecretRef is a reference to a secret type SecretRef struct { // Name of the secret Name string `json:"name,omitempty"` } // Repo provides information about a repository providing config (e.g. kustomize packages, // Deployment manager configs, etc...) type Repo struct { // Name is a name to identify the repository. Name string `json:"name,omitempty"` // URI where repository can be obtained. // Can use any URI understood by go-getter: // https://github.com/hashicorp/go-getter/blob/master/README.md#installation-and-usage URI string `json:"uri,omitempty"` } // KfDefStatus defines the observed state of KfDef type KfDefStatus struct { Conditions []KfDefCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // ReposCache is used to cache information about local caching of the URIs. ReposCache []RepoCache `json:"reposCache,omitempty"` } type RepoCache struct { Name string `json:"name,omitempty"` LocalPath string `json:"localPath,string"` } type KfDefConditionType string const ( // KfAvailable means Kubeflow is serving. KfAvailable KfDefConditionType = "Available" // KfDegraded means one or more Kubeflow services are not healthy. KfDegraded KfDefConditionType = "Degraded" // Pending means Kubeflow services is being updated. Pending KfDefConditionType = "Pending" ) type KfDefCondition struct { // Type of deployment condition. Type KfDefConditionType `json:"type"` // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status"` // The last time this condition was updated. LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` // Last time the condition transitioned from one status to another. LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` // The reason for the condition's last transition. Reason string `json:"reason,omitempty"` // A human readable message indicating details about the transition. Message string `json:"message,omitempty"` } // GetPluginSpec will try to unmarshal the spec for the specified plugin to the supplied // interface. Returns an error if the plugin isn't defined or if there is a problem // unmarshaling it. func (d *KfDef) GetPluginSpec(pluginKind string, s interface{}) error { for _, p := range d.Spec.Plugins { if p.Kind != pluginKind { continue } // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(p.Spec) if err != nil { log.Errorf("Could not marshal plugin %v args; error %v", pluginKind, err) return err } err = yaml.Unmarshal(specBytes, s) if err != nil { log.Errorf("Could not unmarshal plugin %v to the provided type; error %v", pluginKind, err) } return nil } return &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("Plugin not found: %v", pluginKind), } } // SetPluginSpec sets the requested parameter: add the plugin if it doesn't already exist, or replace existing plugin. func (d *KfDef) SetPluginSpec(pluginKind string, spec interface{}) error { // Convert spec to RawExtension r := &runtime.RawExtension{} // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(spec) if err != nil { log.Errorf("Could not marshal spec; error %v", err) return err } err = yaml.Unmarshal(specBytes, r) if err != nil { log.Errorf("Could not unmarshal plugin to RawExtension; error %v", err) } index := -1 for i, p := range d.Spec.Plugins { if p.Kind == pluginKind { index = i break } } if index == -1 { // Plugin in doesn't exist so add it log.Infof("Adding plugin %v", pluginKind) p := Plugin{} p.Name = string(pluginKind) p.Kind = pluginKind d.Spec.Plugins = append(d.Spec.Plugins, p) index = len(d.Spec.Plugins) - 1 } d.Spec.Plugins[index].Spec = r return nil } // GetSecret returns the specified secret or an error if the secret isn't specified. func (d *KfDef) GetSecret(name string) (string, error) { for _, s := range d.Spec.Secrets { if s.Name != name { continue } if s.SecretSource.LiteralSource != nil { return s.SecretSource.LiteralSource.Value, nil } if s.SecretSource.EnvSource != nil { return os.Getenv(s.SecretSource.EnvSource.Name), nil } return "", fmt.Errorf("No secret source provided for secret %v", name) } return "", &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("Secret not found: %v", name), } } // SetSecret sets the specified secret; if a secret with the given name already exists it is overwritten. func (d *KfDef) SetSecret(newSecret Secret) { for i, s := range d.Spec.Secrets { if s.Name == newSecret.Name { d.Spec.Secrets[i] = newSecret return } } d.Spec.Secrets = append(d.Spec.Secrets, newSecret) } func (d *KfDef) DeleteApplication(appName string) { // First we check applications for an application with the specified name. if d.Spec.Applications != nil { applications := []Application{} for _, a := range d.Spec.Applications { if a.Name != appName { applications = append(applications, a) } } d.Spec.Applications = applications } } // IsValid returns true if the spec is a valid and complete spec. // If false it will also return a string providing a message about why its invalid. func (d *KfDef) IsValid() (bool, string) { // Validate KfConfig errs := valid.NameIsDNSLabel(d.Name, false) if errs != nil && len(errs) > 0 { return false, fmt.Sprintf("invalid name due to %v", strings.Join(errs, ",")) } return true, "" } ================================================ FILE: pkg/apis/apps/kfdef/v1/application_types_test.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 v1 import ( "encoding/json" "github.com/ghodss/yaml" "github.com/prometheus/common/log" "io/ioutil" "os" "path" "reflect" "testing" ) type FakePluginSpec struct { Param string `json:"param,omitempty"` BoolParam bool `json:"boolParam,omitempty"` } func TestKfDef_GetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { Filename string PluginKind string Expected *FakePluginSpec } cases := []testCase{ { Filename: "kfctl_plugin_test.yaml", PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "someparam", BoolParam: true, }, }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Filename) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } log.Infof("Want ") d := &KfDef{} err := yaml.Unmarshal(buf, d) if err != nil { t.Fatalf("Could not parse as KfDef error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginKind, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfDef_SetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { PluginKind string Expected *FakePluginSpec } cases := []testCase{ { PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "oldparam", BoolParam: true, }, }, // Override the existing plugin { PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, // Add a new plugin { PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, } d := &KfDef{} for _, c := range cases { err := d.SetPluginSpec(c.PluginKind, c.Expected) if err != nil { t.Fatalf("Could not set plugin spec; error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginKind, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfDef_GetSecret(t *testing.T) { d := &KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "somedata", }, }, }, { Name: "s2", SecretSource: &SecretSource{ EnvSource: &EnvSource{ Name: "s2", }, }, }, }, }, } type testCase struct { SecretName string ExpectedValue string } cases := []testCase{ { SecretName: "s1", ExpectedValue: "somedata", }, { SecretName: "s2", ExpectedValue: "somesecret", }, } os.Setenv("s2", "somesecret") for _, c := range cases { actual, err := d.GetSecret(c.SecretName) if err != nil { t.Errorf("Error getting secret %v; error %v", c.SecretName, err) } if actual != c.ExpectedValue { t.Errorf("Secret %v value is wrong; got %v; want %v", c.SecretName, actual, c.ExpectedValue) } } } func TestKfDef_SetSecret(t *testing.T) { type testCase struct { Input KfDef Secret Secret Expected KfDef } cases := []testCase{ // No Secrets exist { Input: KfDef{}, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, Expected: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, }, }, }, }, // Override a secret { Input: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "oldvalue", }, }, }, }, }, }, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, Expected: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, }, }, }, }, } for _, c := range cases { i := &KfDef{} *i = c.Input i.SetSecret(c.Secret) if !reflect.DeepEqual(*i, c.Expected) { pGot, _ := Pformat(i) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting secret %v; got;\n%v\nwant;\n%v", c.Secret.Name, pGot, pWant) } } } func Test_DeleteApplication(t *testing.T) { type testCase struct { Filename string DeleteAppName string Expected []Application } cases := []testCase{ { Filename: "kfctl_plugin_test.yaml", DeleteAppName: "delete", Expected: []Application{ { Name: "keep", }, }, }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Filename) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } log.Infof("Want ") d := &KfDef{} err := yaml.Unmarshal(buf, d) if err != nil { t.Fatalf("Could not parse as KfDef error %v", err) } d.DeleteApplication(c.DeleteAppName) if !reflect.DeepEqual(d.Spec.Applications, c.Expected) { pGot, _ := Pformat(d.Spec.Applications) pWant, _ := Pformat(c.Expected) t.Errorf("Error deleting applicaitons got;\n%v\nwant;\n%v", pGot, pWant) } } } // Pformat returns a pretty format output of any value. func Pformat(value interface{}) (string, error) { if s, ok := value.(string); ok { return s, nil } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { return "", err } return string(valueJson), nil } ================================================ FILE: pkg/apis/apps/kfdef/v1/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 v1 contains API Schema definitions for the kfdef v1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1 ================================================ FILE: pkg/apis/apps/kfdef/v1/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1 contains API Schema definitions for the kfdef v1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "kfdef.apps.kubeflow.org", Version: "v1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfDef{}, &KfDefList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/kfdef/v1/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/apis/apps/kfdef/v1/testdata/kfctl_plugin_test.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1 kind: KfDef spec: applications: - name: delete - name: keep plugins: - kind: fakeplugin spec: param: someparam boolParam: true ================================================ FILE: pkg/apis/apps/kfdef/v1/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 v1 import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Application) DeepCopyInto(out *Application) { *out = *in if in.KustomizeConfig != nil { in, out := &in.KustomizeConfig, &out.KustomizeConfig *out = new(KustomizeConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. func (in *Application) DeepCopy() *Application { if in == nil { return nil } out := new(Application) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvSource) DeepCopyInto(out *EnvSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvSource. func (in *EnvSource) DeepCopy() *EnvSource { if in == nil { return nil } out := new(EnvSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDef) DeepCopyInto(out *KfDef) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDef. func (in *KfDef) DeepCopy() *KfDef { if in == nil { return nil } out := new(KfDef) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfDef) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefCondition) DeepCopyInto(out *KfDefCondition) { *out = *in in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefCondition. func (in *KfDefCondition) DeepCopy() *KfDefCondition { if in == nil { return nil } out := new(KfDefCondition) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefList) DeepCopyInto(out *KfDefList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]KfDef, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefList. func (in *KfDefList) DeepCopy() *KfDefList { if in == nil { return nil } out := new(KfDefList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfDefList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefSpec) DeepCopyInto(out *KfDefSpec) { *out = *in if in.Applications != nil { in, out := &in.Applications, &out.Applications *out = make([]Application, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]Plugin, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Secrets != nil { in, out := &in.Secrets, &out.Secrets *out = make([]Secret, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Repos != nil { in, out := &in.Repos, &out.Repos *out = make([]Repo, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefSpec. func (in *KfDefSpec) DeepCopy() *KfDefSpec { if in == nil { return nil } out := new(KfDefSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefStatus) DeepCopyInto(out *KfDefStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]KfDefCondition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.ReposCache != nil { in, out := &in.ReposCache, &out.ReposCache *out = make([]RepoCache, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefStatus. func (in *KfDefStatus) DeepCopy() *KfDefStatus { if in == nil { return nil } out := new(KfDefStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(RepoRef) **out = **in } if in.Overlays != nil { in, out := &in.Overlays, &out.Overlays *out = make([]string, len(*in)) copy(*out, *in) } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters *out = make([]NameValue, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeConfig. func (in *KustomizeConfig) DeepCopy() *KustomizeConfig { if in == nil { return nil } out := new(KustomizeConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LiteralSource) DeepCopyInto(out *LiteralSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LiteralSource. func (in *LiteralSource) DeepCopy() *LiteralSource { if in == nil { return nil } out := new(LiteralSource) 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 *Plugin) DeepCopyInto(out *Plugin) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) if in.Spec != nil { in, out := &in.Spec, &out.Spec *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin. func (in *Plugin) DeepCopy() *Plugin { if in == nil { return nil } out := new(Plugin) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Repo) DeepCopyInto(out *Repo) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repo. func (in *Repo) DeepCopy() *Repo { if in == nil { return nil } out := new(Repo) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoCache) DeepCopyInto(out *RepoCache) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoCache. func (in *RepoCache) DeepCopy() *RepoCache { if in == nil { return nil } out := new(RepoCache) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoRef) DeepCopyInto(out *RepoRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoRef. func (in *RepoRef) DeepCopy() *RepoRef { if in == nil { return nil } out := new(RepoRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Secret) DeepCopyInto(out *Secret) { *out = *in if in.SecretSource != nil { in, out := &in.SecretSource, &out.SecretSource *out = new(SecretSource) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Secret. func (in *Secret) DeepCopy() *Secret { if in == nil { return nil } out := new(Secret) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. func (in *SecretRef) DeepCopy() *SecretRef { if in == nil { return nil } out := new(SecretRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretSource) DeepCopyInto(out *SecretSource) { *out = *in if in.LiteralSource != nil { in, out := &in.LiteralSource, &out.LiteralSource *out = new(LiteralSource) **out = **in } if in.EnvSource != nil { in, out := &in.EnvSource, &out.EnvSource *out = new(EnvSource) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretSource. func (in *SecretSource) DeepCopy() *SecretSource { if in == nil { return nil } out := new(SecretSource) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/application_types.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 v1alpha1 import ( "fmt" "io/ioutil" netUrl "net/url" "os" "path" "strings" "github.com/ghodss/yaml" gogetter "github.com/hashicorp/go-getter" "github.com/hashicorp/go-getter/helper/url" "github.com/kubeflow/kfctl/v3/config" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/pkg/errors" log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" valid "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) // KfDefSpec holds common attributes used by each platform type KfDefSpec struct { config.ComponentConfig `json:",inline"` // TODO(jlewi): Why is AppDir a part of the spec? AppDir is currently used // to refer to the location on disk where all the manifests are stored. // But that should be treated as a local cache and not part of the spec. // For example, if the app is checked out on a different machine the AppDir will change. // AppDir. AppDir is stored in KfDefSpec because we pass a KfDef around to // as a way to pass the information to all the KfApps that need to know the local AppDir. // A better solution might be to store AppDir in KfDef.Status to better reflect its // ephemeral nature and match K8s semantics. AppDir string `json:"appdir,omitempty"` Version string `json:"version,omitempty"` MountLocal bool `json:"mountLocal,omitempty"` // TODO(jlewi): Project, Email, IpName, Hostname, Zone and other // GCP specific values should be moved into GCP plugin. Project string `json:"project,omitempty"` Email string `json:"email,omitempty"` IpName string `json:"ipName,omitempty"` Hostname string `json:"hostname,omitempty"` Zone string `json:"zone,omitempty"` UseBasicAuth bool `json:"useBasicAuth"` SkipInitProject bool `json:"skipInitProject,omitempty"` UseIstio bool `json:"useIstio"` EnableApplications bool `json:"enableApplications"` ServerVersion string `json:"serverVersion,omitempty"` DeleteStorage bool `json:"deleteStorage,omitempty"` PackageManager string `json:"packageManager,omitempty"` Repos []Repo `json:"repos,omitempty"` Secrets []Secret `json:"secrets,omitempty"` Plugins []Plugin `json:"plugins,omitempty"` // Applications defines a list of applications to install Applications []Application `json:"applications,omitempty"` } var DefaultRegistry = RegistryConfig{ Name: "kubeflow", Repo: "https://github.com/kubeflow/kubeflow.git", Path: "kubeflow", } // Application defines an application to install type Application struct { Name string `json:"name,omitempty"` KustomizeConfig *KustomizeConfig `json:"kustomizeConfig,omitempty"` } type KustomizeConfig struct { RepoRef *RepoRef `json:"repoRef,omitempty"` Overlays []string `json:"overlays,omitempty"` Parameters []config.NameValue `json:"parameters,omitempty"` } type RepoRef struct { Name string `json:"name,omitempty"` Path string `json:"path,omitempty"` } // Plugin can be used to customize the generation and deployment of Kubeflow // TODO(jlewi): Should Plugin contain K8s TypeMeta so that we can use ApiVersion and Kind // to identify what it refers to? type Plugin struct { Name string `json:"name,omitempty"` // TODO(jlewi): Should we be using runtime.Object or runtime.RawExtension Spec *runtime.RawExtension `json:"spec,omitempty"` } // SecretRef is a reference to a secret type SecretRef struct { // Name of the secret Name string `json:"name,omitempty"` } // Repo provides information about a repository providing config (e.g. kustomize packages, // Deployment manager configs, etc...) type Repo struct { // Name is a name to identify the repository. Name string `json:"name,omitempty"` // URI where repository can be obtained. // Can use any URI understood by go-getter: // https://github.com/hashicorp/go-getter/blob/master/README.md#installation-and-usage Uri string `json:"uri,omitempty"` // Root is the relative path to use as the root. // TODO(jlewi): Get rid of this field. SyncCache now takes care of setting the directory // as needed. Root string `json:"root,omitempty"` } // Secret provides information about secrets needed to configure Kubeflow. // Secrets can be provided via references e.g. a URI so that they won't // be serialized as part of the KfDefSpec which is intended to be written into source control. type Secret struct { Name string `json:"name,omitempty"` SecretSource *SecretSource `json:"secretSource,omitempty"` } type SecretSource struct { LiteralSource *LiteralSource `json:"literalSource,omitempty"` HashedSource *HashedSource `json:"hashedSource,omitempty"` EnvSource *EnvSource `json:"envSource,omitempty"` } type LiteralSource struct { Value string `json:"value,omitempty"` } type HashedSource struct { HashedValue string `json:"value,omitempty"` } type EnvSource struct { Name string `json:"Name,omitempty"` } // RegistryConfig is used for two purposes: // 1. used during image build, to configure registries that should be baked into the bootstrapper docker image. // (See: https://github.com/kubeflow/kubeflow/blob/master/bootstrap/image_registries.yaml) // 2. used during app create rpc call, specifies a registry to be added to an app. // required info for registry: Name, Repo, Version, Path // Additionally if any of required fields is blank we will try to map with one of // the registries baked into the Docker image using the name. type RegistryConfig struct { Name string `json:"name,omitempty"` Repo string `json:"repo,omitempty"` Version string `json:"version,omitempty"` Path string `json:"path,omitempty"` RegUri string `json:"reguri,omitempty"` } type KsComponent struct { Name string `json:"name,omitempty"` Prototype string `json:"prototype,omitempty"` } type KsLibrary struct { Name string `json:"name"` Registry string `json:"registry"` Version string `json:"version"` } type KsParameter struct { // nested components are referenced as "a.b.c" where "a" or "b" may be a module name Component string `json:"component,omitempty"` Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` } type KsModule struct { Name string `json:"name"` Components []*KsComponent `json:"components,omitempty"` Modules []*KsModule `json:"modules,omitempty"` } type KsPackage struct { Name string `json:"name,omitempty"` // Registry should be the name of the registry containing the package. Registry string `json:"registry,omitempty"` } type Registry struct { // Name is the user defined name of a registry. Name string `json:"-"` // Protocol is the registry protocol for this registry. Currently supported // values are `github`, `fs`, `helm`. Protocol string `json:"protocol"` // URI is the location of the registry. URI string `json:"uri"` } type LibrarySpec struct { Version string Path string } // KsRegistry corresponds to ksonnet.io/registry // which is the registry.yaml file found in every registry. type KsRegistry struct { ApiVersion string Kind string Libraries map[string]LibrarySpec } // RegistriesConfigFile corresponds to a YAML file specifying information // about known registries. type RegistriesConfigFile struct { // Registries provides information about known registries. Registries []*RegistryConfig } type AppConfig struct { Registries []*RegistryConfig `json:"registries,omitempty"` Packages []KsPackage `json:"packages,omitempty"` Components []KsComponent `json:"components,omitempty"` Parameters []KsParameter `json:"parameters,omitempty"` // Parameters to apply when creating the ksonnet components ApplyParameters []KsParameter `json:"applyParameters,omitempty"` } // KfDefStatus defines the observed state of KfDef type KfDefStatus struct { Conditions []KfDefCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,6,rep,name=conditions"` // ReposCache is used to cache information about local caching of the URIs. ReposCache map[string]RepoCache `json:"reposCache,omitempty"` } type RepoCache struct { LocalPath string `json:"localPath,string"` } type KfDefConditionType string const ( // KfCreated means the KfDef spec has been created. KfCreated KfDefConditionType = "Created" // KfDeploying means Kubeflow is in the process of being deployed. KfDeploying KfDefConditionType = "Deploying" // KfSucceeded means Kubeflow was successfully deployed. KfSucceeded KfDefConditionType = "Succeeded" // KfFailed meansthere was a problem deploying Kubeflow. KfFailed KfDefConditionType = "Failed" // Reasons for conditions // InvalidKfDefSpecReason indicates the KfDef was not valid. InvalidKfDefSpecReason = "InvalidKfDefSpec" ) type KfDefCondition struct { // Type of deployment condition. Type KfDefConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=KfDefConditionType"` // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"` // The last time this condition was updated. LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,6,opt,name=lastUpdateTime"` // Last time the condition transitioned from one status to another. LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,7,opt,name=lastTransitionTime"` // The reason for the condition's last transition. Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` // A human readable message indicating details about the transition. Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfDef is the Schema for the applications API // +k8s:openapi-gen=true type KfDef struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec KfDefSpec `json:"spec,omitempty"` Status KfDefStatus `json:"status,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfDefList contains a list of KfDef type KfDefList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []KfDef `json:"items"` } // GetDefaultRegistry return reference of a newly copied Default Registry func GetDefaultRegistry() *RegistryConfig { newReg := DefaultRegistry return &newReg } const DefaultCacheDir = ".cache" func isValidUrl(toTest string) bool { _, err := netUrl.ParseRequestURI(toTest) if err != nil { return false } else { return true } } // TODO: THIS FUNCTION IS DEPRECATED. PLEASE USE `LoadKFDefFromURI` in kfloader.go // LoadKFDefFromURI constructs a KfDef given the path to a YAML file // specifying a YAML config file. // configFile is the path to the YAML file containing the KfDef spec. Can be any URI supported by hashicorp // go-getter. func LoadKFDefFromURI(configFile string) (*KfDef, error) { if configFile == "" { return nil, fmt.Errorf("config file must be the URI of a KfDef spec") } // TODO(jlewi): We should check if configFile doesn't specify a protocol or the protocol // is file:// then we can just read it rather than fetching with go-getter. appDir, err := ioutil.TempDir("", "") if err != nil { return nil, fmt.Errorf("Create a temporary directory to copy the file to.") } // Open config file // // TODO(jlewi): Should we use hashicorp go-getter.GetAny here? We use that to download // the tarballs for the repos. Maybe we should use that here as well to be consistent. appFile := path.Join(appDir, "tmp_app.yaml") log.Infof("Downloading %v to %v", configFile, appFile) configFileUri, err := netUrl.Parse(configFile) if err != nil { log.Errorf("Could not parse configFile url") } if isValidUrl(configFile) { errGet := gogetter.GetFile(appFile, configFile) if errGet != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err), } } } else { g := new(gogetter.FileGetter) g.Copy = true errGet := g.GetFile(appFile, configFileUri) if errGet != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err), } } } // Read contents configFileBytes, err := ioutil.ReadFile(appFile) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not read from config file %s: %v", configFile, err), } } // Unmarshal content onto KfDef struct kfDef := &KfDef{} if err := yaml.Unmarshal(configFileBytes, kfDef); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not unmarshal config file onto KfDef struct: %v", err), } } return kfDef, nil } // SyncCache will synchronize the local cache of any repositories. // On success the status is updated with pointers to the cache. // // TODO(jlewi): I'm not sure this handles head references correctly. // e.g. suppose we have a URI like // https://github.com/kubeflow/manifests/tarball/pull/189/head?archive=tar.gz // This gets unpacked to: kubeflow-manifests-e2c1bcb where e2c1bcb is the commit. // I don't think the code is currently setting the local directory for the cache correctly in // that case. // // // Using tarball vs. archive in github links affects the download path // e.g. // https://github.com/kubeflow/manifests/tarball/master?archive=tar.gz // unpacks to kubeflow-manifests-${COMMIT} // https://github.com/kubeflow/manifests/archive/master.tar.gz // unpacks to manifests-master // Always use archive format so that the path is predetermined. // // Instructions: https://github.com/hashicorp/go-getter#protocol-specific-options // // What is the correct syntax for downloading pull requests? // The following doesn't seem to work // https://github.com/kubeflow/manifests/archive/master.tar.gz?ref=pull/188 // * Appears to download master // // This appears to work // https://github.com/kubeflow/manifests/tarball/pull/188/head?archive=tar.gz // But unpacks it into // kubeflow-manifests-${COMMIT} // func (d *KfDef) SyncCache() error { if d.Spec.AppDir == "" { return fmt.Errorf("AppDir must be specified") } if d.Status.ReposCache == nil { d.Status.ReposCache = make(map[string]RepoCache) } appDir := d.Spec.AppDir // Loop over all the repos and download them. // TODO(https://github.com/kubeflow/kubeflow/issues/3545): We should check if we already have a local copy and // not redownload it. baseCacheDir := path.Join(appDir, DefaultCacheDir) if _, err := os.Stat(baseCacheDir); os.IsNotExist(err) { log.Infof("Creating directory %v", baseCacheDir) appdirErr := os.MkdirAll(baseCacheDir, os.ModePerm) if appdirErr != nil { log.Errorf("Couldn't create directory %v: %v", baseCacheDir, appdirErr) return appdirErr } } for _, r := range d.Spec.Repos { cacheDir := path.Join(baseCacheDir, r.Name) // Can we use a checksum or other mechanism to verify if the existing location is good? // If there was a problem the first time around then removing it might provide a way to recover. if _, err := os.Stat(cacheDir); err == nil { if _, ok := d.Status.ReposCache[r.Name]; ok && d.Status.ReposCache[r.Name].LocalPath != "" { log.Infof("%v exists; not resyncing ", cacheDir) continue } log.Infof("Deleting cachedir %v because Status.ReposCache is out of date", cacheDir) // TODO(jlewi): The reason the cachedir might exist but not be stored in KfDef.status // is because of a backwards compatibility path in which we download the cache to construct // the KfDef. Specifically coordinator.CreateKfDefFromOptions is calling kftypes.DownloadFromCache // We don't want to rely on that method to set the cache because we have logic // below to set LocalPath that we don't want to duplicate. // Unfortunately this means we end up fetching the repo twice which is very inefficient. if err := os.RemoveAll(cacheDir); err != nil { log.Errorf("There was a problem deleting directory %v; error %v", cacheDir, err) return errors.WithStack(err) } } u, err := url.Parse(r.Uri) if err != nil { log.Errorf("Could not parse URI %v; error %v", r.Uri, err) return errors.WithStack(err) } log.Infof("Fetching %v to %v", r.Uri, cacheDir) tarballUrlErr := gogetter.GetAny(cacheDir, r.Uri) if tarballUrlErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't download URI %v: %v", r.Uri, tarballUrlErr), } } // This is a bit of a hack to deal with the fact that GitHub tarballs // can unpack to a directory containing the commit. localPath := cacheDir if u.Scheme == "http" || u.Scheme == "https" { files, filesErr := ioutil.ReadDir(cacheDir) if filesErr != nil { log.Errorf("Error reading cachedir; error %v", filesErr) return errors.WithStack(filesErr) } subdir := files[0].Name() localPath = path.Join(cacheDir, subdir) } d.Status.ReposCache[r.Name] = RepoCache{ LocalPath: localPath, } log.Infof("Fetch succeeded; LocalPath %v", d.Status.ReposCache[r.Name].LocalPath) } return nil } // GetSecret returns the specified secret or an error if the secret isn't specified. func (d *KfDef) GetSecret(name string) (string, error) { for _, s := range d.Spec.Secrets { if s.Name != name { continue } if s.SecretSource.LiteralSource != nil { return s.SecretSource.LiteralSource.Value, nil } if s.SecretSource.HashedSource != nil { return s.SecretSource.HashedSource.HashedValue, nil } if s.SecretSource.EnvSource != nil { return os.Getenv(s.SecretSource.EnvSource.Name), nil } return "", fmt.Errorf("No secret source provided for secret %v", name) } return "", NewSecretNotFound(name) } // SetSecret sets the specified secret; if a secret with the given name already exists it is overwritten. func (d *KfDef) SetSecret(newSecret Secret) { for i, s := range d.Spec.Secrets { if s.Name == newSecret.Name { d.Spec.Secrets[i] = newSecret return } } d.Spec.Secrets = append(d.Spec.Secrets, newSecret) } // GetPluginSpec will try to unmarshal the spec for the specified plugin to the supplied // interface. Returns an error if the plugin isn't defined or if there is a problem // unmarshaling it. func (d *KfDef) GetPluginSpec(pluginName string, s interface{}) error { for _, p := range d.Spec.Plugins { if p.Name != pluginName { continue } // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(p.Spec) if err != nil { log.Errorf("Could not marshal plugin %v args; error %v", pluginName, err) return err } err = yaml.Unmarshal(specBytes, s) if err != nil { log.Errorf("Could not unmarshal plugin %v to the provided type; error %v", pluginName, err) } return nil } return NewPluginNotFound(pluginName) } // SetPluginSpec sets the requested parameter. The plugin is added if it doesn't already exist. func (d *KfDef) SetPluginSpec(pluginName string, spec interface{}) error { // Convert spec to RawExtension r := &runtime.RawExtension{} // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(spec) if err != nil { log.Errorf("Could not marshal spec; error %v", err) return err } err = yaml.Unmarshal(specBytes, r) if err != nil { log.Errorf("Could not unmarshal plugin to RawExtension; error %v", err) } index := -1 for i, p := range d.Spec.Plugins { if p.Name == pluginName { index = i break } } if index == -1 { // Plugin in doesn't exist so add it log.Infof("Adding plugin %v", pluginName) d.Spec.Plugins = append(d.Spec.Plugins, Plugin{ Name: pluginName, }) index = len(d.Spec.Plugins) - 1 } d.Spec.Plugins[index].Spec = r return nil } // IsValid returns true if the spec is a valid and complete spec. // If false it will also return a string providing a message about why its invalid. func (d *KfDef) IsValid() (bool, string) { // TODO(jlewi): Add more validation and a unittest. // Validate kfDef errs := valid.NameIsDNSLabel(d.Name, false) if errs != nil && len(errs) > 0 { return false, fmt.Sprintf("invalid name due to %v", strings.Join(errs, ",")) } // PackageManager is currently required because we will try to load the package manager and get an error if // none is specified. if d.Spec.PackageManager == "" { return false, fmt.Sprintf("KfDef.Spec.PackageManager is required") } return true, "" } // WriteToFile write the KfDef to a file. // WriteToFile will strip out any literal secrets before writing it func (d *KfDef) WriteToFile(path string) error { stripped := d.DeepCopy() secrets := make([]Secret, 0) for _, s := range stripped.Spec.Secrets { if s.SecretSource.LiteralSource != nil { log.Warnf("Stripping literal secret %v from KfDef before serializing it", s.Name) continue } secrets = append(secrets, s) } stripped.Spec.Secrets = secrets // Rewrite app.yaml buf, bufErr := yaml.Marshal(stripped) if bufErr != nil { log.Errorf("Error marshaling kfdev; %v", bufErr) return bufErr } log.Infof("Writing stripped KfDef to %v", path) return ioutil.WriteFile(path, buf, 0644) } type PluginNotFound struct { Name string } func (e *PluginNotFound) Error() string { return fmt.Sprintf("Missing plugin %v", e.Name) } func NewPluginNotFound(n string) *PluginNotFound { return &PluginNotFound{ Name: n, } } func IsPluginNotFound(e error) bool { if e == nil { return false } _, ok := e.(*PluginNotFound) return ok } type SecretNotFound struct { Name string } func (e *SecretNotFound) Error() string { return fmt.Sprintf("Missing secret %v", e.Name) } func NewSecretNotFound(n string) *SecretNotFound { return &SecretNotFound{ Name: n, } } func IsSecretNotFound(e error) bool { if e == nil { return false } _, ok := e.(*SecretNotFound) return ok } func getParameter(parameters []config.NameValue, paramName string) (string, bool) { for _, p := range parameters { if p.Name == paramName { return p.Value, true } } return "", false } func setParameter(parameters []config.NameValue, paramName string, value string) []config.NameValue { pIndex := -1 for i, p := range parameters { if p.Name == paramName { pIndex = i } } if pIndex < 0 { parameters = append(parameters, config.NameValue{}) pIndex = len(parameters) - 1 } parameters[pIndex].Name = paramName parameters[pIndex].Value = value return parameters } type AppNotFound struct { Name string } func (e *AppNotFound) Error() string { return fmt.Sprintf("Application %v is missing", e.Name) } func IsAppNotFound(e error) bool { if e == nil { return false } _, ok := e.(*AppNotFound) return ok } // GetApplicationParameter gets the desired application parameter. func (d *KfDef) GetApplicationParameter(appName string, paramName string) (string, bool) { // First we check applications for an application with the specified name. if d.Spec.Applications != nil { for _, a := range d.Spec.Applications { if a.Name == appName { return getParameter(a.KustomizeConfig.Parameters, paramName) } } } // Since an application with the specified name wasn't found check the deprecated componentParams if _, ok := d.Spec.ComponentParams[appName]; ok { return getParameter(d.Spec.ComponentParams[appName], paramName) } return "", false } // SetApplicationParameter sets the desired application parameter. func (d *KfDef) SetApplicationParameter(appName string, paramName string, value string) error { // First we check applications for an application with the specified name. if d.Spec.Applications != nil { appIndex := -1 for i, a := range d.Spec.Applications { if a.Name == appName { appIndex = i } } if appIndex >= 0 { if d.Spec.Applications[appIndex].KustomizeConfig == nil { return errors.WithStack(fmt.Errorf("Application %v doesn't have KustomizeConfig", appName)) } d.Spec.Applications[appIndex].KustomizeConfig.Parameters = setParameter( d.Spec.Applications[appIndex].KustomizeConfig.Parameters, paramName, value) return nil } } // Since an application with the specified name wasn't found check the deprecated componentParams if _, ok := d.Spec.ComponentParams[appName]; ok { d.Spec.ComponentParams[appName] = setParameter(d.Spec.ComponentParams[appName], paramName, value) return nil } return &AppNotFound{Name: appName} } ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/application_types_test.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 v1alpha1 import ( "encoding/json" "fmt" "github.com/ghodss/yaml" "github.com/kubeflow/kfctl/v3/config" "github.com/prometheus/common/log" "io/ioutil" "os" "path" "reflect" "testing" ) // TODO(https://github.com/kubeflow/kubeflow/issues/3056): Fix the test and uncomment. //import ( // "testing" // // "github.com/onsi/gomega" // "golang.org/x/net/context" // metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // "k8s.io/apimachinery/pkg/types" //) // //func TestStorageApplication(t *testing.T) { // key := types.NamespacedName{ // Name: "foo", // Namespace: "default", // } // created := &KfDef{ // ObjectMeta: metav1.ObjectMeta{ // Name: "foo", // Namespace: "default", // }} // g := gomega.NewGomegaWithT(t) // // // Test Create // fetched := &KfDef{} // g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred()) // // g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) // g.Expect(fetched).To(gomega.Equal(created)) // // // Test Updating the Labels // updated := fetched.DeepCopy() // updated.Labels = map[string]string{"hello": "world"} // g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred()) // // g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred()) // g.Expect(fetched).To(gomega.Equal(updated)) // // // Test Delete // g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred()) // g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred()) //} // TODO(jlewi): We should add a unittest for the case where Status.ReposCache // points to some incorrect locations but the actual cache dir exists and is correct. func TestSyncCache(t *testing.T) { type testCase struct { input *KfDef expected map[string]RepoCache } // Verify that we can sync some files. testDir, _ := ioutil.TempDir("", "") srcDir := path.Join(testDir, "src") err := os.Mkdir(srcDir, os.ModePerm) if err != nil { t.Fatalf("Failed to create directoy; %v", err) } ioutil.WriteFile(path.Join(srcDir, "file1"), []byte("hello world"), os.ModePerm) repoName := "testRepo" testCases := []testCase{ { input: &KfDef{ Spec: KfDefSpec{ AppDir: path.Join(testDir, "app1"), Repos: []Repo{{ Name: repoName, Uri: srcDir, }, }, }, }, expected: map[string]RepoCache{ repoName: { LocalPath: path.Join(testDir, "app1", ".cache", repoName), }, }, }, // The following test cases pull from GitHub. The may be worth commenting // out in the unittests and only running manually //{ // input: &KfDef{ // Spec: KfDefSpec{ // AppDir: path.Join(testDir, "app2"), // Repos: []Repo{{ // Name: repoName, // Uri: "https://github.com/kubeflow/manifests/archive/master.tar.gz", // }, // }, // }, // }, // expected: map[string]RepoCache { // repoName: { // LocalPath: path.Join(testDir, "app2", ".cache", repoName, "manifests-master"), // }, // }, //}, //{ // input: &KfDef{ // Spec: KfDefSpec{ // AppDir: path.Join(testDir, "app3"), // Repos: []Repo{{ // Name: repoName, // Uri: "https://github.com/kubeflow/manifests/tarball/pull/187/head?archive=tar.gz", // }, // }, // }, // }, // expected: map[string]RepoCache { // repoName: { // LocalPath: path.Join(testDir, "app3", ".cache", repoName, "kubeflow-manifests-c04764b"), // }, // }, //}, } for _, c := range testCases { err = c.input.SyncCache() if err != nil { t.Fatalf("Could not sync cache; %v", err) } actual := c.input.Status.ReposCache[repoName].LocalPath expected := c.expected[repoName].LocalPath if actual != expected { t.Fatalf("LocalPath; got %v; want %v", actual, expected) } } } func TestWriteKfDef(t *testing.T) { // Verify that if we write KfDef it will be stripped of any literal secrets. type testCase struct { input *KfDef output *KfDef } cases := []testCase{ { input: &KfDef{ Spec: KfDefSpec{ AppDir: "someapp", Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "somedata", }, }, }, { Name: "s2", SecretSource: &SecretSource{ EnvSource: &EnvSource{ Name: "somesecret", }, }, }, }, }, }, output: &KfDef{ Spec: KfDefSpec{ AppDir: "someapp", Secrets: []Secret{ { Name: "s2", SecretSource: &SecretSource{ EnvSource: &EnvSource{ Name: "somesecret", }, }, }, }, }, }, }, } for _, c := range cases { testDir, _ := ioutil.TempDir("", "") testFile := path.Join(testDir, "app.yaml") err := c.input.WriteToFile(testFile) if err != nil { t.Fatalf("Could not write file; %v", err) } // Read contents configFileBytes, err := ioutil.ReadFile(testFile) if err != nil { t.Fatalf("Could not read file; %v", err) } result := &KfDef{} if err := yaml.Unmarshal(configFileBytes, result); err != nil { t.Fatalf("Could not unmarshal the result; %v", err) } // Test they are equal if !reflect.DeepEqual(result, c.output) { pExpected, _ := Pformat(c.output) pActual, _ := Pformat(result) t.Errorf("Result wasn't properly stripped: Got:\n%v;\n Want:\n%v", pActual, pExpected) } } } type FakePluginSpec struct { Param string `json:"param,omitempty"` BoolParam bool `json:"boolParam,omitempty"` } func TestKfDef_GetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { Filename string PluginName string Expected *FakePluginSpec } cases := []testCase{ { Filename: "kfctl_plugin_test.yaml", PluginName: "fakeplugin", Expected: &FakePluginSpec{ Param: "someparam", BoolParam: true, }, }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Filename) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } log.Infof("Want ") d := &KfDef{} err := yaml.Unmarshal(buf, d) if err != nil { t.Fatalf("Could not parse as KfDef error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginName, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfDef_SetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { PluginName string Expected *FakePluginSpec } cases := []testCase{ { PluginName: "fakeplugin", Expected: &FakePluginSpec{ Param: "oldparam", BoolParam: true, }, }, // Override the existing plugin { PluginName: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, // Add a new plugin { PluginName: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, } d := &KfDef{} for _, c := range cases { err := d.SetPluginSpec(c.PluginName, c.Expected) if err != nil { t.Fatalf("Could not set plugin spec; error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginName, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfDef_GetSecret(t *testing.T) { d := &KfDef{ Spec: KfDefSpec{ AppDir: "someapp", Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "somedata", }, }, }, { Name: "s2", SecretSource: &SecretSource{ EnvSource: &EnvSource{ Name: "s2", }, }, }, }, }, } type testCase struct { SecretName string ExpectedValue string } cases := []testCase{ { SecretName: "s1", ExpectedValue: "somedata", }, { SecretName: "s2", ExpectedValue: "somesecret", }, } os.Setenv("s2", "somesecret") for _, c := range cases { actual, err := d.GetSecret(c.SecretName) if err != nil { t.Errorf("Error getting secret %v; error %v", c.SecretName, err) } if actual != c.ExpectedValue { t.Errorf("Secret %v value is wrong; got %v; want %v", c.SecretName, actual, c.ExpectedValue) } } } func TestKfDef_SetSecret(t *testing.T) { type testCase struct { Input KfDef Secret Secret Expected KfDef } cases := []testCase{ // No Secrets exist { Input: KfDef{}, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, Expected: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, }, }, }, }, // Override a secret { Input: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "oldvalue", }, }, }, }, }, }, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, Expected: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, }, }, }, }, } for _, c := range cases { i := &KfDef{} *i = c.Input i.SetSecret(c.Secret) if !reflect.DeepEqual(*i, c.Expected) { pGot, _ := Pformat(i) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting secret %v; got;\n%v\nwant;\n%v", c.Secret.Name, pGot, pWant) } } } func Test_PluginNotFoundError(t *testing.T) { type testCase struct { Input error Expected bool } cases := []testCase{ { Input: NewPluginNotFound("someplugin"), Expected: true, }, { Input: fmt.Errorf("some error"), Expected: false, }, } for _, c := range cases { actual := IsPluginNotFound(c.Input) if actual != c.Expected { t.Errorf("IsPluginNotFound: Got %v; Want %v", actual, c.Expected) } } } func TestKfDef_SetApplicationParameter(t *testing.T) { type testCase struct { Input *KfDef AppName string ParamName string Value string Expected *KfDef } cases := []testCase{ // New parameter { Input: &KfDef{ Spec: KfDefSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{}, }, }, }, }, AppName: "app1", ParamName: "p1", Value: "v1", Expected: &KfDef{ Spec: KfDefSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []config.NameValue{ { Name: "p1", Value: "v1", }, }, }, }, }, }, }, }, // Override parameter { Input: &KfDef{ Spec: KfDefSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []config.NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, AppName: "app1", ParamName: "p1", Value: "v1", Expected: &KfDef{ Spec: KfDefSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []config.NameValue{ { Name: "p1", Value: "v1", }, }, }, }, }, }, }, }, // Test cases below deal with backwards compatibility when we don't have an application. // New parameter { Input: &KfDef{ Spec: KfDefSpec{ ComponentConfig: config.ComponentConfig{ ComponentParams: config.Parameters{ "app1": []config.NameValue{}, }, }, }, }, AppName: "app1", ParamName: "p1", Value: "v1", Expected: &KfDef{ Spec: KfDefSpec{ ComponentConfig: config.ComponentConfig{ ComponentParams: config.Parameters{ "app1": []config.NameValue{ { Name: "p1", Value: "v1", }, }, }, }, }, }, }, // Override parameter { Input: &KfDef{ Spec: KfDefSpec{ ComponentConfig: config.ComponentConfig{ ComponentParams: config.Parameters{ "app1": []config.NameValue{ { Name: "p1", Value: "oldvalue", }, }, }, }, }, }, AppName: "app1", ParamName: "p1", Value: "v1", Expected: &KfDef{ Spec: KfDefSpec{ ComponentConfig: config.ComponentConfig{ ComponentParams: config.Parameters{ "app1": []config.NameValue{ { Name: "p1", Value: "v1", }, }, }, }, }, }, }, } for _, c := range cases { c.Input.SetApplicationParameter(c.AppName, c.ParamName, c.Value) if !reflect.DeepEqual(c.Input, c.Expected) { pGot, _ := Pformat(c.Input) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting App %v; Param %v; value %v; got;\n%v\nwant;\n%v", c.AppName, c.ParamName, c.Value, pGot, pWant) } } } func TestKfDef_GetApplicationParameter(t *testing.T) { type testCase struct { Input *KfDef AppName string ParamName string Expected string HasParam bool } cases := []testCase{ // No parameter { Input: &KfDef{ Spec: KfDefSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{}, }, }, }, }, AppName: "app1", ParamName: "p1", Expected: "", HasParam: false, }, // Has Parameter { Input: &KfDef{ Spec: KfDefSpec{ Applications: []Application{ { Name: "app2", KustomizeConfig: &KustomizeConfig{ Parameters: []config.NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, AppName: "app2", ParamName: "p1", Expected: "old1", HasParam: true, }, // Test cases below deal with backwards compatibility when we don't have an application. // No parameter { Input: &KfDef{ Spec: KfDefSpec{ ComponentConfig: config.ComponentConfig{ ComponentParams: config.Parameters{ "app3": []config.NameValue{}, }, }, }, }, AppName: "app3", ParamName: "p1", Expected: "", HasParam: false, }, // Has parameter { Input: &KfDef{ Spec: KfDefSpec{ ComponentConfig: config.ComponentConfig{ ComponentParams: config.Parameters{ "app4": []config.NameValue{ { Name: "p1", Value: "oldvalue", }, }, }, }, }, }, AppName: "app4", ParamName: "p1", Expected: "oldvalue", HasParam: true, }, } for _, c := range cases { v, hasParam := c.Input.GetApplicationParameter(c.AppName, c.ParamName) if c.HasParam != hasParam { t.Errorf("Error getting App %v; Param %v; hasParam; got; %v; want %v", c.AppName, c.ParamName, hasParam, c.HasParam) } if c.Expected != v { t.Errorf("Error getting App %v; Param %v; got; %v; want %v", c.AppName, c.ParamName, c, c.Expected) } } } // Pformat returns a pretty format output of any value. func Pformat(value interface{}) (string, error) { if s, ok := value.(string); ok { return s, nil } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { return "", err } return string(valueJson), nil } ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/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 v1alpha1 contains API Schema definitions for the kfdef v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1alpha1 ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the kfdef v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "kfdef.apps.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfDef{}, &KfDefList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/testdata/kfctl_plugin_test.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1alpha1 kind: KfDef spec: plugins: - name: fakeplugin spec: param: someparam boolParam: true ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/v1alpha1_suite_test.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 v1alpha1 // TODO(https://github.com/kubeflow/kubeflow/issues/3056): Fix the test and uncomment. //import ( // "log" // "os" // "path/filepath" // "testing" // // "k8s.io/client-go/kubernetes/scheme" // "k8s.io/client-go/rest" // "sigs.k8s.io/controller-runtime/pkg/client" // "sigs.k8s.io/controller-runtime/pkg/envtest" //) // //var cfg *rest.Config //var c client.Client // //func TestMain(m *testing.M) { // t := &envtest.Environment{ // CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crds")}, // } // // err := SchemeBuilder.AddToScheme(scheme.Scheme) // if err != nil { // log.Fatal(err) // } // // if cfg, err = t.Start(); err != nil { // log.Fatal(err) // } // // if c, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}); err != nil { // log.Fatal(err) // } // // code := m.Run() // t.Stop() // os.Exit(code) //} ================================================ FILE: pkg/apis/apps/kfdef/v1alpha1/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 v1alpha1 import ( config "github.com/kubeflow/kfctl/v3/config" runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AppConfig) DeepCopyInto(out *AppConfig) { *out = *in if in.Registries != nil { in, out := &in.Registries, &out.Registries *out = make([]*RegistryConfig, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] *out = new(RegistryConfig) **out = **in } } } if in.Packages != nil { in, out := &in.Packages, &out.Packages *out = make([]KsPackage, len(*in)) copy(*out, *in) } if in.Components != nil { in, out := &in.Components, &out.Components *out = make([]KsComponent, len(*in)) copy(*out, *in) } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters *out = make([]KsParameter, len(*in)) copy(*out, *in) } if in.ApplyParameters != nil { in, out := &in.ApplyParameters, &out.ApplyParameters *out = make([]KsParameter, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppConfig. func (in *AppConfig) DeepCopy() *AppConfig { if in == nil { return nil } out := new(AppConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AppNotFound) DeepCopyInto(out *AppNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppNotFound. func (in *AppNotFound) DeepCopy() *AppNotFound { if in == nil { return nil } out := new(AppNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Application) DeepCopyInto(out *Application) { *out = *in if in.KustomizeConfig != nil { in, out := &in.KustomizeConfig, &out.KustomizeConfig *out = new(KustomizeConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. func (in *Application) DeepCopy() *Application { if in == nil { return nil } out := new(Application) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvSource) DeepCopyInto(out *EnvSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvSource. func (in *EnvSource) DeepCopy() *EnvSource { if in == nil { return nil } out := new(EnvSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HashedSource) DeepCopyInto(out *HashedSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashedSource. func (in *HashedSource) DeepCopy() *HashedSource { if in == nil { return nil } out := new(HashedSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDef) DeepCopyInto(out *KfDef) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDef. func (in *KfDef) DeepCopy() *KfDef { if in == nil { return nil } out := new(KfDef) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfDef) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefCondition) DeepCopyInto(out *KfDefCondition) { *out = *in in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefCondition. func (in *KfDefCondition) DeepCopy() *KfDefCondition { if in == nil { return nil } out := new(KfDefCondition) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefList) DeepCopyInto(out *KfDefList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]KfDef, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefList. func (in *KfDefList) DeepCopy() *KfDefList { if in == nil { return nil } out := new(KfDefList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfDefList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefSpec) DeepCopyInto(out *KfDefSpec) { *out = *in in.ComponentConfig.DeepCopyInto(&out.ComponentConfig) if in.Repos != nil { in, out := &in.Repos, &out.Repos *out = make([]Repo, len(*in)) copy(*out, *in) } if in.Secrets != nil { in, out := &in.Secrets, &out.Secrets *out = make([]Secret, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]Plugin, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Applications != nil { in, out := &in.Applications, &out.Applications *out = make([]Application, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefSpec. func (in *KfDefSpec) DeepCopy() *KfDefSpec { if in == nil { return nil } out := new(KfDefSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefStatus) DeepCopyInto(out *KfDefStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]KfDefCondition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.ReposCache != nil { in, out := &in.ReposCache, &out.ReposCache *out = make(map[string]RepoCache, len(*in)) for key, val := range *in { (*out)[key] = val } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefStatus. func (in *KfDefStatus) DeepCopy() *KfDefStatus { if in == nil { return nil } out := new(KfDefStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KsComponent) DeepCopyInto(out *KsComponent) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsComponent. func (in *KsComponent) DeepCopy() *KsComponent { if in == nil { return nil } out := new(KsComponent) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KsLibrary) DeepCopyInto(out *KsLibrary) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsLibrary. func (in *KsLibrary) DeepCopy() *KsLibrary { if in == nil { return nil } out := new(KsLibrary) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KsModule) DeepCopyInto(out *KsModule) { *out = *in if in.Components != nil { in, out := &in.Components, &out.Components *out = make([]*KsComponent, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] *out = new(KsComponent) **out = **in } } } if in.Modules != nil { in, out := &in.Modules, &out.Modules *out = make([]*KsModule, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] *out = new(KsModule) (*in).DeepCopyInto(*out) } } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsModule. func (in *KsModule) DeepCopy() *KsModule { if in == nil { return nil } out := new(KsModule) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KsPackage) DeepCopyInto(out *KsPackage) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsPackage. func (in *KsPackage) DeepCopy() *KsPackage { if in == nil { return nil } out := new(KsPackage) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KsParameter) DeepCopyInto(out *KsParameter) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsParameter. func (in *KsParameter) DeepCopy() *KsParameter { if in == nil { return nil } out := new(KsParameter) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KsRegistry) DeepCopyInto(out *KsRegistry) { *out = *in if in.Libraries != nil { in, out := &in.Libraries, &out.Libraries *out = make(map[string]LibrarySpec, len(*in)) for key, val := range *in { (*out)[key] = val } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KsRegistry. func (in *KsRegistry) DeepCopy() *KsRegistry { if in == nil { return nil } out := new(KsRegistry) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(RepoRef) **out = **in } if in.Overlays != nil { in, out := &in.Overlays, &out.Overlays *out = make([]string, len(*in)) copy(*out, *in) } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters *out = make([]config.NameValue, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeConfig. func (in *KustomizeConfig) DeepCopy() *KustomizeConfig { if in == nil { return nil } out := new(KustomizeConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LibrarySpec) DeepCopyInto(out *LibrarySpec) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibrarySpec. func (in *LibrarySpec) DeepCopy() *LibrarySpec { if in == nil { return nil } out := new(LibrarySpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LiteralSource) DeepCopyInto(out *LiteralSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LiteralSource. func (in *LiteralSource) DeepCopy() *LiteralSource { if in == nil { return nil } out := new(LiteralSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Plugin) DeepCopyInto(out *Plugin) { *out = *in if in.Spec != nil { in, out := &in.Spec, &out.Spec *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin. func (in *Plugin) DeepCopy() *Plugin { if in == nil { return nil } out := new(Plugin) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PluginNotFound) DeepCopyInto(out *PluginNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginNotFound. func (in *PluginNotFound) DeepCopy() *PluginNotFound { if in == nil { return nil } out := new(PluginNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RegistriesConfigFile) DeepCopyInto(out *RegistriesConfigFile) { *out = *in if in.Registries != nil { in, out := &in.Registries, &out.Registries *out = make([]*RegistryConfig, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] *out = new(RegistryConfig) **out = **in } } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistriesConfigFile. func (in *RegistriesConfigFile) DeepCopy() *RegistriesConfigFile { if in == nil { return nil } out := new(RegistriesConfigFile) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Registry) DeepCopyInto(out *Registry) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Registry. func (in *Registry) DeepCopy() *Registry { if in == nil { return nil } out := new(Registry) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig. func (in *RegistryConfig) DeepCopy() *RegistryConfig { if in == nil { return nil } out := new(RegistryConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Repo) DeepCopyInto(out *Repo) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repo. func (in *Repo) DeepCopy() *Repo { if in == nil { return nil } out := new(Repo) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoCache) DeepCopyInto(out *RepoCache) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoCache. func (in *RepoCache) DeepCopy() *RepoCache { if in == nil { return nil } out := new(RepoCache) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoRef) DeepCopyInto(out *RepoRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoRef. func (in *RepoRef) DeepCopy() *RepoRef { if in == nil { return nil } out := new(RepoRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Secret) DeepCopyInto(out *Secret) { *out = *in if in.SecretSource != nil { in, out := &in.SecretSource, &out.SecretSource *out = new(SecretSource) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Secret. func (in *Secret) DeepCopy() *Secret { if in == nil { return nil } out := new(Secret) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretNotFound) DeepCopyInto(out *SecretNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretNotFound. func (in *SecretNotFound) DeepCopy() *SecretNotFound { if in == nil { return nil } out := new(SecretNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. func (in *SecretRef) DeepCopy() *SecretRef { if in == nil { return nil } out := new(SecretRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretSource) DeepCopyInto(out *SecretSource) { *out = *in if in.LiteralSource != nil { in, out := &in.LiteralSource, &out.LiteralSource *out = new(LiteralSource) **out = **in } if in.HashedSource != nil { in, out := &in.HashedSource, &out.HashedSource *out = new(HashedSource) **out = **in } if in.EnvSource != nil { in, out := &in.EnvSource, &out.EnvSource *out = new(EnvSource) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretSource. func (in *SecretSource) DeepCopy() *SecretSource { if in == nil { return nil } out := new(SecretSource) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/README.md ================================================ ## `KfDef` defines an interface for controlling Kubeflow resources In the following sections we explain what fields in `KfDefSpec` means. ### KfDefSpec.Applications This is the list of applications that Kubeflow cluster will be installed. - Name: Name identifier of the application. - KustomizeConfig: Configurations for Kustomize to find the manifests and additional information to apply to. #### KustomizeConfig - RepoRef: - Name: Name of the repo Kustomize will be looking into. The repo must be on the list of `KfDefSpec.Repos`. - Path: Relative path in the repo to find the manifests. - Overlays: A list of names to be applied as overlays. - Parameters: Name/value pair of parameters to override the parameters defined in manifests. Example: [link](https://github.com/kubeflow/manifests/blob/master/profiles/base/params.env#L3-L4) ### KfDefSpec.Plugins This is the list of plugins that Kubeflow will be run on top of. For example, platforms like GCP/AWS are part of plugins. - Definitions of plugins should go to [plugins folder](https://github.com/kubeflow/kfctl/tree/master/pkg/apis/apps/plugins). - Plugins must have associated [kfapp handler](https://github.com/kubeflow/kfctl/tree/master/pkg/kfapp) for them to be applied. ### KfDefSpec.Secrets This is a set of secrets Kubeflow needs during installation. - LiteralSource: User provides the secret information as literal string into `KfDef` yaml file. This is not recommended and we are planning to deprecate it. - EnvSource: User provides the name of ENV var and we will use the value for create the secret. ### KfDefSpec.Repos This is a list of GIT repositories that we will cache and use as reference during installations. - Name: The name identifier of the repository cached. - URI: The URI to download the repository. ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/application_types.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 v1beta1 import ( "fmt" "github.com/ghodss/yaml" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" valid "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "os" "strings" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfDef is the Schema for the applications API // +k8s:openapi-gen=true type KfDef struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec KfDefSpec `json:"spec,omitempty"` Status KfDefStatus `json:"status,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfDefList contains a list of KfDef type KfDefList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []KfDef `json:"items"` } type KfDefSpec struct { Version string `json:"version,omitempty"` Applications []Application `json:"applications,omitempty"` Plugins []Plugin `json:"plugins,omitempty"` Secrets []Secret `json:"secrets,omitempty"` Repos []Repo `json:"repos,omitempty"` } // Application defines an application to install type Application struct { Name string `json:"name,omitempty"` KustomizeConfig *KustomizeConfig `json:"kustomizeConfig,omitempty"` } type KustomizeConfig struct { RepoRef *RepoRef `json:"repoRef,omitempty"` Overlays []string `json:"overlays,omitempty"` Parameters []NameValue `json:"parameters,omitempty"` } type RepoRef struct { Name string `json:"name,omitempty"` Path string `json:"path,omitempty"` } type NameValue struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` } // Plugin can be used to customize the generation and deployment of Kubeflow type Plugin struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec *runtime.RawExtension `json:"spec,omitempty"` } // Secret provides information about secrets needed to configure Kubeflow. // Secrets can be provided via references. type Secret struct { Name string `json:"name,omitempty"` SecretSource *SecretSource `json:"secretSource,omitempty"` } type SecretSource struct { LiteralSource *LiteralSource `json:"literalSource,omitempty"` EnvSource *EnvSource `json:"envSource,omitempty"` } type LiteralSource struct { Value string `json:"value,omitempty"` } type EnvSource struct { Name string `json:"name,omitempty"` } // SecretRef is a reference to a secret type SecretRef struct { // Name of the secret Name string `json:"name,omitempty"` } // Repo provides information about a repository providing config (e.g. kustomize packages, // Deployment manager configs, etc...) type Repo struct { // Name is a name to identify the repository. Name string `json:"name,omitempty"` // URI where repository can be obtained. // Can use any URI understood by go-getter: // https://github.com/hashicorp/go-getter/blob/master/README.md#installation-and-usage URI string `json:"uri,omitempty"` } // KfDefStatus defines the observed state of KfDef type KfDefStatus struct { Conditions []KfDefCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` // ReposCache is used to cache information about local caching of the URIs. ReposCache []RepoCache `json:"reposCache,omitempty"` } type RepoCache struct { Name string `json:"name,omitempty"` LocalPath string `json:"localPath,string"` } type KfDefConditionType string const ( // KfAvailable means Kubeflow is serving. KfAvailable KfDefConditionType = "Available" // KfDegraded means one or more Kubeflow services are not healthy. KfDegraded KfDefConditionType = "Degraded" // Pending means Kubeflow services is being updated. Pending KfDefConditionType = "Pending" ) type KfDefCondition struct { // Type of deployment condition. Type KfDefConditionType `json:"type"` // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status"` // The last time this condition was updated. LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` // Last time the condition transitioned from one status to another. LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` // The reason for the condition's last transition. Reason string `json:"reason,omitempty"` // A human readable message indicating details about the transition. Message string `json:"message,omitempty"` } // GetPluginSpec will try to unmarshal the spec for the specified plugin to the supplied // interface. Returns an error if the plugin isn't defined or if there is a problem // unmarshaling it. func (d *KfDef) GetPluginSpec(pluginKind string, s interface{}) error { for _, p := range d.Spec.Plugins { if p.Kind != pluginKind { continue } // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(p.Spec) if err != nil { log.Errorf("Could not marshal plugin %v args; error %v", pluginKind, err) return err } err = yaml.Unmarshal(specBytes, s) if err != nil { log.Errorf("Could not unmarshal plugin %v to the provided type; error %v", pluginKind, err) } return nil } return &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("Plugin not found: %v", pluginKind), } } // SetPluginSpec sets the requested parameter: add the plugin if it doesn't already exist, or replace existing plugin. func (d *KfDef) SetPluginSpec(pluginKind string, spec interface{}) error { // Convert spec to RawExtension r := &runtime.RawExtension{} // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(spec) if err != nil { log.Errorf("Could not marshal spec; error %v", err) return err } err = yaml.Unmarshal(specBytes, r) if err != nil { log.Errorf("Could not unmarshal plugin to RawExtension; error %v", err) } index := -1 for i, p := range d.Spec.Plugins { if p.Kind == pluginKind { index = i break } } if index == -1 { // Plugin in doesn't exist so add it log.Infof("Adding plugin %v", pluginKind) p := Plugin{} p.Name = string(pluginKind) p.Kind = pluginKind d.Spec.Plugins = append(d.Spec.Plugins, p) index = len(d.Spec.Plugins) - 1 } d.Spec.Plugins[index].Spec = r return nil } // GetSecret returns the specified secret or an error if the secret isn't specified. func (d *KfDef) GetSecret(name string) (string, error) { for _, s := range d.Spec.Secrets { if s.Name != name { continue } if s.SecretSource.LiteralSource != nil { return s.SecretSource.LiteralSource.Value, nil } if s.SecretSource.EnvSource != nil { return os.Getenv(s.SecretSource.EnvSource.Name), nil } return "", fmt.Errorf("No secret source provided for secret %v", name) } return "", &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("Secret not found: %v", name), } } // SetSecret sets the specified secret; if a secret with the given name already exists it is overwritten. func (d *KfDef) SetSecret(newSecret Secret) { for i, s := range d.Spec.Secrets { if s.Name == newSecret.Name { d.Spec.Secrets[i] = newSecret return } } d.Spec.Secrets = append(d.Spec.Secrets, newSecret) } func (d *KfDef) DeleteApplication(appName string) { // First we check applications for an application with the specified name. if d.Spec.Applications != nil { applications := []Application{} for _, a := range d.Spec.Applications { if a.Name != appName { applications = append(applications, a) } } d.Spec.Applications = applications } } // IsValid returns true if the spec is a valid and complete spec. // If false it will also return a string providing a message about why its invalid. func (d *KfDef) IsValid() (bool, string) { // Validate KfConfig errs := valid.NameIsDNSLabel(d.Name, false) if errs != nil && len(errs) > 0 { return false, fmt.Sprintf("invalid name due to %v", strings.Join(errs, ",")) } return true, "" } ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/application_types_test.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 v1beta1 import ( "encoding/json" "github.com/ghodss/yaml" "github.com/prometheus/common/log" "io/ioutil" "os" "path" "reflect" "testing" ) type FakePluginSpec struct { Param string `json:"param,omitempty"` BoolParam bool `json:"boolParam,omitempty"` } func TestKfDef_GetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { Filename string PluginKind string Expected *FakePluginSpec } cases := []testCase{ { Filename: "kfctl_plugin_test.yaml", PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "someparam", BoolParam: true, }, }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Filename) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } log.Infof("Want ") d := &KfDef{} err := yaml.Unmarshal(buf, d) if err != nil { t.Fatalf("Could not parse as KfDef error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginKind, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfDef_SetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { PluginKind string Expected *FakePluginSpec } cases := []testCase{ { PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "oldparam", BoolParam: true, }, }, // Override the existing plugin { PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, // Add a new plugin { PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, } d := &KfDef{} for _, c := range cases { err := d.SetPluginSpec(c.PluginKind, c.Expected) if err != nil { t.Fatalf("Could not set plugin spec; error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginKind, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfDef_GetSecret(t *testing.T) { d := &KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "somedata", }, }, }, { Name: "s2", SecretSource: &SecretSource{ EnvSource: &EnvSource{ Name: "s2", }, }, }, }, }, } type testCase struct { SecretName string ExpectedValue string } cases := []testCase{ { SecretName: "s1", ExpectedValue: "somedata", }, { SecretName: "s2", ExpectedValue: "somesecret", }, } os.Setenv("s2", "somesecret") for _, c := range cases { actual, err := d.GetSecret(c.SecretName) if err != nil { t.Errorf("Error getting secret %v; error %v", c.SecretName, err) } if actual != c.ExpectedValue { t.Errorf("Secret %v value is wrong; got %v; want %v", c.SecretName, actual, c.ExpectedValue) } } } func TestKfDef_SetSecret(t *testing.T) { type testCase struct { Input KfDef Secret Secret Expected KfDef } cases := []testCase{ // No Secrets exist { Input: KfDef{}, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, Expected: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, }, }, }, }, // Override a secret { Input: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "oldvalue", }, }, }, }, }, }, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, Expected: KfDef{ Spec: KfDefSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, }, }, }, }, } for _, c := range cases { i := &KfDef{} *i = c.Input i.SetSecret(c.Secret) if !reflect.DeepEqual(*i, c.Expected) { pGot, _ := Pformat(i) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting secret %v; got;\n%v\nwant;\n%v", c.Secret.Name, pGot, pWant) } } } func Test_DeleteApplication(t *testing.T) { type testCase struct { Filename string DeleteAppName string Expected []Application } cases := []testCase{ { Filename: "kfctl_plugin_test.yaml", DeleteAppName: "delete", Expected: []Application{ { Name: "keep", }, }, }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Filename) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } log.Infof("Want ") d := &KfDef{} err := yaml.Unmarshal(buf, d) if err != nil { t.Fatalf("Could not parse as KfDef error %v", err) } d.DeleteApplication(c.DeleteAppName) if !reflect.DeepEqual(d.Spec.Applications, c.Expected) { pGot, _ := Pformat(d.Spec.Applications) pWant, _ := Pformat(c.Expected) t.Errorf("Error deleting applicaitons got;\n%v\nwant;\n%v", pGot, pWant) } } } // Pformat returns a pretty format output of any value. func Pformat(value interface{}) (string, error) { if s, ok := value.(string); ok { return s, nil } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { return "", err } return string(valueJson), nil } ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/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 v1beta1 contains API Schema definitions for the kfdef v1beta1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1beta1 ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the kfdef v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1beta1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "kfdef.apps.kubeflow.org", Version: "v1beta1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfDef{}, &KfDefList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/testdata/kfctl_plugin_test.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1beta1 kind: KfDef spec: applications: - name: delete - name: keep plugins: - kind: fakeplugin spec: param: someparam boolParam: true ================================================ FILE: pkg/apis/apps/kfdef/v1beta1/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 v1beta1 import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Application) DeepCopyInto(out *Application) { *out = *in if in.KustomizeConfig != nil { in, out := &in.KustomizeConfig, &out.KustomizeConfig *out = new(KustomizeConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. func (in *Application) DeepCopy() *Application { if in == nil { return nil } out := new(Application) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvSource) DeepCopyInto(out *EnvSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvSource. func (in *EnvSource) DeepCopy() *EnvSource { if in == nil { return nil } out := new(EnvSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDef) DeepCopyInto(out *KfDef) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDef. func (in *KfDef) DeepCopy() *KfDef { if in == nil { return nil } out := new(KfDef) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfDef) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefCondition) DeepCopyInto(out *KfDefCondition) { *out = *in in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefCondition. func (in *KfDefCondition) DeepCopy() *KfDefCondition { if in == nil { return nil } out := new(KfDefCondition) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefList) DeepCopyInto(out *KfDefList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]KfDef, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefList. func (in *KfDefList) DeepCopy() *KfDefList { if in == nil { return nil } out := new(KfDefList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfDefList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefSpec) DeepCopyInto(out *KfDefSpec) { *out = *in if in.Applications != nil { in, out := &in.Applications, &out.Applications *out = make([]Application, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]Plugin, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Secrets != nil { in, out := &in.Secrets, &out.Secrets *out = make([]Secret, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Repos != nil { in, out := &in.Repos, &out.Repos *out = make([]Repo, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefSpec. func (in *KfDefSpec) DeepCopy() *KfDefSpec { if in == nil { return nil } out := new(KfDefSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefStatus) DeepCopyInto(out *KfDefStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]KfDefCondition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.ReposCache != nil { in, out := &in.ReposCache, &out.ReposCache *out = make([]RepoCache, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefStatus. func (in *KfDefStatus) DeepCopy() *KfDefStatus { if in == nil { return nil } out := new(KfDefStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(RepoRef) **out = **in } if in.Overlays != nil { in, out := &in.Overlays, &out.Overlays *out = make([]string, len(*in)) copy(*out, *in) } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters *out = make([]NameValue, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeConfig. func (in *KustomizeConfig) DeepCopy() *KustomizeConfig { if in == nil { return nil } out := new(KustomizeConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LiteralSource) DeepCopyInto(out *LiteralSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LiteralSource. func (in *LiteralSource) DeepCopy() *LiteralSource { if in == nil { return nil } out := new(LiteralSource) 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 *Plugin) DeepCopyInto(out *Plugin) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) if in.Spec != nil { in, out := &in.Spec, &out.Spec *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin. func (in *Plugin) DeepCopy() *Plugin { if in == nil { return nil } out := new(Plugin) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Repo) DeepCopyInto(out *Repo) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repo. func (in *Repo) DeepCopy() *Repo { if in == nil { return nil } out := new(Repo) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoCache) DeepCopyInto(out *RepoCache) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoCache. func (in *RepoCache) DeepCopy() *RepoCache { if in == nil { return nil } out := new(RepoCache) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoRef) DeepCopyInto(out *RepoRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoRef. func (in *RepoRef) DeepCopy() *RepoRef { if in == nil { return nil } out := new(RepoRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Secret) DeepCopyInto(out *Secret) { *out = *in if in.SecretSource != nil { in, out := &in.SecretSource, &out.SecretSource *out = new(SecretSource) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Secret. func (in *Secret) DeepCopy() *Secret { if in == nil { return nil } out := new(Secret) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. func (in *SecretRef) DeepCopy() *SecretRef { if in == nil { return nil } out := new(SecretRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretSource) DeepCopyInto(out *SecretSource) { *out = *in if in.LiteralSource != nil { in, out := &in.LiteralSource, &out.LiteralSource *out = new(LiteralSource) **out = **in } if in.EnvSource != nil { in, out := &in.EnvSource, &out.EnvSource *out = new(EnvSource) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretSource. func (in *SecretSource) DeepCopy() *SecretSource { if in == nil { return nil } out := new(SecretSource) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/apis/apps/kfupgrade/kfupgrade.go ================================================ // Copyright 2019 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 kfupgrade contains kfupgrade related types package kfupgrade ================================================ FILE: pkg/apis/apps/kfupgrade/v1alpha1/application_types.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 v1alpha1 import ( "fmt" "github.com/ghodss/yaml" gogetter "github.com/hashicorp/go-getter" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" log "github.com/sirupsen/logrus" "io/ioutil" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "path" ) const ( KfUpgradeFile = "update.yaml" ) type KfUpgradeSpec struct { // Reference to the current (existing) KfDef. CurrentKfDef *KfDefRef `json:"currentKfDef,omitempty"` // Reference to the new KfDef. // +optional NewKfDef *KfDefRef `json:"newKfDef,omitempty"` // Base config file used to generate the new KfDef. // +optional BaseConfigPath string `json:"baseConfigPath,omitempty"` } type KfDefRef struct { // Name of the referrent. Name string `json:"name,omitempty"` // Version of the referent. // +optional Version string `json:"version,omitempty"` } // KfUpgradeStatus defines the observed state of KfUpgrade type KfUpgradeStatus struct { Conditions []KfUpgradeCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,6,rep,name=conditions"` } type KfUpgradeConditionType string const ( // KfDeploying means Kubeflow is in the process of being deployed. KfUpgradeInProgress KfUpgradeConditionType = "InProgress" // KfSucceeded means Kubeflow was successfully deployed. KfUpgradeSucceeded KfUpgradeConditionType = "Succeeded" // KfFailed meansthere was a problem deploying Kubeflow. KfUpgradeFailed KfUpgradeConditionType = "Failed" // Reasons for conditions // InvalidKfUpgradeSpecReason indicates the KfUpgrade was not valid. InvalidKfUpgradeSpecReason = "InvalidKfUpgradeSpec" ) type KfUpgradeCondition struct { // Type of deployment condition. Type KfUpgradeConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=KfDefConditionType"` // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"` // The last time this condition was updated. LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty" protobuf:"bytes,6,opt,name=lastUpdateTime"` // Last time the condition transitioned from one status to another. LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,7,opt,name=lastTransitionTime"` // The reason for the condition's last transition. Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"` // A human readable message indicating details about the transition. Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfUpgrade is the Schema for the applications API // +k8s:openapi-gen=true type KfUpgrade struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec KfUpgradeSpec `json:"spec,omitempty"` Status KfUpgradeStatus `json:"status,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KfUpgradeList contains a list of KfUpgrade type KfUpgradeList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []KfUpgrade `json:"items"` } // LoadKfUpgradeFromUri constructs a KfUpgrade given the path to a YAML file. // configFile is the path to the YAML file containing the KfDef spec. Can be any URI supported by hashicorp // go-getter. func LoadKfUpgradeFromUri(configFile string) (*KfUpgrade, error) { if configFile == "" { return nil, fmt.Errorf("config file must be the URI of a KfDef spec") } appDir, err := ioutil.TempDir("", "") if err != nil { return nil, fmt.Errorf("Create a temporary directory to copy the file to.") } // Open config file appFile := path.Join(appDir, KfUpgradeFile) log.Infof("Downloading %v to %v", configFile, appFile) err = gogetter.GetFile(appFile, configFile) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err), } } // Read contents configFileBytes, err := ioutil.ReadFile(appFile) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not read from config file %s: %v", configFile, err), } } // Unmarshal content onto KfUpgrade struct kfUpgrade := &KfUpgrade{} if err := yaml.Unmarshal(configFileBytes, kfUpgrade); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not unmarshal config file onto KfUpgrade struct: %v", err), } } return kfUpgrade, nil } // WriteToFile write the KfUpgrade to a file. func (u *KfUpgrade) WriteToFile(path string) error { // Write app.yaml buf, bufErr := yaml.Marshal(u) if bufErr != nil { log.Errorf("Error marshaling kfdev; %v", bufErr) return bufErr } log.Infof("Writing KfUpgrade to %v", path) return ioutil.WriteFile(path, buf, 0644) } ================================================ FILE: pkg/apis/apps/kfupgrade/v1alpha1/doc.go ================================================ // Copyright 2019 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 v1alpha1 contains API Schema definitions for the kfupgrade v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfupgrade // +k8s:defaulter-gen=TypeMeta // +groupName=kfupgrade.apps.kubeflow.org package v1alpha1 ================================================ FILE: pkg/apis/apps/kfupgrade/v1alpha1/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the kfdef v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfupdate // +k8s:defaulter-gen=TypeMeta // +groupName=kfupdate.apps.kubeflow.org package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "kfupdate.apps.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfUpgrade{}, &KfUpgradeList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/kfupgrade/v1alpha1/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 v1alpha1 import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfDefRef) DeepCopyInto(out *KfDefRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfDefRef. func (in *KfDefRef) DeepCopy() *KfDefRef { if in == nil { return nil } out := new(KfDefRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfUpgrade) DeepCopyInto(out *KfUpgrade) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfUpgrade. func (in *KfUpgrade) DeepCopy() *KfUpgrade { if in == nil { return nil } out := new(KfUpgrade) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfUpgrade) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfUpgradeCondition) DeepCopyInto(out *KfUpgradeCondition) { *out = *in in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfUpgradeCondition. func (in *KfUpgradeCondition) DeepCopy() *KfUpgradeCondition { if in == nil { return nil } out := new(KfUpgradeCondition) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfUpgradeList) DeepCopyInto(out *KfUpgradeList) { *out = *in out.TypeMeta = in.TypeMeta out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items *out = make([]KfUpgrade, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfUpgradeList. func (in *KfUpgradeList) DeepCopy() *KfUpgradeList { if in == nil { return nil } out := new(KfUpgradeList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfUpgradeList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfUpgradeSpec) DeepCopyInto(out *KfUpgradeSpec) { *out = *in if in.CurrentKfDef != nil { in, out := &in.CurrentKfDef, &out.CurrentKfDef *out = new(KfDefRef) **out = **in } if in.NewKfDef != nil { in, out := &in.NewKfDef, &out.NewKfDef *out = new(KfDefRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfUpgradeSpec. func (in *KfUpgradeSpec) DeepCopy() *KfUpgradeSpec { if in == nil { return nil } out := new(KfUpgradeSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfUpgradeStatus) DeepCopyInto(out *KfUpgradeStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]KfUpgradeCondition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfUpgradeStatus. func (in *KfUpgradeStatus) DeepCopy() *KfUpgradeStatus { if in == nil { return nil } out := new(KfUpgradeStatus) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/apis/apps/plugins/aws/aws.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 aws ================================================ FILE: pkg/apis/apps/plugins/aws/v1alpha1/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 v1beta1 contains API Schema definitions for the kfdef v1beta1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1alpha1 ================================================ FILE: pkg/apis/apps/plugins/aws/v1alpha1/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the KfAwsPlugin v1alpha1. // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/aws // +k8s:defaulter-gen=TypeMeta // +groupName=aws.plugins.kubeflow.org package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "aws.plugins.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfAwsPlugin{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/plugins/aws/v1alpha1/types.go ================================================ package v1alpha1 import ( kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:openapi-gen=true // Placeholder for the plugin API. type KfAwsPlugin struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec AwsPluginSpec `json:"spec,omitempty"` } // AwsPlugin defines the extra data provided by the GCP Plugin in KfDef type AwsPluginSpec struct { Auth *Auth `json:"auth,omitempty"` Region string `json:"region,omitempty"` Roles []string `json:"roles,omitempty"` } type Auth struct { BasicAuth *BasicAuth `json:"basicAuth,omitempty"` Oidc *OIDC `json:"oidc,omitempty"` Cognito *Coginito `json:"cognito,omitempty"` } type BasicAuth struct { Username string `json:"username,omitempty"` Password *kfdeftypes.SecretRef `json:"password,omitempty"` } type OIDC struct { OidcAuthorizationEndpoint string `json:"oidcAuthorizationEndpoint,omitempty"` OidcIssuer string `json:"oidcIssuer,omitempty"` OidcTokenEndpoint string `json:"oidcTokenEndpoint,omitempty"` OidcUserInfoEndpoint string `json:"oidcUserInfoEndpoint,omitempty"` CertArn string `json:"certArn,omitempty"` OAuthClientId string `json:"oAuthClientId,omitempty"` OAuthClientSecret string `json:"oAuthClientSecret,omitempty"` } type Coginito struct { CognitoAppClientId string `json:"cognitoAppClientId,omitempty"` CognitoUserPoolArn string `json:"cognitoUserPoolArn,omitempty"` CognitoUserPoolDomain string `json:"cognitoUserPoolDomain,omitempty"` CertArn string `json:"certArn,omitempty"` } // IsValid returns true if the spec is a valid and complete spec. // If false it will also return a string providing a message about why its invalid. func (plugin *AwsPluginSpec) IsValid() (bool, string) { basicAuthSet := plugin.Auth.BasicAuth != nil oidcAuthSet := plugin.Auth.Oidc != nil cognitoAuthSet := plugin.Auth.Cognito != nil if basicAuthSet { msg := "" isValid := true if plugin.Auth.BasicAuth.Username == "" { isValid = false msg += "BasicAuth requires username. " } if plugin.Auth.BasicAuth.Password == nil { isValid = false msg += "BasicAuth requires password. " } return isValid, msg } if oidcAuthSet { msg := "" isValid := true if plugin.Auth.Oidc.OidcAuthorizationEndpoint == "" { isValid = false msg += "OidcAuthorizationEndpoint is required" } if plugin.Auth.Oidc.OidcIssuer == "" { isValid = false msg += "OidcIssuer is required" } if plugin.Auth.Oidc.OidcTokenEndpoint == "" { isValid = false msg += "OidcTokenEndpoint is required" } if plugin.Auth.Oidc.OidcUserInfoEndpoint == "" { isValid = false msg += "OidcUserInfoEndpoint is required" } if plugin.Auth.Oidc.CertArn == "" { isValid = false msg += "CertArn is required" } if plugin.Auth.Oidc.OAuthClientId == "" { isValid = false msg += "OAuthClientId is required" } if plugin.Auth.Oidc.OAuthClientSecret == "" { isValid = false msg += "OAuthClientSecret is required" } return isValid, msg } if cognitoAuthSet { msg := "" isValid := true if plugin.Auth.Cognito.CognitoAppClientId == "" { isValid = false msg += "CognitoAppClientId is required" } if plugin.Auth.Cognito.CognitoUserPoolArn == "" { isValid = false msg += "CognitoUserPoolArn is required" } if plugin.Auth.Cognito.CognitoUserPoolDomain == "" { isValid = false msg += "CognitoUserPoolDomain is required" } if plugin.Auth.Cognito.CertArn == "" { isValid = false msg += "CertArn is required" } return isValid, msg } // return false, "Either BasicAuth, ODC or Cognito must be set" // TODO: BasicAuth is configured to be working in AWS env. Let's add validation back once it's supported. return true, "" } ================================================ FILE: pkg/apis/apps/plugins/aws/v1alpha1/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 v1alpha1 import ( v1beta1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Auth) DeepCopyInto(out *Auth) { *out = *in if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(BasicAuth) (*in).DeepCopyInto(*out) } if in.Oidc != nil { in, out := &in.Oidc, &out.Oidc *out = new(OIDC) **out = **in } if in.Cognito != nil { in, out := &in.Cognito, &out.Cognito *out = new(Coginito) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth. func (in *Auth) DeepCopy() *Auth { if in == nil { return nil } out := new(Auth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AwsPluginSpec) DeepCopyInto(out *AwsPluginSpec) { *out = *in if in.Auth != nil { in, out := &in.Auth, &out.Auth *out = new(Auth) (*in).DeepCopyInto(*out) } if in.Roles != nil { in, out := &in.Roles, &out.Roles *out = make([]string, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AwsPluginSpec. func (in *AwsPluginSpec) DeepCopy() *AwsPluginSpec { if in == nil { return nil } out := new(AwsPluginSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = *in if in.Password != nil { in, out := &in.Password, &out.Password *out = new(v1beta1.SecretRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. func (in *BasicAuth) DeepCopy() *BasicAuth { if in == nil { return nil } out := new(BasicAuth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Coginito) DeepCopyInto(out *Coginito) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Coginito. func (in *Coginito) DeepCopy() *Coginito { if in == nil { return nil } out := new(Coginito) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfAwsPlugin) DeepCopyInto(out *KfAwsPlugin) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfAwsPlugin. func (in *KfAwsPlugin) DeepCopy() *KfAwsPlugin { if in == nil { return nil } out := new(KfAwsPlugin) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfAwsPlugin) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OIDC) DeepCopyInto(out *OIDC) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDC. func (in *OIDC) DeepCopy() *OIDC { if in == nil { return nil } out := new(OIDC) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/apis/apps/plugins/gcp/gcp.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 gcp ================================================ FILE: pkg/apis/apps/plugins/gcp/v1alpha1/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 v1beta1 contains API Schema definitions for the kfdef v1beta1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef // +k8s:defaulter-gen=TypeMeta // +groupName=kfdef.apps.kubeflow.org package v1alpha1 ================================================ FILE: pkg/apis/apps/plugins/gcp/v1alpha1/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the KfGcpPlugin v1alpha1. // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp // +k8s:defaulter-gen=TypeMeta // +groupName=gcp.plugins.kubeflow.org package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "gcp.plugins.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfGcpPlugin{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/apis/apps/plugins/gcp/v1alpha1/types.go ================================================ package v1alpha1 import ( "fmt" kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:openapi-gen=true // Placeholder for the plugin API. type KfGcpPlugin struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec GcpPluginSpec `json:"spec,omitempty"` } // GcpPlugin defines the extra data provided by the GCP Plugin in KfDef type GcpPluginSpec struct { Auth *Auth `json:"auth,omitempty"` // SAClientId if supplied grant this service account cluster admin access // TODO(jlewi): Might want to make it a list SAClientId string `json:"username,omitempty"` // CreatePipelinePersistentStorage indicates whether to create storage. // Use a pointer so we can distinguish unset values. CreatePipelinePersistentStorage *bool `json:"createPipelinePersistentStorage,omitempty"` // EnableWorkloadIdentity indicates whether to enable workload identity. // Use a pointer so we can distinguish unset values. EnableWorkloadIdentity *bool `json:"enableWorkloadIdentity,omitempty"` // DeploymentManagerConfig provides location of the deployment manager configs. DeploymentManagerConfig *DeploymentManagerConfig `json:"deploymentManagerConfig,omitempty"` Project string `json:"project,omitempty"` Email string `json:"email,omitempty"` IpName string `json:"ipName,omitempty"` Hostname string `json:"hostname,omitempty"` Zone string `json:"zone,omitempty"` UseBasicAuth bool `json:"useBasicAuth"` SkipInitProject bool `json:"skipInitProject,omitempty"` DeleteStorage bool `json:"deleteStorage,omitempty"` } type Auth struct { BasicAuth *BasicAuth `json:"basicAuth,omitempty"` IAP *IAP `json:"iap,omitempty"` } type BasicAuth struct { Username string `json:"username,omitempty"` Password *kfdeftypes.SecretRef `json:"password,omitempty"` } type IAP struct { OAuthClientId string `json:"oAuthClientId,omitempty"` OAuthClientSecret *kfdeftypes.SecretRef `json:"oAuthClientSecret,omitempty"` } type DeploymentManagerConfig struct { RepoRef *kfdeftypes.RepoRef `json:"repoRef,omitempty"` } // IsValid returns true if the spec is a valid and complete spec. // If false it will also return a string providing a message about why its invalid. func (s *GcpPluginSpec) IsValid() (bool, string) { if len(s.Hostname) > 63 { return false, fmt.Sprintf("Invaid host name: host name %s is longer than 63 characters. Please shorten the metadata.name.", s.Hostname) } basicAuthSet := s.Auth.BasicAuth != nil iapAuthSet := s.Auth.IAP != nil if basicAuthSet == iapAuthSet { return false, "Exactly one of BasicAuth and IAP must be set; the other should be nil" } if basicAuthSet { msg := "" isValid := true if s.Auth.BasicAuth.Username == "" { isValid = false msg += "BasicAuth requires username. " } if s.Auth.BasicAuth.Password == nil { isValid = false msg += "BasicAuth requires password. " } return isValid, msg } if iapAuthSet { msg := "" isValid := true if s.Auth.IAP.OAuthClientId == "" { isValid = false msg += "IAP requires OAuthClientId. " } if s.Auth.IAP.OAuthClientSecret == nil { isValid = false msg += "IAP requires OAuthClientSecret. " } return isValid, msg } return false, "Either BasicAuth or IAP must be set" } func (p *GcpPluginSpec) GetCreatePipelinePersistentStorage() bool { if p.CreatePipelinePersistentStorage == nil { return true } v := p.CreatePipelinePersistentStorage return *v } func (p *GcpPluginSpec) GetEnableWorkloadIdentity() bool { if p.EnableWorkloadIdentity == nil { return true } v := p.EnableWorkloadIdentity return *v } ================================================ FILE: pkg/apis/apps/plugins/gcp/v1alpha1/types_test.go ================================================ package v1alpha1 import ( kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" kfutils "github.com/kubeflow/kfctl/v3/pkg/utils" "testing" ) func TestGcpPluginSpec_IsValid(t *testing.T) { type testCase struct { input *GcpPluginSpec expected bool } cases := []testCase{ { // Neither IAP or BasicAuth is set input: &GcpPluginSpec{ Auth: &Auth{}, }, expected: false, }, { // Both IAP and BasicAuth set input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Username: "jlewi", Password: &kfdeftypes.SecretRef{ Name: "somesecret", }, }, IAP: &IAP{ OAuthClientId: "jlewi", OAuthClientSecret: &kfdeftypes.SecretRef{ Name: "somesecret", }, }, }, }, expected: false, }, // Validate basic auth. { input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Username: "jlewi", Password: &kfdeftypes.SecretRef{ Name: "somesecret", }, }, }, }, expected: true, }, { input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Username: "jlewi", }, }, }, expected: false, }, { input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Password: &kfdeftypes.SecretRef{ Name: "somesecret", }, }, }, }, expected: false, }, // End Validate basic auth. // End Validate IAP. { input: &GcpPluginSpec{ Auth: &Auth{ IAP: &IAP{ OAuthClientId: "jlewi", OAuthClientSecret: &kfdeftypes.SecretRef{ Name: "somesecret", }, }, }, }, expected: true, }, { input: &GcpPluginSpec{ Auth: &Auth{ IAP: &IAP{ OAuthClientId: "jlewi", }, }, }, expected: false, }, { input: &GcpPluginSpec{ Auth: &Auth{ IAP: &IAP{ OAuthClientSecret: &kfdeftypes.SecretRef{ Name: "somesecret", }, }, }, }, expected: false, }, { input: &GcpPluginSpec{ Hostname: "this-kfApp-name-is-very-long.endpoints.my-gcp-project-for-kubeflow.cloud.goog", }, expected: false, }, } for _, c := range cases { isValid, _ := c.input.IsValid() // Test they are equal if isValid != c.expected { pSpec := kfutils.PrettyPrint(c.input) t.Errorf("Spec %v;\n IsValid Got:%v %v", pSpec, isValid, c.expected) } } } ================================================ FILE: pkg/apis/apps/plugins/gcp/v1alpha1/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 v1alpha1 import ( v1beta1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Auth) DeepCopyInto(out *Auth) { *out = *in if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(BasicAuth) (*in).DeepCopyInto(*out) } if in.IAP != nil { in, out := &in.IAP, &out.IAP *out = new(IAP) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth. func (in *Auth) DeepCopy() *Auth { if in == nil { return nil } out := new(Auth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = *in if in.Password != nil { in, out := &in.Password, &out.Password *out = new(v1beta1.SecretRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. func (in *BasicAuth) DeepCopy() *BasicAuth { if in == nil { return nil } out := new(BasicAuth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentManagerConfig) DeepCopyInto(out *DeploymentManagerConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(v1beta1.RepoRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentManagerConfig. func (in *DeploymentManagerConfig) DeepCopy() *DeploymentManagerConfig { if in == nil { return nil } out := new(DeploymentManagerConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GcpPluginSpec) DeepCopyInto(out *GcpPluginSpec) { *out = *in if in.Auth != nil { in, out := &in.Auth, &out.Auth *out = new(Auth) (*in).DeepCopyInto(*out) } if in.CreatePipelinePersistentStorage != nil { in, out := &in.CreatePipelinePersistentStorage, &out.CreatePipelinePersistentStorage *out = new(bool) **out = **in } if in.EnableWorkloadIdentity != nil { in, out := &in.EnableWorkloadIdentity, &out.EnableWorkloadIdentity *out = new(bool) **out = **in } if in.DeploymentManagerConfig != nil { in, out := &in.DeploymentManagerConfig, &out.DeploymentManagerConfig *out = new(DeploymentManagerConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GcpPluginSpec. func (in *GcpPluginSpec) DeepCopy() *GcpPluginSpec { if in == nil { return nil } out := new(GcpPluginSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IAP) DeepCopyInto(out *IAP) { *out = *in if in.OAuthClientSecret != nil { in, out := &in.OAuthClientSecret, &out.OAuthClientSecret *out = new(v1beta1.SecretRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAP. func (in *IAP) DeepCopy() *IAP { if in == nil { return nil } out := new(IAP) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfGcpPlugin) DeepCopyInto(out *KfGcpPlugin) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfGcpPlugin. func (in *KfGcpPlugin) DeepCopy() *KfGcpPlugin { if in == nil { return nil } out := new(KfGcpPlugin) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfGcpPlugin) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } ================================================ FILE: pkg/apis/apps/plugins/plugins.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 plugins ================================================ FILE: pkg/apis/kferrors.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 apis import ( "fmt" log "github.com/sirupsen/logrus" ) type StatusCode int const ( OK StatusCode = 200 INVALID_ARGUMENT StatusCode = 400 NOT_FOUND StatusCode = 404 INTERNAL_ERROR StatusCode = 500 UNKNOWN StatusCode = 520 ) // KfError stands for Kubeflow error. This is the standard error interface // for Kubeflow components. type KfError struct { // Code is the HTTP response status code. Code int `json:"code"` Message string `json:"message,omitempty"` } func (e *KfError) Error() string { return fmt.Sprintf(" (kubeflow.error): Code %d with message: %v", e.Code, e.Message) } func IsNotFound(e error) bool { kfError, ok := e.(*KfError) return ok && kfError.Code == int(NOT_FOUND) } // NewKfErrorWithMessage will propogate the error with the given message. // // TODO(jlewi): Not sure this is the best way to propogate the error messages and turn them // into KfErrors. There was a lot of code that was doing this but not asserting that the error // was a KfError which was causing segmentation faults so I wrote this helper method. func NewKfErrorWithMessage(e error, msg string) error { kErr, ok := e.(*KfError) if !ok { log.Infof("Error is not a KfError; %v", e) return &KfError{ Code: int(UNKNOWN), Message: msg + "; " + e.Error(), } } return &KfError{ Code: kErr.Code, Message: msg + "; " + kErr.Message, } } ================================================ FILE: pkg/controller/controller.go ================================================ package controller import ( "sigs.k8s.io/controller-runtime/pkg/manager" "github.com/kubeflow/kfctl/v3/pkg/controller/kfdef" ) // AddToManager adds all Controllers to the Manager func AddToManager(m manager.Manager) error { return kfdef.AddToManager(m) } ================================================ FILE: pkg/controller/kfdef/const.go ================================================ package kfdef import ( "k8s.io/apimachinery/pkg/runtime/schema" ) const ( // KubeflowLabel represents Label for kfctl deployed resource KubeflowLabel = "app.kubernetes.io/managed-by" ) var ( // watchedResources contains all resources we will watch and reconcile when changed watchedResources = []schema.GroupVersionKind{ {Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole"}, {Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRoleBinding"}, {Group: "", Version: "v1", Kind: "ConfigMap"}, {Group: "apiextensions.k8s.io", Version: "v1beta1", Kind: "CustomResourceDefinition"}, {Group: "apps", Version: "v1", Kind: "DaemonSet"}, {Group: "apps", Version: "v1", Kind: "Deployment"}, {Group: "extensions", Version: "v1beta1", Kind: "Deployment"}, {Group: "extensions", Version: "v1beta1", Kind: "Ingress"}, {Group: "admissionregistration.k8s.io", Version: "v1beta1", Kind: "MutatingWebhookConfiguration"}, {Group: "", Version: "v1", Kind: "Namespace"}, {Group: "", Version: "v1", Kind: "PersistentVolumeClaim"}, {Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "Role"}, {Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "Role"}, {Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "RoleBinding"}, {Group: "rbac.authorization.k8s.io", Version: "v1beta1", Kind: "RoleBinding"}, {Group: "", Version: "v1", Kind: "Secret"}, {Group: "", Version: "v1", Kind: "Service"}, {Group: "", Version: "v1", Kind: "ServiceAccount"}, {Group: "apps", Version: "v1", Kind: "StatefulSet"}, {Group: "admissionregistration.k8s.io", Version: "v1beta1", Kind: "ValidatingWebhookConfiguration"}, } watchedKubeflowResources = []schema.GroupVersionKind{ {Group: "app.k8s.io", Version: "v1beta1", Kind: "Application"}, {Group: "rbac.istio.io", Version: "v1alpha1", Kind: "ServiceRole"}, {Group: "rbac.istio.io", Version: "v1alpha1", Kind: "ServiceRoleBinding"}, {Group: "networking.istio.io", Version: "v1alpha3", Kind: "VirtualService"}, {Group: "argoproj.io", Version: "v1alpha1", Kind: "Workflow"}, {Group: "tekton.dev", Version: "v1alpha1", Kind: "Condition"}, } ) ================================================ FILE: pkg/controller/kfdef/kfdef_controller.go ================================================ package kfdef import ( "context" "io/ioutil" "os" "path" "strings" "github.com/ghodss/yaml" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfdefv1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1" "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" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" ) const ( finalizer = "kfdef-finalizer.kfdef.apps.kubeflow.org" // finalizerMaxRetries defines the maximum number of attempts to add finalizers. finalizerMaxRetries = 10 ) // kfdefInstances keep all KfDef CRs watched by the operator var kfdefInstances = map[string]struct{}{} // whether the 2nd controller is added var b2ndController = false // the manager var kfdefManager manager.Manager // the stop channel for the 2nd controller var stop chan struct{} // AddToManager adds all Controllers to the Manager func AddToManager(m manager.Manager) error { kfdefManager = m return Add(kfdefManager) } // Add creates a new KfDef Controller and adds it to the Manager. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(mgr manager.Manager) error { return add(mgr, newReconciler(mgr)) } // newReconciler returns a new reconcile.Reconciler func newReconciler(mgr manager.Manager) reconcile.Reconciler { return &ReconcileKfDef{client: mgr.GetClient(), scheme: mgr.GetScheme()} } // add adds a new Controller to mgr with r as the reconcile.Reconciler func add(mgr manager.Manager, r reconcile.Reconciler) error { log.Infof("Adding controller for kfdef.") // Create a new controller c, err := controller.New("kfdef-controller", mgr, controller.Options{Reconciler: r}) if err != nil { return err } // Watch for changes to primary resource KfDef err = c.Watch(&source.Kind{Type: &kfdefv1.KfDef{}}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request { namespacedName := types.NamespacedName{Name: a.Meta.GetName(), Namespace: a.Meta.GetNamespace()} finalizers := sets.NewString(a.Meta.GetFinalizers()...) if !finalizers.Has(finalizer) { // assume this is a CREATE event log.Infof("Adding finalizer %v: %v.", finalizer, namespacedName) finalizers.Insert(finalizer) instance := &kfdefv1.KfDef{} err = mgr.GetClient().Get(context.TODO(), namespacedName, instance) if err != nil { log.Errorf("Failed to get kfdef CR. Error: %v.", err) return nil } instance.SetFinalizers(finalizers.List()) err = mgr.GetClient().Update(context.TODO(), instance) if err != nil { log.Errorf("Failed to update kfdef with finalizer. Error: %v.", err) } // let the UPDATE event request queue return nil } log.Infof("Watch a change for KfDef CR: %v.%v.", a.Meta.GetName(), a.Meta.GetNamespace()) return []reconcile.Request{{NamespacedName: namespacedName}} }), }, kfdefPredicates) if err != nil { return err } // Watch for changes to kfdef resource and requeue the owner KfDef err = watchKubeflowResources(c, mgr.GetClient(), watchedResources) if err != nil { return err } log.Infof("Controller added to watch on Kubeflow resources with known GVK.") return nil } // watch is monitoring changes for kfctl resources managed by the operator func watchKubeflowResources(c controller.Controller, r client.Client, watchedResources []schema.GroupVersionKind) error { for _, t := range watchedResources { u := &unstructured.Unstructured{} u.SetGroupVersionKind(schema.GroupVersionKind{ Kind: t.Kind, Group: t.Group, Version: t.Version, }) err := c.Watch(&source.Kind{Type: u}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request { anns := a.Meta.GetAnnotations() kfdefAnn := strings.Join([]string{kfutils.KfDefAnnotation, kfutils.KfDefInstance}, "/") _, found := anns[kfdefAnn] if found { kfdefCr := strings.Split(anns[kfdefAnn], ".") namespacedName := types.NamespacedName{Name: kfdefCr[0], Namespace: kfdefCr[1]} instance := &kfdefv1.KfDef{} err := r.Get(context.TODO(), types.NamespacedName{Name: kfdefCr[0], Namespace: kfdefCr[1]}, instance) if err != nil { if errors.IsNotFound(err) { // KfDef CR may have been deleted return nil } } else if instance.GetDeletionTimestamp() != nil { // KfDef is being deleted return nil } log.Infof("Watch a change for Kubeflow resource: %v.%v.", a.Meta.GetName(), a.Meta.GetNamespace()) return []reconcile.Request{{NamespacedName: namespacedName}} } return nil }), }, ownedResourcePredicates) if err != nil { log.Errorf("Cannot create watch for resources %v %v/%v: %v.", t.Kind, t.Group, t.Version, err) } } return nil } var kfdefPredicates = predicate.Funcs{ CreateFunc: func(e event.CreateEvent) bool { object, _ := meta.Accessor(e.Object) log.Infof("Got create event for %v.%v.", object.GetName(), object.GetNamespace()) return true }, GenericFunc: func(e event.GenericEvent) bool { object, _ := meta.Accessor(e.Object) log.Infof("Got generic event for %v.%v.", object.GetName(), object.GetNamespace()) return true }, DeleteFunc: func(e event.DeleteEvent) bool { object, _ := meta.Accessor(e.Object) log.Infof("Got delete event for %v.%v.", object.GetName(), object.GetNamespace()) return false }, UpdateFunc: func(e event.UpdateEvent) bool { object, _ := meta.Accessor(e.ObjectOld) log.Infof("Got update event for %v.%v.", object.GetName(), object.GetNamespace()) upd, _ := meta.Accessor(e.ObjectNew) // these cases will result in a reconcile request // 1. the finalizer is added 2. the deletiontimestamp is added 3. generation is increased if len(object.GetFinalizers()) == 0 && len(upd.GetFinalizers()) > 0 { return true } if object.GetDeletionTimestamp() == nil && upd.GetDeletionTimestamp() != nil { return true } if upd.GetGeneration() > object.GetGeneration() { return true } return false }, } var ownedResourcePredicates = predicate.Funcs{ CreateFunc: func(_ event.CreateEvent) bool { // no action return false }, GenericFunc: func(_ event.GenericEvent) bool { // no action return false }, DeleteFunc: func(e event.DeleteEvent) bool { // handle deletion event object, err := meta.Accessor(e.Object) if err != nil { return false } log.Infof("Got delete event for %v.%v.", object.GetName(), object.GetNamespace()) // if this object has an owner, let the owner handle the appropriate recovery if len(object.GetOwnerReferences()) > 0 { return false } return true }, UpdateFunc: func(e event.UpdateEvent) bool { // no action return false }, } // blank assignment to verify that ReconcileKfDef implements reconcile.Reconciler var _ reconcile.Reconciler = &ReconcileKfDef{} // ReconcileKfDef reconciles a KfDef object type ReconcileKfDef struct { // This client, initialized using mgr.Client() above, is a split client // that reads objects from the cache and writes to the apiserver client client.Client scheme *runtime.Scheme } // Reconcile reads that state of the cluster for a KfDef object and makes changes based on the state read // and what is in the KfDef.Spec // Note: // The Controller will requeue the Request to be processed again if the returned error is non-nil or // Result.Requeue is true, otherwise upon completion it will remove the work from the queue. func (r *ReconcileKfDef) Reconcile(request reconcile.Request) (reconcile.Result, error) { log.Infof("Reconciling KfDef resources. Request.Namespace: %v, Request.Name: %v.", request.Namespace, request.Name) instance := &kfdefv1.KfDef{} err := r.client.Get(context.TODO(), request.NamespacedName, instance) if err != nil { if errors.IsNotFound(err) { // Request object not found, could have been deleted after reconcile request. // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. // Return and don't requeue return reconcile.Result{}, nil } // Error reading the object - requeue the request. return reconcile.Result{}, err } deleted := instance.GetDeletionTimestamp() != nil finalizers := sets.NewString(instance.GetFinalizers()...) if deleted { if !finalizers.Has(finalizer) { log.Info("Kfdef deleted.") return reconcile.Result{}, nil } log.Infof("Deleting kfdef.") // stop the 2nd controller if len(kfdefInstances) == 1 { close(stop) b2ndController = false } // Uninstall Kubeflow err = kfDelete(instance) if err == nil { log.Infof("KubeFlow Deployment Deleted.") } else { // log an error and continue for cleanup. It does not make sense to retry the delete. log.Errorf("Failed to delete Kubeflow.") } // Delete the kfapp directory kfAppDir := path.Join("/tmp", instance.GetNamespace(), instance.GetName()) if err := os.RemoveAll(kfAppDir); err != nil { log.Errorf("Failed to delete the app directory. Error: %v.", err) return reconcile.Result{}, err } log.Infof("kfAppDir deleted.") // Remove this KfDef instance delete(kfdefInstances, strings.Join([]string{instance.GetName(), instance.GetNamespace()}, ".")) // Remove finalizer once kfDelete is completed. finalizers.Delete(finalizer) instance.SetFinalizers(finalizers.List()) finalizerError := r.client.Update(context.TODO(), instance) for retryCount := 0; errors.IsConflict(finalizerError) && retryCount < finalizerMaxRetries; retryCount++ { // Based on Istio operator at https://github.com/istio/istio/blob/master/operator/pkg/controller/istiocontrolplane/istiocontrolplane_controller.go // for finalizer removal errors workaround. log.Info("Conflict during finalizer removal, retrying.") _ = r.client.Get(context.TODO(), request.NamespacedName, instance) finalizers = sets.NewString(instance.GetFinalizers()...) finalizers.Delete(finalizer) instance.SetFinalizers(finalizers.List()) finalizerError = r.client.Update(context.TODO(), instance) } if finalizerError != nil { log.Errorf("Error removing finalizer: %v.", finalizerError) return reconcile.Result{}, finalizerError } return reconcile.Result{}, nil } else if !finalizers.Has(finalizer) { log.Infof("Normally this should not happen. Adding finalizer %v: %v.", finalizer, request) finalizers.Insert(finalizer) instance.SetFinalizers(finalizers.List()) err = r.client.Update(context.TODO(), instance) if err != nil { log.Errorf("Failed to update kfdef with finalizer. Error: %v.", err) return reconcile.Result{}, err } } // If this is a kfdef change, for now, remove the kfapp config path if request.Name == instance.GetName() && request.Namespace == instance.GetNamespace() { kfAppDir := path.Join("/tmp", instance.GetNamespace(), instance.GetName()) if err = os.RemoveAll(kfAppDir); err != nil { log.Errorf("Failed to delete the app directory. Error: %v.", err) return reconcile.Result{}, err } } err = kfApply(instance) if err == nil { log.Infof("KubeFlow Deployment Completed.") // add to kfdefInstances if not exists if _, ok := kfdefInstances[strings.Join([]string{instance.GetName(), instance.GetNamespace()}, ".")]; !ok { kfdefInstances[strings.Join([]string{instance.GetName(), instance.GetNamespace()}, ".")] = struct{}{} } if b2ndController == false { c, err := controller.New("kubeflow-controller", kfdefManager, controller.Options{Reconciler: r}) if err != nil { return reconcile.Result{}, nil } // Watch for changes to kfdef resource and requeue the owner KfDef err = watchKubeflowResources(c, kfdefManager.GetClient(), watchedKubeflowResources) if err != nil { return reconcile.Result{}, nil } stop = make(chan struct{}) go func() { // Start the controller if err := c.Start(stop); err != nil { log.Error(err, "cannot run the 2nd Kubeflow controller") } }() log.Infof("Controller added to watch resources from CRDs created by Kubeflow deployment.") b2ndController = true } } // If deployment created successfully - don't requeue return reconcile.Result{}, err } // kfApply is equivalent of kfctl apply func kfApply(instance *kfdefv1.KfDef) error { log.Infof("Creating a new KubeFlow Deployment. KubeFlow.Namespace: %v.", instance.Namespace) kfApp, err := kfLoadConfig(instance, "apply") if err != nil { log.Errorf("Failed to load KfApp. Error: %v.", err) return err } // Apply kfApp. err = kfApp.Apply(kftypesv3.K8S) return err } // kfDelete is equivalent of kfctl delete func kfDelete(instance *kfdefv1.KfDef) error { log.Infof("Uninstall Kubeflow. KubeFlow.Namespace: %v.", instance.Namespace) kfApp, err := kfLoadConfig(instance, "delete") if err != nil { log.Errorf("Failed to load KfApp. Error: %v.", err) return err } // Delete kfApp. err = kfApp.Delete(kftypesv3.K8S) return err } func kfLoadConfig(instance *kfdefv1.KfDef, action string) (kftypesv3.KfApp, error) { // Define kfApp kfdefBytes, _ := yaml.Marshal(instance) // Make the kfApp directory kfAppDir := path.Join("/tmp", instance.GetNamespace(), instance.GetName()) if err := os.MkdirAll(kfAppDir, 0755); err != nil { log.Errorf("Failed to create the app directory. Error: %v.", err) return nil, err } configFilePath := path.Join(kfAppDir, "config.yaml") err := ioutil.WriteFile(configFilePath, kfdefBytes, 0644) if err != nil { log.Errorf("Failed to write config.yaml. Error: %v.", err) return nil, err } if action == "apply" { // Indicate to add annotation to the top level resources setAnnotationAnn := strings.Join([]string{kfutils.KfDefAnnotation, kfutils.SetAnnotation}, "/") setAnnotations(configFilePath, map[string]string{ setAnnotationAnn: "true", }) } if action == "delete" { // Enable force delete since inClusterConfig has no ./kube/config file to pass the delete safety check. forceDeleteAnn := strings.Join([]string{kfutils.KfDefAnnotation, kfutils.ForceDelete}, "/") setAnnotations(configFilePath, map[string]string{ forceDeleteAnn: "true", }) // Indicate the Kubeflow is installed by the operator byOperatorAnn := strings.Join([]string{kfutils.KfDefAnnotation, kfutils.InstallByOperator}, "/") setAnnotations(configFilePath, map[string]string{ byOperatorAnn: "true", }) } kfApp, err := coordinator.NewLoadKfAppFromURI(configFilePath) if err != nil { log.Errorf("failed to build kfApp from URI %v: Error: %v.", configFilePath, err) return nil, err } return kfApp, nil } 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: pkg/kfapp/aws/OWNERS ================================================ approvers: - jeffwan - PatrickXYS ================================================ FILE: pkg/kfapp/aws/aws.go ================================================ /* 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. */ package aws import ( "encoding/base64" "fmt" "io" "io/ioutil" "math/rand" "os" "path" "path/filepath" "strconv" "strings" "time" "github.com/gogo/protobuf/proto" "golang.org/x/crypto/bcrypt" awssdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/eks" "github.com/aws/aws-sdk-go/service/iam" "github.com/ghodss/yaml" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/kfconfig/awsplugin" "github.com/kubeflow/kfctl/v3/pkg/utils" "github.com/pkg/errors" log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" ) const ( KUBEFLOW_AWS_INFRA_DIR = "aws_config" KUBEFLOW_MANIFEST_DIR = "kustomize" CLUSTER_CONFIG_FILE = "cluster_config.yaml" PATH = "path" BASIC_AUTH_SECRET = "kubeflow-login" // Path in manifests repo to where the additional configs are located CONFIG_LOCAL_PATH = "aws/infra_configs" ALB_OIDC_SECRET = "alb-oidc-secret" // Namespace for istio IstioNamespace = "istio-system" // Plugin parameter constants AwsPluginName = kfconfig.AWS_PLUGIN_KIND MINIMUM_EKSCTL_VERSION = "0.1.32" KUBEFLOW_ADMIN_ROLE_NAME = "kf-admin-%v-%v" KUBEFLOW_USER_ROLE_NAME = "kf-user-%v-%v" ) // Aws implements KfApp Interface // It includes the KsApp along with additional Aws types type Aws struct { kfDef *kfconfig.KfConfig iamClient *iam.IAM eksClient *eks.EKS sess *session.Session k8sClient *clientset.Clientset cluster *Cluster region string roles []string istioManifests []manifest ingressManifests []manifest certManagerManifests []manifest } type manifest struct { name string path string } // GetKfApp returns the aws kfapp. It's called by coordinator.GetKfApp func GetPlatform(kfdef *kfconfig.KfConfig) (kftypes.Platform, error) { // Manifest lists are used in `Delete` to make sure we track and clean up all the resources. istioManifests := []manifest{ { name: "Istio CRDs", path: path.Join(KUBEFLOW_MANIFEST_DIR, "istio-crds", "base", "crds.yaml"), }, { name: "Istio Control Plane", path: path.Join(KUBEFLOW_MANIFEST_DIR, "istio-install", "base", "istio-noauth.yaml"), }, } ingressManifests := []manifest{ { name: "ALB Ingress", path: path.Join(KUBEFLOW_MANIFEST_DIR, "istio-ingress", "base", "ingress.yaml"), }, } certManagerManifests := []manifest{ { name: "Cert Manager", path: path.Join(KUBEFLOW_MANIFEST_DIR, "cert-manager-crds", "base", "crd.yaml"), }, { name: "Cert Manager API Service", path: path.Join(KUBEFLOW_MANIFEST_DIR, "cert-manager", "base", "api-service.yaml"), }, { name: "Cert Manager MutationWebhookConfig", path: path.Join(KUBEFLOW_MANIFEST_DIR, "cert-manager", "base", "mutating-webhook-configuration.yaml"), }, { name: "Cert Manager ValidatingWebhookConfiguration", path: path.Join(KUBEFLOW_MANIFEST_DIR, "cert-manager", "base", "validating-webhook-configuration.yaml"), }, } // set aws.sess with shared config file information, such as region session := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, })) k8sClient, err := getK8sclient() if err != nil { return nil, err } _aws := &Aws{ kfDef: kfdef, sess: session, iamClient: iam.New(session), eksClient: eks.New(session), k8sClient: k8sClient, istioManifests: istioManifests, ingressManifests: ingressManifests, certManagerManifests: certManagerManifests, } return _aws, nil } // GetPluginSpec gets the plugin spec. func (aws *Aws) GetPluginSpec() (*awsplugin.AwsPluginSpec, error) { awsPluginSpec := &awsplugin.AwsPluginSpec{} err := aws.kfDef.GetPluginSpec(AwsPluginName, awsPluginSpec) return awsPluginSpec, err } func (aws *Aws) attachPoliciesToRoles(roles []string) error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return err } for _, iamRole := range roles { aws.attachIamInlinePolicy(iamRole, "iam_alb_ingress_policy", filepath.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR, "iam_alb_ingress_policy.json")) aws.attachIamInlinePolicy(iamRole, "iam_profile_controller_policy", filepath.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR, "iam_profile_controller_policy.json")) //aws.attachIamInlinePolicy(iamRole, "iam_csi_fsx_policy", // filepath.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR, "iam_csi_fsx_policy.json")) if awsPluginSpec.GetEnableNodeGroupLog() { aws.attachIamInlinePolicy(iamRole, "iam_cloudwatch_policy", filepath.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR, "iam_cloudwatch_policy.json")) } } return nil } // TODO: To be implemented. Consider to have EKS cluster config support. func (aws *Aws) updateEKSClusterConfig() error { return nil } func (aws *Aws) getWorkerNodeGroupRoles(clusterName string) ([]string, error) { // List all the roles and figure out nodeGroupWorkerRole input := &iam.ListRolesInput{} listRolesOutput, err := aws.iamClient.ListRoles(input) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Call not list roles with errors: %v", err), } } var nodeGroupIamRoles []string for _, output := range listRolesOutput.Roles { if strings.HasPrefix(*output.RoleName, "eksctl-"+clusterName+"-") && strings.Contains(*output.RoleName, "NodeInstanceRole") { nodeGroupIamRoles = append(nodeGroupIamRoles, *output.RoleName) } } return nodeGroupIamRoles, nil } func copyFile(source string, dest string) error { from, err := os.Open(source) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot open input file for copying: %v", err), } } defer from.Close() to, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE, 0666) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot create dest file %v : %v", dest, err), } } defer to.Close() _, err = io.Copy(to, from) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("copy failed source %v dest %v: %v", source, dest, err), } } return nil } // updateClusterConfig replaces placeholders in cluster_config.yaml func (aws *Aws) updateClusterConfig(clusterConfigFile string) error { buf, err := ioutil.ReadFile(clusterConfigFile) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when reading template %v: %v", clusterConfigFile, err), } } var data map[string]interface{} if err = yaml.Unmarshal(buf, &data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when unmarshaling template %v: %v", clusterConfigFile, err), } } res, ok := data["metadata"] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Invalid cluster config - not able to find metadata entry.", } } // Replace placeholder with clusterName and Region metadata := res.(map[string]interface{}) metadata["name"] = aws.kfDef.Name metadata["region"] = aws.region data["metadata"] = metadata if buf, err = yaml.Marshal(data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when marshaling for %v: %v", clusterConfigFile, err), } } if err = ioutil.WriteFile(clusterConfigFile, buf, 0644); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when writing to %v: %v", clusterConfigFile, err), } } return nil } // ${BASE_DIR}/${KFAPP}/aws_config -> destDir (dest) func (aws *Aws) generateInfraConfigs() error { // 1. Copy and Paste all files from `sourceDir` to `destDir` repo, ok := aws.kfDef.GetRepoCache(kftypes.ManifestsRepoName) if !ok { err := fmt.Errorf("Repo %v not found in KfDef.Status.ReposCache", kftypes.ManifestsRepoName) log.Errorf("%v", err) return errors.WithStack(err) } sourceDir := path.Join(repo.LocalPath, CONFIG_LOCAL_PATH) destDir := path.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR) if _, err := os.Stat(destDir); os.IsNotExist(err) { log.Infof("Creating AWS infrastructure configs in directory %v", destDir) destDirErr := os.MkdirAll(destDir, os.ModePerm) if destDirErr != nil { return destDirErr } } else { log.Infof("AWS infrastructure configs already exist in directory %v", destDir) } // List all the files under source directory files, err := ioutil.ReadDir(sourceDir) if err != nil { return err } for _, file := range files { sourceFile := filepath.Join(sourceDir, file.Name()) destFile := filepath.Join(destDir, file.Name()) copyErr := copyFile(sourceFile, destFile) if copyErr != nil { return &kfapis.KfError{ Code: copyErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("Could not copy %v to %v: %v", sourceFile, destFile, copyErr.(*kfapis.KfError).Message), } } } // 2. Reading from cluster_config.yaml and replace placeholders with values in aws.kfDef.Spec. clusterConfigFile := filepath.Join(destDir, CLUSTER_CONFIG_FILE) if err := aws.updateClusterConfig(clusterConfigFile); err != nil { return err } // 3. Update managed_cluster // @Deprecated. Don't need to update the field, we add configs part of awsPluginSpec. It's false by default return nil } func (aws *Aws) generateBasicAuthPasswordHash() (string, error) { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return "", err } if awsPluginSpec.Auth == nil || awsPluginSpec.Auth.BasicAuth == nil || awsPluginSpec.Auth.BasicAuth.Password == "" { err := errors.WithStack(fmt.Errorf("BasicAuth.Password must be set if enabled BasicAuth")) return "", err } encodedPassword, err := base64EncryptPassword(awsPluginSpec.Auth.BasicAuth.Password) if err != nil { log.Errorf("There was a problem encrypting the password; %v", err) return "", err } return encodedPassword, nil } func base64EncryptPassword(password string) (string, error) { passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), 10) if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when hashing password: %v", err), } } encodedPassword := base64.StdEncoding.EncodeToString(passwordHash) return encodedPassword, nil } // Init initializes aws kfapp - platform func (aws *Aws) Init(resources kftypes.ResourceEnum) error { // 1. Use AWS SDK to check if credentials from (~/.aws/credentials or ENV) and session verify commandsTocheck := []string{"aws", "aws-iam-authenticator", "eksctl"} for _, command := range commandsTocheck { if err := utils.CheckCommandExist(command); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not find command %v in PATH", command), } } } // 2. Check if current eksctl version meets minimum requirement version, err := utils.GetEksctlVersion() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Can not run eksctl version %v", err), } } if lessThan, err := isEksctlVersionLessThan(version, MINIMUM_EKSCTL_VERSION); err != nil || lessThan { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("eksctl version has to be great than %s %v", MINIMUM_EKSCTL_VERSION, err), } } return nil } // Generate generate aws infrastructure configs and aws kfapp manifest // Remind: Need to be thread-safe: this entry is share among kfctl and deploy app func (aws *Aws) Generate(resources kftypes.ResourceEnum) error { awsDir := path.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR) if _, err := os.Stat(awsDir); err == nil { log.Infof("Folder %v exists, skip aws.Generate", awsDir) return nil } else if !os.IsNotExist(err) { log.Errorf("Stat folder %v error: %v; trying to delete it...", awsDir, err) _ = os.RemoveAll(awsDir) } // Use aws sts get-caller-identity to verify aws credential setting if err := utils.CheckAwsStsCallerIdentity(aws.sess); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not authenticate aws client: %v, Please make sure you set up AWS credentials and regions", err), } } if setAwsPluginDefaultsErr := aws.setAwsPluginDefaults(); setAwsPluginDefaultsErr != nil { return &kfapis.KfError{ Code: setAwsPluginDefaultsErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("set aws plugin defaults: %v", setAwsPluginDefaultsErr.(*kfapis.KfError).Message), } } if awsConfigFilesErr := aws.generateInfraConfigs(); awsConfigFilesErr != nil { return &kfapis.KfError{ Code: awsConfigFilesErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("Could not generate cluster configs under %v Error: %v", KUBEFLOW_AWS_INFRA_DIR, awsConfigFilesErr.(*kfapis.KfError).Message), } } pluginSpec, err := aws.GetPluginSpec() if err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("aws-alb-ingress-controller", "cluster-name", aws.kfDef.Name); err != nil { return errors.WithStack(err) } if pluginSpec.Auth != nil && pluginSpec.Auth.BasicAuth != nil && pluginSpec.Auth.BasicAuth.Password != "" { if err := aws.kfDef.SetApplicationParameter("dex", "static_email", pluginSpec.Auth.BasicAuth.Username); err != nil { return errors.WithStack(err) } if encodedPasswordHash, err := aws.generateBasicAuthPasswordHash(); err == nil { if err := aws.kfDef.SetApplicationParameter("dex", "static_password_hash", encodedPasswordHash); err != nil { return errors.WithStack(err) } } else { return errors.WithStack(err) } } else { if pluginSpec.Auth.Cognito != nil { if err := aws.kfDef.SetApplicationParameter("istio-ingress", "CognitoUserPoolArn", pluginSpec.Auth.Cognito.CognitoUserPoolArn); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "CognitoUserPoolDomain", pluginSpec.Auth.Cognito.CognitoUserPoolDomain); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "CognitoAppClientId", pluginSpec.Auth.Cognito.CognitoAppClientId); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "certArn", pluginSpec.Auth.Cognito.CertArn); err != nil { return errors.WithStack(err) } } // By default we use cognito overlay in manifest, remove cognito and add oidc overlay if this is enabled. if pluginSpec.Auth.Oidc != nil { if err := aws.kfDef.SetApplicationParameter("istio", "clusterRbacConfig", "ON"); err != nil { return errors.WithStack(err) } if err := aws.kfDef.RemoveApplicationOverlay("istio-ingress", "cognito"); err != nil { return errors.WithStack(err) } if err := aws.kfDef.AddApplicationOverlay("istio-ingress", "oidc"); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "oidcIssuer", pluginSpec.Auth.Oidc.OidcIssuer); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "oidcAuthorizationEndpoint", pluginSpec.Auth.Oidc.OidcAuthorizationEndpoint); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "oidcTokenEndpoint", pluginSpec.Auth.Oidc.OidcTokenEndpoint); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "oidcUserInfoEndpoint", pluginSpec.Auth.Oidc.OidcUserInfoEndpoint); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("istio-ingress", "certArn", pluginSpec.Auth.Oidc.CertArn); err != nil { return errors.WithStack(err) } //TODO: consider to use secret from secretGenerator? if err := aws.kfDef.SetApplicationParameter("istio-ingress", "oidcSecretName", ALB_OIDC_SECRET); err != nil { return errors.WithStack(err) } } } // Special handling for cloud watch logs of worker node groups if pluginSpec.GetEnableNodeGroupLog() { //aws.kfDef.Spec.Components = append(aws.kfDef.Spec.Components, "fluentd-cloud-watch") if err := aws.kfDef.SetApplicationParameter("fluentd-cloud-watch", "clusterName", aws.kfDef.Name); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("fluentd-cloud-watch", "region", aws.region); err != nil { return errors.WithStack(err) } } // Special handling for managed SQL service if pluginSpec.ManagedRelationDatabase != nil { // Setup metadata -> remove `db` overlay, add `external-mysql` overlay if err := aws.kfDef.RemoveApplicationOverlay("metadata", "db"); err != nil { return errors.WithStack(err) } if err := aws.kfDef.AddApplicationOverlay("metadata", "external-mysql"); err != nil { return errors.WithStack(err) } // add external-mysql to pipeline/api-service and external-mysql to metadata, if err := aws.kfDef.SetApplicationParameter("metadata", "MYSQL_HOST", pluginSpec.ManagedRelationDatabase.Host); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("metadata", "MYSQL_USERNAME", string(pluginSpec.ManagedRelationDatabase.Username)); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("metadata", "MYSQL_ROOT_PASSWORD", string(pluginSpec.ManagedRelationDatabase.Password)); err != nil { return errors.WithStack(err) } if pluginSpec.ManagedRelationDatabase.Port != nil { if err := aws.kfDef.SetApplicationParameter("metadata", "MYSQL_PORT", fmt.Sprint(*pluginSpec.ManagedRelationDatabase.Port)); err != nil { return errors.WithStack(err) } } // Setup pipeline/api-service -> move mysql application, add external-mysql overlay to pipeline/api-service if err := aws.kfDef.DeleteApplication("mysql"); err != nil { return errors.WithStack(err) } if err := aws.kfDef.AddApplicationOverlay("api-service", "external-mysql"); err != nil { return errors.WithStack(err) } // add external-mysql to pipeline/api-service and external-mysql to metadata, if err := aws.kfDef.SetApplicationParameter("api-service", "mysqlHost", pluginSpec.ManagedRelationDatabase.Host); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("api-service", "mysqlUser", pluginSpec.ManagedRelationDatabase.Username); err != nil { return errors.WithStack(err) } if err := aws.kfDef.SetApplicationParameter("api-service", "mysqlPassword", pluginSpec.ManagedRelationDatabase.Password); err != nil { return errors.WithStack(err) } } // Special handling for managed object storage if pluginSpec.ManagedObjectStorage != nil { // TODO: replace worker-controller, pipeline, etc layer } // Special handling for sparkakus rand.Seed(time.Now().UnixNano()) if err := aws.kfDef.SetApplicationParameter("spartakus", "usageId", strconv.Itoa(rand.Int())); err != nil { if kfconfig.IsAppNotFound(err) { log.Infof("Spartakus not included; not setting usageId") } } return nil } func (aws *Aws) setAwsPluginDefaults() error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return err } if isValid, msg := awsPluginSpec.IsValid(); !isValid { log.Errorf("AwsPluginSpec isn't valid; error %v", msg) return fmt.Errorf(msg) } aws.region = awsPluginSpec.Region aws.roles = awsPluginSpec.Roles if awsPluginSpec.ManagedCluster == nil { awsPluginSpec.ManagedCluster = proto.Bool(awsPluginSpec.GetManagedCluster()) log.Infof("ManagedCluster set defaulting to %v", utils.PrettyPrint(*awsPluginSpec.ManagedCluster)) } if awsPluginSpec.EnablePodIamPolicy == nil { awsPluginSpec.EnablePodIamPolicy = proto.Bool(awsPluginSpec.GetEnablePodIamPolicy()) log.Infof("EnablePodIamPolicy set defaulting to %v", utils.PrettyPrint(*awsPluginSpec.EnablePodIamPolicy)) } if awsPluginSpec.EnableNodeGroupLog == nil { awsPluginSpec.EnableNodeGroupLog = proto.Bool(awsPluginSpec.GetEnableNodeGroupLog()) log.Infof("EnableNodeGroupLog set defaulting to %v", utils.PrettyPrint(*awsPluginSpec.EnableNodeGroupLog)) } if awsPluginSpec.Auth == nil { awsPluginSpec.Auth = &awsplugin.Auth{} } return nil } // Apply create eks cluster if needed, bind IAM policy to node group roles and enable cluster level configs. // Remind: Need to be thread-safe: this entry is share among kfctl and deploy app func (aws *Aws) Apply(resources kftypes.ResourceEnum) error { // use aws sts get-caller-identity to verify aws credential works. if err := utils.CheckAwsStsCallerIdentity(aws.sess); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not authenticate aws client: %v, Please make sure you set up AWS credentials and regions", err), } } if err := aws.setAwsPluginDefaults(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("aws set aws plugin defaults: %v", err.(*kfapis.KfError).Message), } } // 1. Create EKS cluster if needed if err := aws.createEKSCluster(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Failed to create EKS cluster %v", err.(*kfapis.KfError).Message), } } // 2. For non-eks cluster (kops) or user doesn't enable pod level IAM policy, // attach IAM policies like ALB, FSX, EFS, cloudWatch Fluentd to worker node group roles // For eks cluster enable pod IAM, we create identity provider and role. Override kubeflow components service account with annotation. awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not get awsPluginSpec %v", err), } } isEksCluster, err := aws.IsEksCluster(aws.kfDef.Name) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not determinte it's EKS cluster %v", err), } } if err := createNamespace(aws.k8sClient, aws.kfDef.Namespace); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Could not create namespace %v", err), } } if err := createNamespace(aws.k8sClient, IstioNamespace); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Could not create namespace %v", err), } } // Create IAM role binding for k8s service account. if awsPluginSpec.GetEnablePodIamPolicy() && isEksCluster { err := aws.setupIamRoleForServiceAccount() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not setup pod IAM policy %v", err), } } } else if awsPluginSpec.GetEnablePodIamPolicy() { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("IAM for Service Account is not supported on non-EKS cluster %v", err), } } // 3. Attach policies to worker node groups. This will be used by both EKS and non-EKS AWS Kubernetes clusters. if err := aws.attachPoliciesToRoles(aws.roles); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Failed to attach IAM policies %v", err.(*kfapis.KfError).Message), } } // 4. Update cluster configs to enable master log or private access config. if err := aws.updateEKSClusterConfig(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Failed to update eks cluster configs %v", err.(*kfapis.KfError).Message), } } // 5. Setup OIDC create OIDC secret for ALB if err := aws.setupOIDC(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Failed to update create OIDC secret for ALB %v", err.(*kfapis.KfError).Message), } } return nil } func (aws *Aws) Delete(resources kftypes.ResourceEnum) error { // use aws to call sts get-caller-identity to verify aws credential works. if err := utils.CheckAwsStsCallerIdentity(aws.sess); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not authenticate aws client: %v, Please make sure you set up AWS credentials and regions", err), } } setAwsPluginDefaultsErr := aws.setAwsPluginDefaults() if setAwsPluginDefaultsErr != nil { return &kfapis.KfError{ Code: setAwsPluginDefaultsErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("aws set aws plugin defaults: %v", setAwsPluginDefaultsErr.(*kfapis.KfError).Message), } } // 1. Delete ingress and istio, cert-manager dependencies if err := aws.uninstallK8sDependencies(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Could not uninstall eks cluster Error: %v", err.(*kfapis.KfError).Message), } } // 2. Detach inline policies from worker IAM Roles if err := aws.detachPoliciesFromWorkerRoles(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Could not detach iam role Error: %v", err.(*kfapis.KfError).Message), } } // 3. Delete WebIdentityIAMRole and OIDC Provider and pre-configured roles if err := aws.deleteWebIdentityRolesAndProvider(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Could not detach iam role Error: %v", err.(*kfapis.KfError).Message), } } // 4. Delete EKS cluster if err := aws.deleteEKSCluster(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Could not uninstall eks cluster Error: %v", err.(*kfapis.KfError).Message), } } return nil } func (aws *Aws) Dump(resources kftypes.ResourceEnum) error { return nil } // uninstallK8sDependencies delete istio-ingress, istio and cert-manager dependencies. func (aws *Aws) uninstallK8sDependencies() error { rev := func(manifests []manifest) []manifest { var r []manifest max := len(manifests) for i := 0; i < max; i++ { r = append(r, manifests[max-1-i]) } return r } // 1. Delete Ingress and wait for 15s for alb-ingress-controller to clean up resources if err := deleteManifests(rev(aws.ingressManifests)); err != nil { return errors.WithStack(err) } var albCleanUpInSeconds = 15 log.Infof("Wait for %d seconds for alb ingress controller to clean up ALB", albCleanUpInSeconds) time.Sleep(time.Duration(albCleanUpInSeconds) * time.Second) // 2. Delete cert-manager manifest. // Simplify process by deleting cert-manager namespace, don't have to delete every single manifest if err := deleteNamespace(aws.k8sClient, "cert-manager"); err != nil { return errors.WithStack(err) } if err := deleteManifests(rev(aws.certManagerManifests)); err != nil { return errors.WithStack(err) } // 3. Delete istio dependencies if err := deleteManifests(rev(aws.istioManifests)); err != nil { return errors.WithStack(err) } return nil } func deleteManifests(manifests []manifest) error { config := kftypes.GetConfig() for _, m := range manifests { log.Infof("Deleting %s...", m.name) if _, err := os.Stat(m.path); os.IsNotExist(err) { log.Warnf("File %s not found", m.path) continue } err := utils.DeleteResourceFromFile( config, m.path, ) if err != nil { log.Errorf("Failed to delete %s: %+v", m.name, err) return err } } return nil } func (aws *Aws) detachPoliciesFromWorkerRoles() error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return errors.WithStack(err) } var roles []string eksCluster, err := aws.getEksCluster(aws.kfDef.Name) if err != nil { return err } if awsPluginSpec.GetEnablePodIamPolicy() { // no matter it's managed or self-managed cluster, we setup kf-admin roles. roles = append(roles, fmt.Sprintf(KUBEFLOW_ADMIN_ROLE_NAME, aws.region, eksCluster.name)) } else { // Find worker roles based on new cluster kfctl created or existing cluster if awsPluginSpec.GetManagedCluster() { workerRoles, err := aws.getWorkerNodeGroupRoles(aws.kfDef.Name) if err != nil { return errors.WithStack(err) } roles = workerRoles } else { roles = awsPluginSpec.Roles } } // Detach IAM Policies for _, iamRole := range roles { aws.deleteIamRolePolicy(iamRole, "iam_alb_ingress_policy") aws.deleteIamRolePolicy(iamRole, "iam_profile_controller_policy") // TODO: use Addon to check permissions // aws.deleteIamRolePolicy(iamRole, "iam_csi_fsx_policy") if awsPluginSpec.GetEnableNodeGroupLog() { aws.deleteIamRolePolicy(iamRole, "iam_cloudwatch_policy") } } return nil } // deleteIamRolePolicy detach inline policy from the role func (aws *Aws) deleteIamRolePolicy(roleName, policyName string) error { log.Infof("Deleting inline policy %s for iam role %s", policyName, roleName) input := &iam.DeleteRolePolicyInput{ PolicyName: awssdk.String(policyName), RoleName: awssdk.String(roleName), } _, err := aws.iamClient.DeleteRolePolicy(input) // This error can be skipped and should not block delete process. // It's possible user make any changes on IAM role. if err != nil { log.Warnf("Unable to delete iam inline policy %s because %v", policyName, err.Error()) } return nil } // attachIamInlinePolicy attach inline policy to IAM role func (aws *Aws) attachIamInlinePolicy(roleName, policyName, policyDocumentPath string) error { log.Infof("Attaching inline policy %s for iam role %s", policyName, roleName) policyDocumentJSONBytes, _ := ioutil.ReadFile(policyDocumentPath) input := &iam.PutRolePolicyInput{ PolicyDocument: awssdk.String(string(policyDocumentJSONBytes)), PolicyName: awssdk.String(policyName), RoleName: awssdk.String(roleName), } _, err := aws.iamClient.PutRolePolicy(input) if err != nil { log.Warnf("Unable to attach iam inline policy %s because %v", policyName, err.Error()) return nil } log.Infof("Successfully attach policy to IAM Role %v", roleName) return nil } // setupIamRoleForServiceAccount will create/reuse IAM identity provider and create/reuse web identity role. func (aws *Aws) setupIamRoleForServiceAccount() error { eksCluster, err := aws.getEksCluster(aws.kfDef.Name) if err != nil { return err } accountId, err := utils.CheckAwsAccountId(aws.sess) if err != nil { return errors.Errorf("Can not find accountId for cluster %v", aws.kfDef.Name) } // Create Identity Provider. issuerURLWithoutProtocol := eksCluster.oidcIssuerUrl[len("https://"):] exist, arn, err := aws.checkIdentityProviderExists(accountId, issuerURLWithoutProtocol) if err != nil { return errors.Errorf("Can not check identity provider existence: %v", err) } oidcProviderArn := arn if !exist { arn, err := aws.createIdentityProvider(eksCluster.oidcIssuerUrl) if err != nil { return errors.Errorf("Can not check identity provider existence: %v", err) } oidcProviderArn = arn } kubeflowAdminRoleName := fmt.Sprintf(KUBEFLOW_ADMIN_ROLE_NAME, aws.region, eksCluster.name) kubeflowUserRoleName := fmt.Sprintf(KUBEFLOW_USER_ROLE_NAME, aws.region, eksCluster.name) // Link service account, role and policy kubeflowSAIamRoleMapping := map[string]string{ "kf-admin": kubeflowAdminRoleName, "alb-ingress-controller": kubeflowAdminRoleName, "profiles-controller-service-account": kubeflowAdminRoleName, "fluentd": kubeflowAdminRoleName, "kf-user": kubeflowUserRoleName, } for ksa, iamRoleName := range kubeflowSAIamRoleMapping { // 1. Create AWS IAM Roles with web identity provider as trusted identities if err := aws.createOrUpdateWebIdentityRole(oidcProviderArn, issuerURLWithoutProtocol, iamRoleName, aws.kfDef.Namespace, ksa); err != nil { return errors.Errorf("Can not create web identity role: %v", err) } // 2. Create Kubernetes Service Account iamRoleArn := fmt.Sprintf(AWS_IAM_ROLE_ARN, accountId, iamRoleName) if err := aws.createOrUpdateK8sServiceAccount(aws.k8sClient, aws.kfDef.Namespace, ksa, iamRoleArn); err != nil { return errors.Errorf("Can not create Service Account %s/%s, %v", aws.kfDef.Namespace, ksa, err) } // 3. Link KSA to IAM Role - add service account in Role Trust Relationships if err := aws.updateRoleTrustIdentity(iamRoleName, aws.kfDef.Namespace, ksa); err != nil { return errors.Errorf("Can not update IAM role trust relationships %v", err) } } // We only want to attach admin role at this moment. // Grant kf-user policies later, based on the potential actions use may have, like ECR access, S3 access, etc. aws.roles = append(aws.roles, fmt.Sprintf(KUBEFLOW_ADMIN_ROLE_NAME, aws.region, eksCluster.name)) return nil } func (aws *Aws) deleteWebIdentityRolesAndProvider() error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return errors.WithStack(err) } if !awsPluginSpec.GetEnablePodIamPolicy() { log.Infof("Pod IAM Policy is not set, skip delete web identity provider") return nil } eksCluster, err := aws.getEksCluster(aws.kfDef.Name) if err != nil { return err } // Delete IAM role we created kfAdminRoleName := fmt.Sprintf(KUBEFLOW_ADMIN_ROLE_NAME, aws.region, eksCluster.name) kfUserRoleName := fmt.Sprintf(KUBEFLOW_USER_ROLE_NAME, aws.region, eksCluster.name) aws.deleteIAMRole(kfAdminRoleName) aws.deleteIAMRole(kfUserRoleName) log.Infof("IAM Role %s, %s has been deleted", kfAdminRoleName, kfUserRoleName) accountId, err := utils.CheckAwsAccountId(aws.sess) if err != nil { return errors.Errorf("Can not find accountId for cluster %v", aws.kfDef.Name) } // Delete oidc web identity provider issuerURLWithoutProtocol := eksCluster.oidcIssuerUrl[len("https://"):] exist, arn, err := aws.checkIdentityProviderExists(accountId, issuerURLWithoutProtocol) if err != nil { return errors.Errorf("Can not check identity provider existence: %v", err) } if !exist { log.Warnf("Identity provider %v of cluster %v does not exist", arn, eksCluster.name) return nil } if err := aws.DeleteIdentityProvider(arn); err != nil { return err } log.Infof("OIDC Identity Provider has been delete %s", issuerURLWithoutProtocol) return nil } // setupOIDC creates secret for ALB ingress controller func (aws *Aws) setupOIDC() error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return err } if awsPluginSpec.Auth.Oidc != nil { // Create OIDC Secret from clientId and clientSecret. _, err = aws.k8sClient.CoreV1().Secrets(IstioNamespace).Get(ALB_OIDC_SECRET, metav1.GetOptions{}) if err == nil { log.Warnf("Secret %v already exists...", ALB_OIDC_SECRET) return nil } // This secret need to be in istio-system, same namespace as istio-ingress return createSecret(aws.k8sClient, ALB_OIDC_SECRET, IstioNamespace, map[string][]byte{ "clientId": []byte(awsPluginSpec.Auth.Oidc.OAuthClientId), "clientSecret": []byte(awsPluginSpec.Auth.Oidc.OAuthClientSecret), }) } return nil } ================================================ FILE: pkg/kfapp/aws/eks.go ================================================ package aws import ( "fmt" awssdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/eks" versionChecker "github.com/hashicorp/go-version" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "os/exec" "path/filepath" ) type Cluster struct { name string apiServerEndpoint string oidcIssuerUrl string clusterArn string roleArn string kubernetesVersion string } // getEksCluster obtain detail info of an eks cluster func (aws *Aws) getEksCluster(clusterName string) (*Cluster, error) { input := &eks.DescribeClusterInput{ Name: awssdk.String(clusterName), } result, err := aws.eksClient.DescribeCluster(input) if err != nil { return nil, err } cluster := &Cluster{ name: awssdk.StringValue(result.Cluster.Name), apiServerEndpoint: awssdk.StringValue(result.Cluster.Endpoint), oidcIssuerUrl: awssdk.StringValue(result.Cluster.Identity.Oidc.Issuer), clusterArn: awssdk.StringValue(result.Cluster.Arn), roleArn: awssdk.StringValue(result.Cluster.RoleArn), kubernetesVersion: awssdk.StringValue(result.Cluster.Version), } return cluster, nil } // IsEksCluster checks if an AWS cluster is EKS cluster. func (aws *Aws) IsEksCluster(clusterName string) (bool, error) { input := &eks.DescribeClusterInput{ Name: awssdk.String(clusterName), } exist := true if _, err := aws.eksClient.DescribeCluster(input); err != nil { if aerr, ok := err.(awserr.Error); ok { if aerr.Code() != eks.ErrCodeResourceNotFoundException { return false, err } exist = false } } return exist, nil } // createEKSCluster creates a new EKS cluster if want kfctl to manage cluster // @Deprecated. In order to simplify workflow, user should always brings their own cluster and install kubeflow on top of it. // We still leave this option here and probably remove codes in future version func (aws *Aws) createEKSCluster() error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return err } if awsPluginSpec.GetManagedCluster() { log.Infoln("Start to create eks cluster. Please wait for 10-15 mins...") clusterConfigFile := filepath.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR, CLUSTER_CONFIG_FILE) output, err := exec.Command("eksctl", "create", "cluster", "--config-file="+clusterConfigFile).Output() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Call 'eksctl create cluster --config-file=%s' with errors: %v", clusterConfigFile, string(output)), } } log.Infoln(string(output)) nodeGroupIamRoles, getRoleError := aws.getWorkerNodeGroupRoles(aws.kfDef.Name) if getRoleError != nil { return errors.WithStack(getRoleError) } aws.roles = nodeGroupIamRoles } else { log.Infof("You already have cluster setup. Skip creating new eks cluster. ") } return nil } // deleteEKSCluster deletes eks cluster if current cluster is a managed cluster func (aws *Aws) deleteEKSCluster() error { awsPluginSpec, err := aws.GetPluginSpec() if err != nil { return err } // Delete cluster if it's a managed cluster created by kfctl if awsPluginSpec.GetManagedCluster() { log.Infoln("Start to delete eks cluster. Please wait for 5 mins...") clusterConfigFile := filepath.Join(aws.kfDef.Spec.AppDir, KUBEFLOW_AWS_INFRA_DIR, CLUSTER_CONFIG_FILE) output, err := exec.Command("eksctl", "delete", "cluster", "--config-file="+clusterConfigFile).Output() log.Infoln("Please go to aws console to check CloudFormation status and double make sure your cluster has been shutdown.") if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not call 'eksctl delete cluster --config-file=%s': %v", clusterConfigFile, string(output)), } } log.Infoln(string(output)) } return nil } // isEksctlVersionLessThan compare two version and return true if v1 is less than v2 func isEksctlVersionLessThan(v1, v2 string) (bool, error) { version1, err := versionChecker.NewVersion(v1) if err != nil { return false, err } version2, err := versionChecker.NewVersion(v2) if err != nil { return false, err } if version1.LessThan(version2) { return true, nil } return false, nil } ================================================ FILE: pkg/kfapp/aws/eks_test.go ================================================ package aws import ( "github.com/golangplus/testing/assert" "testing" ) func TestIsEksctlVersionLessThan(t *testing.T) { v1 := "0.1.30" result, _ := isEksctlVersionLessThan(v1, MINIMUM_EKSCTL_VERSION) assert.True(t, "eksctl version", result) v1 = "0.1.32" result, _ = isEksctlVersionLessThan(v1, MINIMUM_EKSCTL_VERSION) assert.False(t, "eksctl version", result) v1 = "0.1.33" result, _ = isEksctlVersionLessThan(v1, MINIMUM_EKSCTL_VERSION) assert.False(t, "eksctl version", result) } ================================================ FILE: pkg/kfapp/aws/identity.go ================================================ package aws import ( "crypto/sha1" "crypto/tls" json "encoding/json" "fmt" awssdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/iam" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "github.com/tidwall/gjson" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" "net/http" "net/url" "strings" ) const ( AWS_DEFAULT_AUDIENCE = "sts.amazonaws.com" AWS_TRUST_IDENTITY_SUBJECT = "system:serviceaccount:%s:%s" AWS_SERVICE_ACCOUNT_ANNOTATION_KEY = "eks.amazonaws.com/role-arn" AWS_IAM_ROLE_TAG_KEY = "kubeflow/cluster-name" AWS_IAM_ROLE_ARN = "arn:aws:iam::%s:role/%s" ) // checkIdentityProviderExists will return true when the iam identity provider exists, it may return errors // if it was unable to call IAM API func (aws *Aws) checkIdentityProviderExists(accountId, issuerURLWithoutProtocol string) (bool, string, error) { input := &iam.GetOpenIDConnectProviderInput{ OpenIDConnectProviderArn: awssdk.String( fmt.Sprintf("arn:aws:iam::%s:oidc-provider/%s", accountId, issuerURLWithoutProtocol), ), } _, err := aws.iamClient.GetOpenIDConnectProvider(input) if err != nil { awsError := err.(awserr.Error) if awsError.Code() == iam.ErrCodeNoSuchEntityException { return false, "", nil } return false, "", err } return true, awssdk.StringValue(input.OpenIDConnectProviderArn), nil } // createIdentityProvider create an OpenIDConnectProvider, it's one to one mapping to EKS cluster. func (aws *Aws) createIdentityProvider(issuerUrl string) (string, error) { issuerCAThumbprint, err := getIssueCAThumbprint(issuerUrl) oidcProviderInput := &iam.CreateOpenIDConnectProviderInput{ ClientIDList: []*string{awssdk.String(AWS_DEFAULT_AUDIENCE)}, ThumbprintList: []*string{awssdk.String(issuerCAThumbprint)}, Url: awssdk.String(issuerUrl), } output, err := aws.iamClient.CreateOpenIDConnectProvider(oidcProviderInput) if err != nil { return "", errors.Wrap(err, "creating OIDC identity provider") } log.Infof("Creating OpenIDConnectProvider %v", *output.OpenIDConnectProviderArn) return awssdk.StringValue(output.OpenIDConnectProviderArn), nil } // DeleteIdentityProvider will delete the identity provider, it may return an error the API call fails func (aws *Aws) DeleteIdentityProvider(providerArn string) error { input := &iam.DeleteOpenIDConnectProviderInput{ OpenIDConnectProviderArn: awssdk.String(providerArn), } if _, err := aws.iamClient.DeleteOpenIDConnectProvider(input); err != nil { return errors.Wrap(err, "deleting oidc provider") } return nil } // createOrUpdateWebIdentityRole creates an IAM role with trusted entity Web Identity if role doesn't exist func (aws *Aws) createOrUpdateWebIdentityRole(oidcProviderArn, issuerUrl, roleName, serviceAccountNamespace, serviceAccountName string) error { input := &iam.GetRoleInput{ RoleName: awssdk.String(roleName), } // Don't need to update role, return immediately. if _, err := aws.iamClient.GetRole(input); err != nil { // check non exist or other failures. if aerr, ok := err.(awserr.Error); ok { switch aerr.Code() { case iam.ErrCodeNoSuchEntityException: log.Infof("Role %v doesn't exist, creating for KSA %s/%s", roleName, serviceAccountNamespace, serviceAccountName) default: return err } } else { return err } } else { log.Infof("Role %v exists, skip creating role", roleName) return nil } // Create role statement := MakeAssumeRoleWithWebIdentityPolicyDocument(oidcProviderArn, MapOfInterfaces{ "StringEquals": map[string][]string{ issuerUrl + ":aud": []string{AWS_DEFAULT_AUDIENCE}, issuerUrl + ":sub": []string{fmt.Sprintf(AWS_TRUST_IDENTITY_SUBJECT, serviceAccountNamespace, serviceAccountName)}, }, }) assumeRolePolicyDocument := MakePolicyDocument(statement) document, err := json.Marshal(assumeRolePolicyDocument) if err != nil { return errors.Errorf("%v can not be marshal to bytes", document) } roleInput := &iam.CreateRoleInput{ RoleName: awssdk.String(roleName), AssumeRolePolicyDocument: awssdk.String(string(document)), Tags: []*iam.Tag{ { Key: awssdk.String(AWS_IAM_ROLE_TAG_KEY), // roleName is like kf-admin-clusterName Value: awssdk.String(roleName[strings.LastIndex("roleName", "-")+1:]), }, }, } _, err = aws.iamClient.CreateRole(roleInput) if err != nil { return err } return nil } // createOrUpdateK8sServiceAccount creates or updates k8s service account with annotation func (aws *Aws) createOrUpdateK8sServiceAccount(k8sClientset *clientset.Clientset, serviceAccountNamespace, serviceAccountName, iamRoleArn string) error { existingSA, err := k8sClientset.CoreV1().ServiceAccounts(serviceAccountNamespace).Get(serviceAccountName, metav1.GetOptions{}) if err == nil { log.Infof("Service account %v already exists", serviceAccountName) if existingSA.Annotations == nil { existingSA.Annotations = map[string]string{} } existingSA.Annotations[AWS_SERVICE_ACCOUNT_ANNOTATION_KEY] = iamRoleArn _, err = k8sClientset.CoreV1().ServiceAccounts(serviceAccountNamespace).Update(existingSA) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } return nil } log.Infof("Can not find existing service account, creating %s/%s", serviceAccountNamespace, serviceAccountName) _, err = k8sClientset.CoreV1().ServiceAccounts(serviceAccountNamespace).Create( &v1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: serviceAccountName, Namespace: serviceAccountNamespace, Annotations: map[string]string{ AWS_SERVICE_ACCOUNT_ANNOTATION_KEY: iamRoleArn, }, }, }, ) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } // updateRoleTrustIdentity add namespace/serviceAccount to IAM Role trust entity func (aws *Aws) updateRoleTrustIdentity(roleName, serviceAccountNamespace, serviceAccountName string) error { roleInput := &iam.GetRoleInput{ RoleName: awssdk.String(roleName), } output, err := aws.iamClient.GetRole(roleInput) if err != nil { return err } // Seems AssumeRolePolicyDocument is URL encoded, decode string to get string policy document decodeValue, err := url.QueryUnescape(awssdk.StringValue(output.Role.AssumeRolePolicyDocument)) if err != nil { return err } updatedRolePolicy, err := getUpdatedAssumeRolePolicy(decodeValue, serviceAccountNamespace, serviceAccountName) if err != nil { return err } input := &iam.UpdateAssumeRolePolicyInput{ RoleName: awssdk.String(roleName), PolicyDocument: awssdk.String(updatedRolePolicy), } if _, err = aws.iamClient.UpdateAssumeRolePolicy(input); err != nil { return err } return nil } // getUpdatedAssumeRolePolicy creates a new policy document with a new ns/sa record func getUpdatedAssumeRolePolicy(policyDocument, serviceAccountNamespace, serviceAccountName string) (string, error) { var oldDoc MapOfInterfaces json.Unmarshal([]byte(policyDocument), &oldDoc) var statements []MapOfInterfaces statementInBytes, err := json.Marshal(oldDoc["Statement"]) if err != nil { return "", err } json.Unmarshal(statementInBytes, &statements) oidcRoleArn := gjson.Get(policyDocument, "Statement.0.Principal.Federated").String() issuerUrlWithProtocol := getIssuerUrlFromRoleArn(oidcRoleArn) key := fmt.Sprintf("%s:sub", issuerUrlWithProtocol) trustIdentity := fmt.Sprintf(AWS_TRUST_IDENTITY_SUBJECT, serviceAccountNamespace, serviceAccountName) // We assume we only operator on first statement, don't add/remove new statement statement := statements[0] statementInBytes, err = json.Marshal(statement) identities := gjson.Get(string(statementInBytes), "Condition.StringEquals").Map() var originalIdentities []string val, ok := identities[key] if ok { for _, identity := range val.Array() { // avoid adding duplicate record if identity.Str == trustIdentity { return policyDocument, nil } originalIdentities = append(originalIdentities, identity.Str) } } originalIdentities = append(originalIdentities, trustIdentity) document := MakeAssumeRoleWithWebIdentityPolicyDocument(oidcRoleArn, MapOfInterfaces{ "StringEquals": map[string][]string{ issuerUrlWithProtocol + ":aud": []string{AWS_DEFAULT_AUDIENCE}, issuerUrlWithProtocol + ":sub": originalIdentities, }, }) newAssumeRolePolicyDocument := MakePolicyDocument(document) newPolicyDoc, err := json.Marshal(newAssumeRolePolicyDocument) if err != nil { return "", err } return string(newPolicyDoc), nil } // getIssueCAThumbprint will generate CAThumbprint from a given issuerURL, this is used to create an oidc provider func getIssueCAThumbprint(issuerURL string) (string, error) { var issuerCAThumbprint string client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, Proxy: http.ProxyFromEnvironment, }, } response, err := client.Get(issuerURL) if err != nil { return "", errors.Wrap(err, "connecting to issuer OIDC") } if response.TLS != nil { if numCerts := len(response.TLS.PeerCertificates); numCerts >= 1 { root := response.TLS.PeerCertificates[numCerts-1] issuerCAThumbprint = fmt.Sprintf("%x", sha1.Sum(root.Raw)) return issuerCAThumbprint, nil } } return "", errors.Errorf("unable to get OIDC issuer's certificate") } // deleteIAMRole delete an IAM role func (aws *Aws) deleteIAMRole(roleName string) error { input := &iam.DeleteRoleInput{ RoleName: awssdk.String(roleName), } if _, err := aws.iamClient.DeleteRole(input); err != nil { return err } return nil } // getIAMRoleNameFromIAMRoleArn converts roleArn to roleName func getIAMRoleNameFromIAMRoleArn(arn string) string { return arn[strings.LastIndex(arn, "/")+1:] } // getIssuerUrlFromRoleArn parse issuerUrl from Arn: arn:aws:iam::${accountId}:oidc-provider/${issuerUrl} func getIssuerUrlFromRoleArn(arn string) string { return arn[strings.Index(arn, "/")+1:] } // MakeAssumeRoleWithWebIdentityPolicyDocument constructs a trust policy statement for given web identity provider with given conditions func MakeAssumeRoleWithWebIdentityPolicyDocument(providerARN string, condition MapOfInterfaces) MapOfInterfaces { return MapOfInterfaces{ "Effect": "Allow", "Action": "sts:AssumeRoleWithWebIdentity", "Principal": map[string]string{ "Federated": providerARN, }, "Condition": condition, } } // MakePolicyDocument constructs a policy document with given statements func MakePolicyDocument(statements ...MapOfInterfaces) MapOfInterfaces { return MapOfInterfaces{ "Version": "2012-10-17", "Statement": statements, } } type ( // MapOfInterfaces is an alias for map[string]interface{} MapOfInterfaces = map[string]interface{} ) ================================================ FILE: pkg/kfapp/aws/k8sClient.go ================================================ package aws import ( kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/pkg/errors" log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "os" "path/filepath" ) // getK8sclient creates a Kubernetes client set func getK8sclient() (*clientset.Clientset, error) { kubeconfig := os.Getenv("KUBECONFIG") if kubeconfig == "" { if home := homeDir(); home != "" { kubeconfig = filepath.Join(home, ".kube", "config") } } // use the current context in kubeconfig config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { return nil, errors.Errorf("Failed to create config file from %s", kubeconfig) } clientset, err := clientset.NewForConfig(config) if err != nil { return nil, errors.Errorf("Failed to create kubernetes clientset") } return clientset, nil } // homeDir returns home folder and it's used to detect kubeconfig file func homeDir() string { if h := os.Getenv("HOME"); h != "" { return h } return os.Getenv("USERPROFILE") // windows } func createNamespace(client *clientset.Clientset, namespace string) error { _, err := client.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) if err == nil { log.Infof("Namespace %v already exists...", namespace) return nil } log.Infof("Creating namespace: %v", namespace) _, err = client.CoreV1().Namespaces().Create( &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, }, }, ) return err } func deleteNamespace(client *clientset.Clientset, namespace string) error { _, err := client.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) if err != nil { log.Infof("Namespace %v does not exist, skip deleting", namespace) return nil } log.Infof("Deleting namespace: %v", namespace) background := metav1.DeletePropagationBackground err = client.CoreV1().Namespaces().Delete( namespace, &metav1.DeleteOptions{ PropagationPolicy: &background, }, ) return err } func createSecret(client *clientset.Clientset, secretName string, namespace string, data map[string][]byte) error { secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, Namespace: namespace, }, Data: data, } log.Infof("Creating secret: %v/%v", namespace, secretName) _, err := client.CoreV1().Secrets(namespace).Create(secret) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } ================================================ FILE: pkg/kfapp/coordinator/coordinator.go ================================================ /* 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. */ package coordinator import ( "fmt" "io/ioutil" "os" "path/filepath" "strings" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfdefsv1alpha1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" kfdefsv1beta1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" "github.com/kubeflow/kfctl/v3/pkg/kfapp/aws" "github.com/kubeflow/kfctl/v3/pkg/kfapp/existing_arrikto" "github.com/kubeflow/kfctl/v3/pkg/kfapp/gcp" "github.com/kubeflow/kfctl/v3/pkg/kfapp/kustomize" "github.com/kubeflow/kfctl/v3/pkg/kfapp/minikube" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfconfigloaders "github.com/kubeflow/kfctl/v3/pkg/kfconfig/loaders" "github.com/kubeflow/kfctl/v3/pkg/utils" log "github.com/sirupsen/logrus" ) // Builder defines the methods used to create KfApps. // Primary purpose is to allow injecting a fake for use in testing. type Builder interface { LoadKfAppCfgFile(cfgFile string) (kftypesv3.KfApp, error) } type DefaultBuilder struct { } func (b *DefaultBuilder) LoadKfAppCfgFile(cfgFile string) (kftypesv3.KfApp, error) { return NewLoadKfAppFromURI(cfgFile) } // GetPlatform will return an implementation of kftypesv3.GetPlatform that matches the platform string // It looks for statically compiled-in implementations, otherwise throws unrecognized error func getPlatform(kfdef *kfconfig.KfConfig) (kftypesv3.Platform, error) { switch kfdef.Spec.Platform { case string(kftypesv3.MINIKUBE): return minikube.Getplatform(kfdef), nil case string(kftypesv3.GCP): return gcp.GetPlatform(kfdef) case string(kftypesv3.EXISTING_ARRIKTO): return existing_arrikto.GetPlatform(kfdef) case string(kftypesv3.AWS): return aws.GetPlatform(kfdef) default: // TODO(https://github.com/kubeflow/kubeflow/issues/3520) Fix dynamic loading // of platform plugins. log.Infof("** Unrecognized platform %v **", kfdef.Spec.Platform) return nil, fmt.Errorf("Unrecognized platform %v", kfdef.Spec.Platform) } } func (coord *coordinator) getPackageManagers(kfdef *kfconfig.KfConfig) *map[string]kftypesv3.KfApp { var packagemanagers = make(map[string]kftypesv3.KfApp) _packagemanager, _packagemanagerErr := getPackageManager(kfdef) if _packagemanagerErr != nil { log.Fatalf("Could not get packagemanager %v: %v **", kftypesv3.KUSTOMIZE, _packagemanagerErr) } if _packagemanager != nil { packagemanagers[kftypesv3.KUSTOMIZE] = _packagemanager } return &packagemanagers } // getPackageManager will return an implementation of kftypesv3.KfApp that matches the packagemanager string // It looks for statically compiled-in implementations, otherwise it delegates to // kftypesv3.LoadKfApp which will try and dynamically load a .so // func getPackageManager(kfdef *kfconfig.KfConfig) (kftypesv3.KfApp, error) { return kustomize.GetKfApp(kfdef), nil } // Helper function to filter out spartakus. func filterSpartakus(components []string) []string { ret := []string{} for _, comp := range components { if comp != "spartakus" { ret = append(ret, comp) } } return ret } // Helper function to print out warning message if using usage reporting. func usageReportWarn(applications []kfconfig.Application) { msg := "\n" + "****************************************************************\n" + "Notice anonymous usage reporting enabled using spartakus\n" + "To disable it\n" + "If you have already deployed it run the following commands:\n" + " cd $(pwd)\n" + " kubectl -n ${K8S_NAMESPACE} delete deploy -l app=spartakus\n" + "\n" + "For more info: https://www.kubeflow.org/docs/other-guides/usage-reporting/\n" + "****************************************************************\n" + "\n" for _, app := range applications { if app.Name == "spartakus" { log.Infof(msg) return } } } // repoVersionToRepoStruct converts the name of a repo and the old style version // into a new go-getter style syntax and a Repo spec // // master // tag // pull/[/head] // func repoVersionToUri(repo string, version string) string { // Version can be // --version master // --version tag // --version pull//head if strings.HasPrefix(version, "pull") { if !strings.HasSuffix(version, "head") { version = version + "/head" } } tarballUrl := "https://github.com/kubeflow/" + repo + "/tarball/" + version + "?archive=tar.gz" return tarballUrl } // isDirEmpty - quick check to determine if the directory is empty func isDirEmpty(dir string) bool { files, _ := ioutil.ReadDir(dir) if len(files) > 1 { return false } return true } // This is the entrypoint for commands like build or apply. // NewLoadKfAppFromURI takes in a config file and constructs the KfApp // used by the build and apply semantics for kfctl func NewLoadKfAppFromURI(configFile string) (kftypesv3.KfApp, error) { kfdef, err := kfconfigloaders.LoadConfigFromURI(configFile) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error creating KfApp from config file: %v", err), } } isRemoteFile, err := utils.IsRemoteFile(configFile) if err != nil { return nil, err } // If the config file is a remote URI, check to see if the AppDir // is empty because we will be generating the KfApp there. if isRemoteFile { // AppDir should be the cwd. if !isDirEmpty(kfdef.Spec.AppDir) { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("current directory %v not empty, please switch directories", kfdef.Spec.AppDir), } } _, err = CreateKfAppCfgFile(kfdef) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error creating KfApp from config file: %v", err), } } } appFile := filepath.Join(kfdef.Spec.AppDir, kfdef.Spec.ConfigFileName) // Since we know we have a local file we can set a default name if none is set based on the local directory if kfdef.Name == "" { kfdef.Name = nameFromAppFile(filepath.Join(kfdef.Spec.AppDir, kfdef.Spec.ConfigFileName)) if kfdef.Name == "" { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("KfDef.Name isn't set and there was a problem inferring the name based on the path %v\nPlease set the name explicitly in the KFDef spec.", appFile), } } log.Infof("No name specified in KfDef.Metadata.Name; defaulting to %v based on location of config file: %v.", kfdef.Name, appFile) } c := &coordinator{ Platforms: make(map[string]kftypesv3.Platform), PackageManagers: make(map[string]kftypesv3.KfApp), KfDef: kfdef, } // fetch the platform [gcp,minikube] platform := c.KfDef.Spec.Platform if platform != "" { _platform, _platformErr := getPlatform(c.KfDef) if _platformErr != nil { log.Fatalf("Could not get platform %v: %v **", platform, _platformErr) return nil, _platformErr } if _platform != nil { c.Platforms[platform] = _platform } } pkg, pkgErr := getPackageManager(c.KfDef) if pkgErr != nil { log.Fatalf("Could not get package manager %v: %v **", kftypesv3.KUSTOMIZE, pkgErr) return nil, pkgErr } if pkg != nil { c.PackageManagers[kftypesv3.KUSTOMIZE] = pkg } initErr := c.Init(kftypesv3.ALL) if initErr != nil { return nil, fmt.Errorf("KfApp initiliazation failed: %v", initErr) } generateErr := c.Generate(kftypesv3.ALL) if generateErr != nil { return nil, fmt.Errorf("couldn't generate KfApp: %v", generateErr) } return c, nil } // TODO: remove this // This is for kfctlServer. We can remove this after kfctlServer uses kfconfig func CreateKfAppCfgFileWithKfDef(d *kfdefsv1alpha1.KfDef) (string, error) { alphaConverter := kfconfigloaders.V1alpha1{} kfconfig, err := alphaConverter.LoadKfConfig(*d) if err != nil { return "", err } kfconfig.Spec.ConfigFileName = kftypesv3.KfConfigFile return CreateKfAppCfgFile(kfconfig) } // CreateKfAppCfgFile will create the application directory and persist // the KfDef to it as app.yaml. // This is only used when the config file is remote (https://github...) // Returns an error if the app.yaml file already exists // Returns path to the app.yaml file. func CreateKfAppCfgFile(d *kfconfig.KfConfig) (string, error) { if _, err := os.Stat(d.Spec.AppDir); os.IsNotExist(err) { log.Infof("Creating directory %v", d.Spec.AppDir) appdirErr := os.MkdirAll(d.Spec.AppDir, os.ModePerm) if appdirErr != nil { log.Errorf("Couldn't create directory %v: %v", d.Spec.AppDir, appdirErr) return "", appdirErr } } else { log.Infof("App directory %v already exists", d.Spec.AppDir) } log.Infof("Writing KfDef to %v", d.Spec.ConfigFileName) cfgFilePathErr := kfconfigloaders.WriteConfigToFile(*d) if cfgFilePathErr != nil { log.Errorf("Failed to write config: %v", cfgFilePathErr) } return filepath.Join(d.Spec.AppDir, d.Spec.ConfigFileName), cfgFilePathErr } // nameFromAppFile infers a default name given the path to the KFDef file. // returns the empty string if there is a problem getting the name. func nameFromAppFile(appFile string) string { absAppPath, err := filepath.Abs(appFile) if err != nil { log.Errorf("KfDef.Name isn't set and there was a problem inferring the name based on the path %v; error: %v\nPlease set the name explicitly in the KFDef spec.", appFile, err) return "" } appDir := filepath.Dir(absAppPath) name := filepath.Base(appDir) if name == appDir { // This case happens if appFile is in the root directory return "" } return name } // this type holds platform implementations of KfApp // eg Platforms[kftypesv3.GCP], Platforms[kftypes.MINIKUBE], PackageManagers["kustomize"] // The data attributes in kfconfig.KfConfig are used by different KfApp implementations type coordinator struct { Platforms map[string]kftypesv3.Platform PackageManagers map[string]kftypesv3.KfApp KfDef *kfconfig.KfConfig } // Return a copy of kfdef v1beta1 type KfDefGetterV1beta1 interface { GetKfDefV1Beta1() *kfdefsv1beta1.KfDef } // Get reference to the plugin . type PluginGetter interface { GetPlugin(name string) (kftypesv3.KfApp, bool) } //TODO(kunming): remove after kfctlserver change (https://github.com/kubeflow/kubeflow/pull/4399) merged. func (kfapp *coordinator) GetKfDef() *kfdefsv1beta1.KfDef { return nil } // GetKfDefV1Beta1 returns a copy of KfDef V1Beta1 used by this application. func (kfapp *coordinator) GetKfDefV1Beta1() *kfdefsv1beta1.KfDef { kfdefIns := &kfdefsv1beta1.KfDef{} err := kfconfigloaders.V1beta1{}.LoadKfDef(*(kfapp.KfDef.DeepCopy()), kfdefIns) if err != nil { kfdefIns.Status.Conditions = append(kfdefIns.Status.Conditions, kfdefsv1beta1.KfDefCondition{ Type: kfdefsv1beta1.KfDegraded, Message: err.Error(), }) return kfdefIns } return kfdefIns } // GetPlatform returns the specified platform. func (kfapp *coordinator) GetPlugin(name string) (kftypesv3.KfApp, bool) { if r, ok := kfapp.Platforms[name]; ok { return r, ok } r, ok := kfapp.PackageManagers[name] return r, ok } func (kfapp *coordinator) Dump(resources kftypesv3.ResourceEnum) error { for packageManagerName, packageManager := range kfapp.PackageManagers { err := packageManager.Dump(kftypesv3.K8S) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("kfApp Apply failed for %v: %v", packageManagerName, err), } } } return nil } func (kfapp *coordinator) Apply(resources kftypesv3.ResourceEnum) error { platform := func() error { if kfapp.KfDef.Spec.Platform != "" { platform := kfapp.Platforms[kfapp.KfDef.Spec.Platform] if platform != nil { platformErr := platform.Apply(resources) if platformErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("coordinator Apply failed for %v: %v", kfapp.KfDef.Spec.Platform, platformErr), } } } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("%v not in Platforms", kfapp.KfDef.Spec.Platform), } } } return nil } k8s := func() error { for packageManagerName, packageManager := range kfapp.PackageManagers { packageManagerErr := packageManager.Apply(kftypesv3.K8S) if packageManagerErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("kfApp Apply failed for %v: %v", packageManagerName, packageManagerErr), } } } updateConfigErr := kfconfigloaders.WriteConfigToFile(*kfapp.KfDef) if updateConfigErr != nil { return &kfapis.KfError{ Code: updateConfigErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("cannot update config file %v: %v", kftypesv3.KfConfigFile, updateConfigErr.(*kfapis.KfError).Message), } } return nil } gcpAddedConfig := func() error { if kfapp.KfDef.Spec.Email == "" || kfapp.KfDef.Spec.Platform != kftypesv3.GCP { return nil } if p, ok := kfapp.Platforms[kfapp.KfDef.Spec.Platform]; !ok { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: "Platform GCP specified but not loaded.", } } else { gcp := p.(*gcp.Gcp) if err := gcp.SetupWorkloadIdentityPermission(); err != nil { return err } // Keep podDefault for backward compatibility return gcp.ConfigPodDefault() } } if err := kfapp.KfDef.SyncCache(); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not sync cache. Error: %v", err), } } switch resources { case kftypesv3.ALL: if err := platform(); err != nil { return err } if err := k8s(); err != nil { return err } return gcpAddedConfig() case kftypesv3.PLATFORM: return platform() case kftypesv3.K8S: if err := k8s(); err != nil { return err } // TODO(gabrielwen): Need to find a more proper way of injecting plugings. // https://github.com/kubeflow/kubeflow/issues/3708 return gcpAddedConfig() } return nil } func (kfapp *coordinator) Delete(resources kftypesv3.ResourceEnum) error { platform := func() error { if kfapp.KfDef.Spec.Platform != "" { platform := kfapp.Platforms[kfapp.KfDef.Spec.Platform] if platform != nil { platformErr := platform.Delete(resources) if platformErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("coordinator Delete failed for %v: %v", kfapp.KfDef.Spec.Platform, platformErr), } } } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("%v not in Platforms", kfapp.KfDef.Spec.Platform), } } } return nil } k8s := func() error { for packageManagerName, packageManager := range kfapp.PackageManagers { packageManagerErr := packageManager.Delete(kftypesv3.K8S) if packageManagerErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("kfApp Delete failed for %v: %v", packageManagerName, packageManagerErr), } } } return nil } if err := kfapp.KfDef.SyncCache(); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not sync cache. Error: %v", err), } } switch resources { case kftypesv3.ALL: // if we're deleting ALL, any problems with deleting k8s will abort and not delete the platform if err := k8s(); err != nil { return err } if err := platform(); err != nil { return err } case kftypesv3.PLATFORM: // deleting the PLATFORM means deleting the cluster. We remove k8s first in order free up any cloud vendor // resources. Deleting k8 resources is a best effort and partial delete or failure should not // prevent PLATFORM (cluster) deletion _ = k8s() if err := platform(); err != nil { return err } case kftypesv3.K8S: if err := k8s(); err != nil { return err } } return nil } func (kfapp *coordinator) Generate(resources kftypesv3.ResourceEnum) error { platform := func() error { if kfapp.KfDef.Spec.Platform != "" { platform := kfapp.Platforms[kfapp.KfDef.Spec.Platform] if platform != nil { platformErr := platform.Generate(resources) if platformErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("coordinator Generate failed for %v: %v", kfapp.KfDef.Spec.Platform, platformErr), } } createConfigErr := kfconfigloaders.WriteConfigToFile(*kfapp.KfDef) if createConfigErr != nil { return &kfapis.KfError{ Code: createConfigErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("cannot create config file %v: %v", kftypesv3.KfConfigFile, createConfigErr.(*kfapis.KfError).Message), } } } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("%v not in Platforms", kfapp.KfDef.Spec.Platform), } } } return nil } k8s := func() error { for packageManagerName, packageManager := range kfapp.PackageManagers { packageManagerErr := packageManager.Generate(kftypesv3.K8S) if packageManagerErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("kfApp Generate failed for %v: %v", packageManagerName, packageManagerErr), } } } return nil } // Print out warning message if using usage reporting component. usageReportWarn(kfapp.KfDef.Spec.Applications) if err := kfapp.KfDef.SyncCache(); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not sync cache. Error: %v", err), } } switch resources { case kftypesv3.ALL: if err := platform(); err != nil { return err } return k8s() case kftypesv3.PLATFORM: return platform() case kftypesv3.K8S: return k8s() } return nil } func (kfapp *coordinator) Init(resources kftypesv3.ResourceEnum) error { platform := func() error { if kfapp.KfDef.Spec.Platform != "" { platform := kfapp.Platforms[kfapp.KfDef.Spec.Platform] if platform != nil { platformErr := platform.Init(resources) if platformErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("coordinator Init failed for %v: %v", kfapp.KfDef.Spec.Platform, platformErr), } } createConfigErr := kfconfigloaders.WriteConfigToFile(*kfapp.KfDef) if createConfigErr != nil { return &kfapis.KfError{ Code: createConfigErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("cannot create config file %v: %v", kftypesv3.KfConfigFile, createConfigErr.(*kfapis.KfError).Message), } } } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("%v not in Platforms", kfapp.KfDef.Spec.Platform), } } } return nil } k8s := func() error { for packageManagerName, packageManager := range kfapp.PackageManagers { packageManagerErr := packageManager.Init(kftypesv3.K8S) if packageManagerErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("kfApp Init failed for %v: %v", packageManagerName, packageManagerErr), } } } return nil } switch resources { case kftypesv3.ALL: if err := platform(); err != nil { return err } return k8s() case kftypesv3.PLATFORM: return platform() case kftypesv3.K8S: return k8s() } return nil } func (kfapp *coordinator) Show(resources kftypesv3.ResourceEnum) error { switch resources { case kftypesv3.K8S: fallthrough case kftypesv3.PLATFORM: fallthrough case kftypesv3.ALL: if kfapp.KfDef.Spec.Platform != "" { platform := kfapp.Platforms[kfapp.KfDef.Spec.Platform] show, ok := platform.(kftypesv3.KfShow) if ok && show != nil { showErr := show.Show(resources) if showErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("coordinator Show failed for %v: %v", kfapp.KfDef.Spec.Platform, showErr), } } } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("coordinator Show failed for %v: Not support 'Show'", kfapp.KfDef.Spec.Platform), } } } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("%v not in Platforms", kfapp.KfDef.Spec.Platform), } } for packageManagerName, packageManager := range kfapp.PackageManagers { show, ok := packageManager.(kftypesv3.KfShow) if ok && show != nil { showErr := show.Show(kftypesv3.K8S) if showErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("kfApp Show failed for %v: %v", packageManagerName, showErr), } } } } } return nil } ================================================ FILE: pkg/kfapp/coordinator/coordinator_test.go ================================================ package coordinator import ( "encoding/json" "io/ioutil" "os" "path" "reflect" "testing" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func Test_CreateKfAppCfgFile(t *testing.T) { type testCase struct { Input kfconfig.KfConfig DirExists bool CfgFileExists bool ExpectError bool } cases := []testCase{ // Test file is created when directory doesn't exist. { Input: kfconfig.KfConfig{ TypeMeta: metav1.TypeMeta{ APIVersion: "kfdef.apps.kubeflow.org/v1alpha1", }, Spec: kfconfig.KfConfigSpec{ ConfigFileName: kftypesv3.KfConfigFile, }, }, DirExists: false, CfgFileExists: false, ExpectError: false, }, // Test file is created when directory exists { Input: kfconfig.KfConfig{ TypeMeta: metav1.TypeMeta{ APIVersion: "kfdef.apps.kubeflow.org/v1alpha1", }, Spec: kfconfig.KfConfigSpec{ ConfigFileName: kftypesv3.KfConfigFile, }, }, DirExists: true, CfgFileExists: false, ExpectError: false, }, // Test an error is raised if the config file already exists. { Input: kfconfig.KfConfig{ TypeMeta: metav1.TypeMeta{ APIVersion: "kfdef.apps.kubeflow.org/v1alpha1", }, Spec: kfconfig.KfConfigSpec{ ConfigFileName: kftypesv3.KfConfigFile, }, }, DirExists: true, CfgFileExists: true, ExpectError: false, }, } for _, c := range cases { tDir, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("Could not create temporary directory; %v", err) } if !c.DirExists { err := os.RemoveAll(tDir) if err != nil { t.Fatalf("Could not delete %v; error %v", tDir, err) } } if c.CfgFileExists { existingCfgFile := path.Join(tDir, kftypesv3.KfConfigFile) err := ioutil.WriteFile(existingCfgFile, []byte("hello world"), 0644) if err != nil { t.Fatalf("Could not write %v; error %v", existingCfgFile, err) } } c.Input.Spec.AppDir = tDir cfgFile, err := CreateKfAppCfgFile(&c.Input) pCase, _ := Pformat(c) hasError := err != nil if hasError != c.ExpectError { t.Errorf("Test case %v;\n CreateKfAppCfgFile returns error; got %v want %v", pCase, hasError, c.ExpectError) } expectFile := path.Join(tDir, kftypesv3.KfConfigFile) if !c.ExpectError { if expectFile != cfgFile { t.Errorf("Test case %v;\n CreateKfAppCfgFile returns cfgFile; got %v want %v", pCase, cfgFile, expectFile) } } } } func Test_repoVersionToRepoStruct(t *testing.T) { type testCase struct { name string version string expected string } testCases := []testCase{ { name: "kubeflow", version: "master", expected: "https://github.com/kubeflow/kubeflow/tarball/master?archive=tar.gz", }, { name: "manifests", version: "pull/189", expected: "https://github.com/kubeflow/manifests/tarball/pull/189/head?archive=tar.gz", }, } for _, c := range testCases { actual := repoVersionToUri(c.name, c.version) if !reflect.DeepEqual(actual, c.expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.expected) t.Errorf("Error converting got;\n%v\nwant;\n%v", pGot, pWant) } } } func Test_nameFromAppFile(t *testing.T) { type testCase struct { appFile string expectedName string } testCases := []testCase{ { appFile: "/mykfapp/kfctl.yaml", expectedName: "mykfapp", }, { appFile: "/parentdir/subapp/app.yaml", expectedName: "subapp", }, { appFile: "/kfctl.yaml", expectedName: "", }, } for _, c := range testCases { actual := nameFromAppFile(c.appFile) if actual != c.expectedName { t.Errorf("Error getting name from %v got;\n%v\nwant;\n%v", c.appFile, actual, c.expectedName) } } } // Pformat returns a pretty format output of any value. func Pformat(value interface{}) (string, error) { if s, ok := value.(string); ok { return s, nil } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { return "", err } return string(valueJson), nil } ================================================ FILE: pkg/kfapp/coordinator/fake/fake.go ================================================ // package fake provides a fake implementation of the coordinator for use in tests package fake import ( "path" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" gcpFake "github.com/kubeflow/kfctl/v3/pkg/kfapp/gcp/fake" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfloaders "github.com/kubeflow/kfctl/v3/pkg/kfconfig/loaders" ) type FakeCoordinator struct { KfDef *kfconfig.KfConfig Plugins map[string]kftypes.KfApp } func (f *FakeCoordinator) Apply(resources kftypes.ResourceEnum) error { return nil } func (f *FakeCoordinator) Delete(resources kftypes.ResourceEnum) error { return nil } func (f *FakeCoordinator) Dump(resources kftypes.ResourceEnum) error { return nil } func (f *FakeCoordinator) Generate(resources kftypes.ResourceEnum) error { return nil } func (f *FakeCoordinator) Init(resources kftypes.ResourceEnum) error { return nil } func (f *FakeCoordinator) GetKfDef() *kfconfig.KfConfig { return f.KfDef } func (f *FakeCoordinator) GetPlugin(name string) (kftypes.KfApp, bool) { a, ok := f.Plugins[name] return a, ok } type FakeBuilder struct { } func (b *FakeBuilder) CreateKfAppCfgFile(def *kfconfig.KfConfig) (string, error) { return path.Join(def.Spec.AppDir, kftypes.KfConfigFile), nil } func (b *FakeBuilder) LoadKfAppCfgFile(cfgFile string) (kftypes.KfApp, error) { d, err := kfloaders.LoadConfigFromURI(cfgFile) if err != nil { return nil, err } f := &FakeCoordinator{ KfDef: d, Plugins: make(map[string]kftypes.KfApp), } for _, p := range d.Spec.Plugins { if p.Name == kftypes.GCP { f.Plugins[kftypes.GCP] = &gcpFake.FakeGcp{} break } } return f, nil } ================================================ FILE: pkg/kfapp/dockerfordesktop/dockerfordesktop.go ================================================ /* 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. */ package dockerfordesktop import ( "fmt" "io/ioutil" "os/user" "path/filepath" "strconv" "strings" "github.com/ghodss/yaml" "github.com/kubeflow/kfctl/v3/config" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfdefs "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" ) // DockerForDesktop implements KfApp Interface // It should include functionality needed for the dockerfordesktop platform type DockerForDesktop struct { kfdefs.KfDef } func GetKfApp(kfdef *kfdefs.KfDef) kftypes.KfApp { _dockerfordesktop := &DockerForDesktop{ KfDef: *kfdef, } return _dockerfordesktop } func (dockerfordesktop *DockerForDesktop) Apply(resources kftypes.ResourceEnum) error { //mount_local_fs //setup_tunnels return nil } func (dockerfordesktop *DockerForDesktop) Delete(resources kftypes.ResourceEnum) error { return nil } func (dockerfordesktop *DockerForDesktop) Dump(resources kftypes.ResourceEnum) error { return nil } func (dockerfordesktop *DockerForDesktop) generate() error { // remove Katib package and component dockerfordesktop.Spec.Packages = kftypes.RemoveItem(dockerfordesktop.Spec.Packages, "katib") dockerfordesktop.Spec.Components = kftypes.RemoveItem(dockerfordesktop.Spec.Components, "katib") dockerfordesktop.Spec.ComponentParams["application"] = []config.NameValue{ { Name: "components", Value: "[" + strings.Join(kftypes.QuoteItems(dockerfordesktop.Spec.Components), ",") + "]", }, } usr, err := user.Current() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Could not get current user; error %v", err), } } uid := usr.Uid gid := usr.Gid dockerfordesktop.Spec.ComponentParams["jupyter"] = []config.NameValue{ { Name: string(kftypes.PLATFORM), Value: dockerfordesktop.Spec.Platform, }, { Name: "accessLocalFs", Value: strconv.FormatBool(dockerfordesktop.Spec.MountLocal), }, { Name: "disks", Value: "local-notebooks", }, { Name: "notebookUid", Value: uid, }, { Name: "notebookGid", Value: gid, }, } dockerfordesktop.Spec.ComponentParams["ambassador"] = []config.NameValue{ { Name: string(kftypes.PLATFORM), Value: dockerfordesktop.Spec.Platform, }, { Name: "replicas", Value: "1", }, } return nil } func (dockerfordesktop *DockerForDesktop) Generate(resources kftypes.ResourceEnum) error { switch resources { case kftypes.K8S: case kftypes.ALL: fallthrough case kftypes.PLATFORM: generateErr := dockerfordesktop.generate() if generateErr != nil { return generateErr } } createConfigErr := dockerfordesktop.writeConfigFile() if createConfigErr != nil { return createConfigErr } return nil } func (dockerfordesktop *DockerForDesktop) Init(resources kftypes.ResourceEnum) error { return nil } func (dockerfordesktop *DockerForDesktop) writeConfigFile() error { buf, bufErr := yaml.Marshal(dockerfordesktop.KfDef) if bufErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot marshal config file: %v", bufErr), } } cfgFilePath := filepath.Join(dockerfordesktop.KfDef.Spec.AppDir, kftypes.KfConfigFile) cfgFilePathErr := ioutil.WriteFile(cfgFilePath, buf, 0644) if cfgFilePathErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot write config file: %v", cfgFilePathErr), } } return nil } ================================================ FILE: pkg/kfapp/existing_arrikto/existing.go ================================================ package existing_arrikto import ( "bytes" "context" cryptorand "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "fmt" "html/template" "math/big" "math/rand" "net" "net/url" "os" "path" "strings" "time" kfapisv3 "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/utils" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/crypto/bcrypt" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/rest" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "sigs.k8s.io/controller-runtime/pkg/client" ) const ( KUBEFLOW_USER_EMAIL = "KUBEFLOW_USER_EMAIL" KUBEFLOW_ENDPOINT = "KUBEFLOW_ENDPOINT" OIDC_ENDPOINT = "OIDC_ENDPOINT" // Path in manifests repo to where the additional configs are located CONFIG_LOCAL_PATH = "kfdef/generic" ) type Existing struct { *kfconfig.KfConfig istioManifests []manifest authOIDCManifests []manifest } type manifest struct { name string path string } func GetPlatform(kfdef *kfconfig.KfConfig) (kftypesv3.Platform, error) { istioManifestsDir := path.Join(CONFIG_LOCAL_PATH, "istio") istioManifests := []manifest{ { name: "Istio CRDs", path: path.Join(istioManifestsDir, "crds.yaml"), }, { name: "Istio Control Plane", path: path.Join(istioManifestsDir, "istio-noauth.yaml"), }, } authOIDCManifestsDir := path.Join(CONFIG_LOCAL_PATH, "auth_oidc") authOIDCManifests := []manifest{ { name: "Istio Gateway", path: path.Join(authOIDCManifestsDir, "gateway.yaml"), }, { name: "Istio Ext-Auth Envoy Filter", path: path.Join(authOIDCManifestsDir, "envoy-filter.yaml"), }, { name: "Dex", path: path.Join(authOIDCManifestsDir, "dex.yaml"), }, { name: "AuthService", path: path.Join(authOIDCManifestsDir, "authservice.yaml"), }, } existing := &Existing{ KfConfig: kfdef, istioManifests: istioManifests, authOIDCManifests: authOIDCManifests, } return existing, nil } func (existing *Existing) GetK8sConfig() (*rest.Config, *clientcmdapi.Config) { return nil, nil } func (existing *Existing) Init(resources kftypesv3.ResourceEnum) error { return nil } func (existing *Existing) Generate(resources kftypesv3.ResourceEnum) error { return nil } func (existing *Existing) Apply(resources kftypesv3.ResourceEnum) error { if err := existing.SyncCache(); err != nil { return internalError(err) } manifestRepo, ok := existing.GetRepoCache(kftypesv3.ManifestsRepoName) if !ok { return internalError(errors.New("Manifests repo is not defined.")) } kfRepoDir := manifestRepo.LocalPath for i := range existing.istioManifests { existing.istioManifests[i].path = path.Join(kfRepoDir, existing.istioManifests[i].path) } for i := range existing.authOIDCManifests { existing.authOIDCManifests[i].path = path.Join(kfRepoDir, existing.authOIDCManifests[i].path) } // Apply extra components config := kftypesv3.GetConfig() // Create namespace // Get a K8s client kubeclient, err := client.New(config, client.Options{}) if err != nil { return internalError(errors.WithStack(err)) } // Create KFApp's namespace ns := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: existing.Namespace, }, } log.Infof("Creating namespace: %v", ns.Name) err = kubeclient.Create(context.TODO(), ns) if err != nil && !apierrors.IsAlreadyExists(err) { log.Errorf("Error creating namespace %v", ns.Name) return internalError(errors.WithStack(err)) } // Install Istio if err := applyManifests(existing.istioManifests); err != nil { return internalError(errors.WithStack(err)) } // Get Kubeflow and Dex Endpoints kfEndpoint, oidcEndpoint, err := getEndpoints(kubeclient) if err != nil { return internalError(errors.WithStack(err)) } log.Infof("Got Kubeflow Endpoint: %s.", kfEndpoint) log.Infof("Got OIDC Endpoint: %s", oidcEndpoint) log.Infof("Creating self-signed cert for %s", kfEndpoint) kfEndpointURL, err := url.Parse(kfEndpoint) if err != nil { return internalError(errors.WithStack(err)) } if err := createSelfSignedCerts(kubeclient, kfEndpointURL.Hostname()); err != nil { return internalError(errors.WithStack(err)) } // Get the kubeflow user to add // TODO(yanniszark): get this from a plugin struct eventually (https://github.com/kubeflow/kubeflow/issues/3529) log.Info("Getting the Kubeflow User") kubeflowUser, err := getKubeflowUser() if err != nil { return internalError(errors.WithStack(err)) } data := struct { KubeflowEndpoint string OIDCEndpoint string AuthServiceClientSecret string KubeflowUser *kfUser }{ KubeflowEndpoint: kfEndpoint, OIDCEndpoint: oidcEndpoint, AuthServiceClientSecret: genRandomString(32), KubeflowUser: kubeflowUser, } // Generate YAML from the dex, authservice templates authOIDCManifestsDir := path.Join(kfRepoDir, CONFIG_LOCAL_PATH, "auth_oidc") err = generateFromGoTemplate( path.Join(authOIDCManifestsDir, "authservice.tmpl"), path.Join(authOIDCManifestsDir, "authservice.yaml"), data, ) if err != nil { return internalError(errors.WithStack(err)) } err = generateFromGoTemplate( path.Join(authOIDCManifestsDir, "dex.tmpl"), path.Join(authOIDCManifestsDir, "dex.yaml"), data, ) if err != nil { return internalError(errors.WithStack(err)) } // Install OIDC Authentication if err := applyManifests(existing.authOIDCManifests); err != nil { return internalError(errors.WithStack(err)) } return nil } func (existing *Existing) Delete(resources kftypesv3.ResourceEnum) error { config := kftypesv3.GetConfig() kubeclient, err := client.New(config, client.Options{}) if err != nil { return internalError(errors.WithStack(err)) } ns := &corev1.Namespace{} for { err := kubeclient.Get(context.TODO(), types.NamespacedName{Name: existing.Namespace}, ns) // If Namespace has been deleted, break if apierrors.IsNotFound(err) { break } // If an unknown error occured, return if err != nil { return internalError(errors.WithStack(err)) } // If Namespace exists, delete it if ns.DeletionTimestamp == nil { if err := kubeclient.Delete(context.TODO(), ns); err != nil { return internalError(errors.WithStack(err)) } } log.Info("Waiting for namespace deletion to finish...") time.Sleep(5 * time.Second) } rev := func(manifests []manifest) []manifest { r := []manifest{} max := len(manifests) for i := 0; i < max; i++ { r = append(r, manifests[max-1-i]) } return r } if err := deleteManifests(rev(existing.authOIDCManifests)); err != nil { return internalError(errors.WithStack(err)) } if err := deleteManifests(rev(existing.istioManifests)); err != nil { return internalError(errors.WithStack(err)) } return nil } func (existing *Existing) Dump(resources kftypesv3.ResourceEnum) error { return nil } func internalError(err error) error { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("%+v", err), } } type kfUser struct { UserEmail string Username string PasswordHash string } func getKubeflowUser() (*kfUser, error) { kfUserEmail := os.Getenv(KUBEFLOW_USER_EMAIL) kfPassword := os.Getenv(kftypesv3.KUBEFLOW_PASSWORD) kfUsername := "" if kfUserEmail == "" || kfPassword == "" { log.Warn("KUBEFLOW_USER_EMAIL or KUBEFLOW_PASSWORD not given. Starting without creating a user.") log.Warn("If you want to create a user, edit the dex ConfigMap.") return nil, nil } else if !strings.Contains(kfUserEmail, "@") { return nil, fmt.Errorf("KUBEFLOW_USER_EMAIL is not a valid email (does not contain '@')") } kfUsername = kfUserEmail[0:strings.Index(kfUserEmail, "@")] kfPasswordHash, err := bcrypt.GenerateFromPassword([]byte(kfPassword), 13) if err != nil { return nil, err } log.Infof("Kubeflow user with email %s will be created", kfUserEmail) return &kfUser{ UserEmail: kfUserEmail, Username: kfUsername, PasswordHash: string(kfPasswordHash), }, nil } func getEndpoints(kubeclient client.Client) (string, string, error) { // Get Istio IngressGateway Service LoadBalancer IP kfEndpoint := os.Getenv(KUBEFLOW_ENDPOINT) if !strings.HasPrefix(kfEndpoint, "https") && kfEndpoint != "" { return "", "", errors.New("KUBEFLOW_ENDPOINT address must start with https:// scheme.") } oidcEndpoint := os.Getenv(OIDC_ENDPOINT) if !strings.HasPrefix(oidcEndpoint, "https") && oidcEndpoint != "" { return "", "", errors.New("OIDC_ENDPOINT address must start with https:// scheme.") } if kfEndpoint == "" { lbIP, err := getLBAddress(kubeclient) if err != nil { return "", "", errors.WithStack(err) } kfEndpoint = fmt.Sprintf("https://%s", lbIP) log.Infof("KUBEFLOW_ENDPOINT not set, using %s", kfEndpoint) } if oidcEndpoint == "" { oidcEndpoint = fmt.Sprintf("%s:5556/dex", kfEndpoint) log.Infof("OIDC_ENDPOINT not set, using %s", oidcEndpoint) } return kfEndpoint, oidcEndpoint, nil } func createSelfSignedCerts(kubeclient client.Client, addr string) error { cert, key, err := generateCert(addr) if err != nil { return errors.WithStack(err) } // Create secret from them secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "istio-ingressgateway-certs", Namespace: "istio-system", }, Data: map[string][]byte{ "tls.crt": cert, "tls.key": key, }, } if err := kubeclient.Create(context.TODO(), secret); err != nil && !apierrors.IsAlreadyExists(err) { return errors.WithStack(err) } return nil } // generateCert returns the self-signed key and cert for // a given address. func generateCert(addr string) ([]byte, []byte, error) { // Generate private key key, err := rsa.GenerateKey(cryptorand.Reader, 2048) if err != nil { return nil, nil, errors.WithStack(err) } // Generate certificate now := time.Now() tmpl := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(seededRand.Int63()), Subject: pkix.Name{ CommonName: addr, Organization: []string{"kubeflow-self-signed"}, }, NotBefore: now.UTC(), NotAfter: now.Add(time.Second * 60 * 60 * 24 * 365).UTC(), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, BasicConstraintsValid: true, IsCA: true, } if ip := net.ParseIP(addr); ip != nil { tmpl.IPAddresses = append(tmpl.IPAddresses, ip) } else { tmpl.DNSNames = append(tmpl.DNSNames, addr) } tmpl.DNSNames = append(tmpl.DNSNames, "localhost") certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key) if err != nil { return nil, nil, errors.WithStack(err) } certificate, err := x509.ParseCertificate(certDERBytes) if err != nil { return nil, nil, errors.WithStack(err) } // PEM Encode both certBuffer := bytes.Buffer{} if err := pem.Encode(&certBuffer, &pem.Block{ Type: "CERTIFICATE", Bytes: certificate.Raw, }); err != nil { return nil, nil, errors.WithStack(err) } keyBuffer := bytes.Buffer{} if err := pem.Encode(&keyBuffer, &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key), }); err != nil { return nil, nil, errors.WithStack(err) } return certBuffer.Bytes(), keyBuffer.Bytes(), nil } func getLBAddress(kubeclient client.Client) (string, error) { // Get IngressGateway Service's address const maxRetries = 80 var lbIngresses []corev1.LoadBalancerIngress svc := &corev1.Service{} lbServiceName := types.NamespacedName{Name: "istio-ingressgateway", Namespace: "istio-system"} for i := 0; ; i++ { log.Info("Trying to get istio-ingressgateway Service Address from its Status") err := kubeclient.Get( context.TODO(), lbServiceName, svc, ) if err != nil { log.Errorf("Error trying to get istio-ingressgateway service") return "", err } if svc.Status.LoadBalancer.Ingress != nil { lbIngresses = svc.Status.LoadBalancer.Ingress break } if i == maxRetries { return "", errors.New("timed out while waiting to get istio-ingressgateway Service Address from its Status") } time.Sleep(10 * time.Second) } for _, lbIngress := range lbIngresses { // Hostname is preferred over IP if lbIngress.Hostname != "" { return lbIngress.Hostname, nil } if lbIngress.IP != "" { return lbIngress.IP, nil } } return "", errors.New(fmt.Sprintf("Couldn't find a LoadBalancer address in Service's %v Status.", lbServiceName)) } func applyManifests(manifests []manifest) error { config := kftypesv3.GetConfig() for _, m := range manifests { log.Infof("Installing %s...", m.name) err := utils.CreateResourceFromFile( config, m.path, ) if err != nil { log.Errorf("Failed to create %s: %v", m.name, err) return err } } return nil } func deleteManifests(manifests []manifest) error { config := kftypesv3.GetConfig() for _, m := range manifests { log.Infof("Deleting %s...", m.name) if _, err := os.Stat(m.path); os.IsNotExist(err) { log.Warnf("File %s not found", m.path) continue } err := utils.DeleteResourceFromFile( config, m.path, ) if err != nil { log.Errorf("Failed to delete %s: %+v", m.name, err) return err } } return nil } func generateFromGoTemplate(tmplPath, outPath string, data interface{}) error { tmpl := template.Must(template.ParseFiles(tmplPath)) f, err := os.Create(outPath) if err != nil { return err } err = tmpl.Execute(f, data) if err != nil { return err } return nil } var seededRand = rand.New(rand.NewSource(time.Now().UnixNano())) func genRandomString(length int) string { const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" b := make([]byte, length) for i := range b { b[i] = charset[seededRand.Intn(len(charset))] } return string(b) } ================================================ FILE: pkg/kfapp/existing_arrikto/existing_test.go ================================================ package existing_arrikto import ( "crypto/tls" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "log" "os" "sigs.k8s.io/controller-runtime/pkg/client/fake" "testing" ) func TestGenerateCert(t *testing.T) { cases := []struct { name string addr string expectError bool }{ { name: "ip", addr: "10.0.93.8", expectError: false, }, { name: "dns missing scheme", addr: "customdnsdomain.com", expectError: false, }, { name: "invalid ip", addr: "451.4.4", expectError: true, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { certPEM, keyPEM, err := generateCert(c.addr) if err != nil { if !c.expectError { t.Fatalf("Unexpected error occured: %+v", err) } else { return } } cert, err := tls.X509KeyPair(certPEM, keyPEM) if err != nil { log.Fatalf("Unexpected error while loading keypair: %+v", cert) } }) } } func TestGetEndpoints(t *testing.T) { cases := []struct { name string kubeflowEndpoint string oidcEndpoint string expectedKubeflowEndpoint string expectedOIDCEndpoint string expectError bool }{ { name: "ip", kubeflowEndpoint: "https://172.56.12.125", expectedKubeflowEndpoint: "https://172.56.12.125", expectedOIDCEndpoint: "https://172.56.12.125:5556/dex", expectError: false, }, { name: "hostname", kubeflowEndpoint: "https://example.com", expectedKubeflowEndpoint: "https://example.com", expectedOIDCEndpoint: "https://example.com:5556/dex", expectError: false, }, { name: "ip without scheme", kubeflowEndpoint: "172.56.12.125", expectError: true, }, { name: "hostname without scheme", kubeflowEndpoint: "example.com", expectError: true, }, { name: "predetermined", kubeflowEndpoint: "https://172.56.12.125", oidcEndpoint: "https://172.56.12.125:5556/dex", expectedKubeflowEndpoint: "https://172.56.12.125", expectedOIDCEndpoint: "https://172.56.12.125:5556/dex", expectError: false, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { os.Setenv(KUBEFLOW_ENDPOINT, c.kubeflowEndpoint) os.Setenv(OIDC_ENDPOINT, c.oidcEndpoint) kubeflowEndpoint, oidcEndpoint, err := getEndpoints(nil) if err != nil { if !c.expectError { t.Fatalf("Unexpected error occured: %+v", err) } else { return } } if kubeflowEndpoint != c.expectedKubeflowEndpoint { t.Fatalf("Wrong Kubeflow Endpoint. Got %s, expected %s.", kubeflowEndpoint, c.expectedKubeflowEndpoint) } if oidcEndpoint != c.expectedOIDCEndpoint { t.Fatalf("Wrong Kubeflow Endpoint. Got %s, expected %s.", oidcEndpoint, c.expectedOIDCEndpoint) } }) } } func TestGetLBAddress(t *testing.T) { cases := []struct { name string lbIngresses []corev1.LoadBalancerIngress expectedAddr string expectError bool }{ { name: "ip", lbIngresses: []corev1.LoadBalancerIngress{ { IP: "172.56.12.125", Hostname: "", }, }, expectedAddr: "172.56.12.125", expectError: false, }, { name: "hostname", lbIngresses: []corev1.LoadBalancerIngress{ { IP: "", Hostname: "mydomain.com", }, }, expectedAddr: "mydomain.com", expectError: false, }, { name: "ip and hostname", lbIngresses: []corev1.LoadBalancerIngress{ { IP: "172.56.12.125", Hostname: "mydomain.com", }, }, expectedAddr: "mydomain.com", expectError: false, }, { name: "multiple ingresses", lbIngresses: []corev1.LoadBalancerIngress{ { IP: "172.56.12.125", Hostname: "mydomain.com", }, { IP: "163.15.42.78", Hostname: "otherdomain.com", }, }, expectedAddr: "mydomain.com", expectError: false, }, { name: "empty", lbIngresses: []corev1.LoadBalancerIngress{ { IP: "", Hostname: "", }, }, expectError: true, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { lbService := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "istio-ingressgateway", Namespace: "istio-system", }, Status: corev1.ServiceStatus{ LoadBalancer: corev1.LoadBalancerStatus{ Ingress: c.lbIngresses, }, }, } kubeclient := fake.NewFakeClient(lbService) addr, err := getLBAddress(kubeclient) if err != nil { if !c.expectError { t.Fatalf("Unexpected error occured: %+v", err) } else { return } } if addr != c.expectedAddr { t.Fatalf("Wrong address. Got %s, expected %s", addr, c.expectedAddr) } }) } } ================================================ FILE: pkg/kfapp/gcp/fake/fake.go ================================================ // package fake provides a fake implementation of the GCP Plugin package fake import ( kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "golang.org/x/oauth2" ) type FakeGcp struct { ts oauth2.TokenSource } func (g *FakeGcp) Apply(resources kftypes.ResourceEnum) error { return nil } func (g *FakeGcp) Delete(resources kftypes.ResourceEnum) error { return nil } func (g *FakeGcp) Dump(resources kftypes.ResourceEnum) error { return nil } func (g *FakeGcp) Generate(resources kftypes.ResourceEnum) error { return nil } func (g *FakeGcp) Init(resources kftypes.ResourceEnum) error { return nil } func (g *FakeGcp) SetTokenSource(s oauth2.TokenSource) error { g.ts = s return nil } ================================================ FILE: pkg/kfapp/gcp/gcp.go ================================================ /* 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. */ package gcp import ( "encoding/base64" "fmt" "io" "io/ioutil" "math/rand" "net/http" "os" "os/exec" "path" "path/filepath" "strconv" "strings" "time" "github.com/cenkalti/backoff" mapset "github.com/deckarep/golang-set" "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/kfconfig/gcpplugin" "github.com/kubeflow/kfctl/v3/pkg/utils" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "golang.org/x/crypto/bcrypt" "golang.org/x/net/context" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/deploymentmanager/v2" "google.golang.org/api/googleapi" "google.golang.org/api/iam/v1" "google.golang.org/api/servicemanagement/v1" "google.golang.org/api/serviceusage/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/client-go/discovery" "k8s.io/client-go/discovery/cached/memory" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" restv2 "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) // TODO: golint complains that we should not use all capital var name. const ( GCP_CONFIG = "gcp_config" CONFIG_FILE = "cluster-kubeflow.yaml" STORAGE_FILE = "storage-kubeflow.yaml" NETWORK_FILE = "network.yaml" GCFS_FILE = "gcfs.yaml" ADMIN_SECRET_NAME = "admin-gcp-sa" USER_SECRET_NAME = "user-gcp-sa" KUBEFLOW_OAUTH = "kubeflow-oauth" IMPORTS = "imports" PATH = "path" CLIENT_ID = "CLIENT_ID" CLIENT_SECRET = "CLIENT_SECRET" BASIC_AUTH_SECRET = "kubeflow-login" KUBECONFIG_FORMAT = "gke_{project}_{zone}_{cluster}" // The default path in kubeflow/kubeflow to the deployment manager configs. // TODO(jlewi): This is only provided for legacy reasons. In 0.7 the path should be set explicitly // in the KfDef spec. DEFAULT_DM_PATH = "deployment/gke/deployment_manager_configs" // Plugin parameter constants GcpPluginName = "KfGcpPlugin" GcpAccessTokenName = "accessToken" BasicAuthPasswordSecretName = "password" // The PodDefault in default namespace PodDefaultName = "add-gcp-secret" DefaultIstioNamespace = "istio-system" ) // Gcp implements KfApp Interface // It includes the KsApp along with additional Gcp types // TODO(jlewi): Why doesn't Gcp store GcpArgs as opposed to duplicating the options? type Gcp struct { kfDef *kfconfig.KfConfig client *http.Client tokenSource oauth2.TokenSource // Function to get the GcpAccount. // Support injection for testing. gcpAccountGetter func() (string, error) gcpProjectGetter func() (string, error) gcpZoneGetter func() (string, error) runGetCredentials bool } type Setter interface { SetTokenSource(s oauth2.TokenSource) error // SetRunGetCredentials controls whether or not to run get credentials SetRunGetCredentials(v bool) } func (gcp *Gcp) SetTokenSource(s oauth2.TokenSource) error { gcp.tokenSource = s // Reset client to force pick up the new token gcp.client = nil return nil } func (gcp *Gcp) SetRunGetCredentials(v bool) { gcp.runGetCredentials = v } type dmOperationEntry struct { operationName string // create or update dmName action string } // GetPlatform returns the gcp kfapp. It's called by coordinator.GetPlatform func GetPlatform(kfdef *kfconfig.KfConfig) (kftypesv3.Platform, error) { _gcp := &Gcp{ kfDef: kfdef, gcpAccountGetter: GetGcloudDefaultAccount, gcpProjectGetter: GetGcloudDefaultProject, gcpZoneGetter: GetGcloudDefaultZone, // Default to true for the CLI. runGetCredentials: true, } return _gcp, nil } // GetPluginSpec gets the plugin spec. func (gcp *Gcp) GetPluginSpec() (*gcpplugin.GcpPluginSpec, error) { // Not passing a pointer interface is a common cause of deserialization problems pluginSpec := &gcpplugin.GcpPluginSpec{} err := gcp.kfDef.GetPluginSpec(GcpPluginName, pluginSpec) return pluginSpec, err } // initGcpClient initializes the clients to talk to GCP. func (gcp *Gcp) initGcpClient() error { if gcp.client != nil { log.Infof("GCP client already configured") return nil } ctx := context.Background() if gcp.tokenSource == nil { // Defensive Programming. // If we try to create a DefaultTokenSource when an AccessToken is provided // Something has gone wrong. So we guard against that. // If accessToken is provided gcp.TokenSource should be set and we should use // that. if _, err := gcp.kfDef.GetSecret(GcpAccessTokenName); !kfconfig.IsSecretNotFound(err) { return errors.WithStack(fmt.Errorf("Gcp.tokenSource is nil and secret %v is in KfDef; Gcp.tokenSource must be set explicitly; using a default token source is not allowed in this case", GcpAccessTokenName)) } log.Infof("Creating default token source") tokenSource, err := google.DefaultTokenSource(ctx, iam.CloudPlatformScope) if err != nil { return errors.Wrap(err, "initGcpClient failed to create default token source") } gcp.tokenSource = tokenSource } else { log.Infof("Using current token source") } log.Infof("Creating GCP client.") gcp.client = oauth2.NewClient(ctx, gcp.tokenSource) return nil } func newDefaultBackoff() *backoff.ExponentialBackOff { b := backoff.NewExponentialBackOff() b.InitialInterval = 3 * time.Second b.MaxInterval = 30 * time.Second return b } func getSA(name string, nameSuffix string, project string) string { return fmt.Sprintf("%v-%v@%v.iam.gserviceaccount.com", name, nameSuffix, project) } // TODO(jlewi): We should be able to get rid of this method because it was only used // for ksonnet. func (gcp *Gcp) GetK8sConfig() (*rest.Config, *clientcmdapi.Config) { // TODO(jlewi): Should we unify the code by just setting ts and then calling // ts.Tpken to get a token? accessToken, _ := gcp.kfDef.GetSecret(GcpAccessTokenName) if accessToken == "" { return nil, nil } ctx := context.Background() // TODO(jlewi): Should we fix this so we can build a cluster config which takes // a TokenSource which can then be pointed at either the DefaultTokenSource // or the refreshable token source? restConfig, err := utils.BuildClusterConfig(ctx, accessToken, gcp.kfDef.Spec.Project, gcp.kfDef.Spec.Zone, gcp.kfDef.Name) if err != nil { return nil, nil } apiConfig := utils.BuildClientCmdAPI(restConfig, accessToken) return restConfig, apiConfig } // GetGcloudDefaultProject try to get the default project. func GetGcloudDefaultProject() (string, error) { output, err := exec.Command("gcloud", "config", "get-value", "project").Output() if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not call 'gcloud config get-value project': %v", err), } } return strings.TrimSpace(string(output)), nil } // GetGcloudDefaultZone try to get the default zone. func GetGcloudDefaultZone() (string, error) { output, err := exec.Command("gcloud", "config", "get-value", "compute/zone").Output() if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not call 'gcloud config get-value compute/zone': %v", err), } } return strings.TrimSpace(string(output)), nil } // GetGcloudDefaultAccount try to get the default account. func GetGcloudDefaultAccount() (string, error) { output, err := exec.Command("gcloud", "config", "get-value", "account").Output() if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not call 'gcloud config get-value account': %v", err), } } return strings.TrimSpace(string(output)), nil } // Simple deploymentmanager.TargetConfiguration factory method. This method assumes imported paths // are all within the same filesystem. From gcloud CLI source codes it appears URL is a possible // option. We might need to update this method or find a way to work with Python source code from // gcloud. func generateTarget(configPath string) (*deploymentmanager.TargetConfiguration, error) { if !filepath.IsAbs(configPath) { if p, err := filepath.Abs(configPath); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Getting absolute path error: %v", err), } } else { configPath = p } } log.Infof("Reading config file: %v", configPath) configBuf, bufErr := ioutil.ReadFile(configPath) if bufErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Reading config file error: %v", bufErr), } } targetConfig := &deploymentmanager.TargetConfiguration{ Config: &deploymentmanager.ConfigFile{ Content: string(configBuf), }, } var config map[string]interface{} if err := yaml.Unmarshal(configBuf, &config); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Unable to read YAML: %v", err), } } if _, ok := config[IMPORTS]; !ok { return targetConfig, nil } entries := config[IMPORTS].([]interface{}) dirName := filepath.Dir(configPath) for _, entry := range entries { entryMap := entry.(map[string]interface{}) if _, ok := entryMap[PATH]; !ok { continue } importPath := entryMap[PATH].(string) if !filepath.IsAbs(importPath) { importPath = path.Join(dirName, importPath) } log.Infof("Reading import file: %v", importPath) if buf, err := ioutil.ReadFile(importPath); err == nil { targetConfig.Imports = append(targetConfig.Imports, &deploymentmanager.ImportFile{ Name: entryMap[PATH].(string), Content: string(buf), }) } else { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("error reading import file: %v", err), } } } return targetConfig, nil } func (gcp *Gcp) getK8sClientset(ctx context.Context) (*clientset.Clientset, error) { cluster, err := utils.GetClusterInfo(ctx, gcp.kfDef.Spec.Project, gcp.kfDef.Spec.Zone, gcp.kfDef.Name, gcp.tokenSource) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("get Cluster error: %v", err), } } config, err := utils.BuildConfigFromClusterInfo(ctx, cluster, gcp.tokenSource) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("build ClientConfig error: %v", err), } } if cli, err := clientset.NewForConfig(config); err == nil { return cli, nil } else { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("create new ClientConfig error: %v", err), } } } func blockingWait(project string, deploymentmanagerService *deploymentmanager.Service, dmOperationEntries []*dmOperationEntry) error { ctx := context.Background() // Explicitly copy string to avoid memory leak. p := "" + project return backoff.Retry(func() error { for _, dmEntry := range dmOperationEntries { op, err := deploymentmanagerService.Operations.Get(p, dmEntry.operationName).Context(ctx).Do() if err != nil { // Retry here as there's a chance to get error for newly created DM operation. log.Errorf("%v error: %v", dmEntry.action, err) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("%v error: %v", dmEntry.action, err), } } if op.Error != nil { for _, e := range op.Error.Errors { log.Errorf("%v error: %+v", dmEntry.action, e) } } if op.Status != "DONE" { log.Infof("%v status: %v (op = %v)", dmEntry.action, op.Status, op.Name) return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("%v did not succeed; status: %v (op = %v)", dmEntry.action, op.Status, op.Name), } } if op.HttpErrorStatusCode > 0 { return backoff.Permanent(&kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("%v error(%v): %v", dmEntry.action, op.HttpErrorStatusCode, op.HttpErrorMessage), }) } log.Infof("%v is finished: %v", dmEntry.action, op.Status) } return nil }, newDefaultBackoff()) } func (gcp *Gcp) updateDeployment(deploymentmanagerService *deploymentmanager.Service, deployment string, yamlfile string) (*dmOperationEntry, error) { appDir := gcp.kfDef.Spec.AppDir gcpConfigDir := path.Join(appDir, GCP_CONFIG) ctx := context.Background() filePath := filepath.Join(gcpConfigDir, yamlfile) dp := &deploymentmanager.Deployment{ Name: deployment, Labels: []*deploymentmanager.DeploymentLabelEntry{}, } // Add the labels for k, v := range gcp.kfDef.Labels { dp.Labels = append(dp.Labels, &deploymentmanager.DeploymentLabelEntry{ Key: k, Value: v, }) } if target, targetErr := generateTarget(filePath); targetErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: targetErr.Error(), } } else { dp.Target = target } project := gcp.kfDef.Spec.Project resp, err := deploymentmanagerService.Deployments.Get(project, deployment).Context(ctx).Do() if err == nil { dp.Fingerprint = resp.Fingerprint opName := resp.Operation.Name if resp.Operation.Status == "DONE" { log.Infof("Updating deployment %v", deployment) op, updateErr := deploymentmanagerService.Deployments.Update(project, deployment, dp).Context(ctx).Do() if updateErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.UNKNOWN), Message: fmt.Sprintf("Update deployment error: %v", updateErr), } } opName = op.Name } else { log.Infof("Wait running deployment %v to finish; operation name: %v.", deployment, opName) } return &dmOperationEntry{ operationName: opName, action: "Updating " + deployment, }, nil } else { log.Infof("Creating deployment %v", deployment) op, insertErr := deploymentmanagerService.Deployments.Insert(project, dp).Context(ctx).Do() if insertErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Insert deployment error: %v", insertErr), } } return &dmOperationEntry{ operationName: op.Name, action: "Creating " + deployment, }, nil } } func createNamespace(k8sClientset *clientset.Clientset, namespace string) error { log.Infof("Creating namespace: %v", namespace) _, err := k8sClientset.CoreV1().Namespaces().Get(namespace, metav1.GetOptions{}) if err == nil { log.Infof("Namespace already exists...") return nil } log.Infof("Get namespace error: %v", err) _, err = k8sClientset.CoreV1().Namespaces().Create( &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, }, }, ) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } func bindAdmin(k8sClientset *clientset.Clientset, user string) error { log.Infof("Binding admin role for %v ...", user) defaultAdmin := "default-admin" _, err := k8sClientset.RbacV1().ClusterRoleBindings().Get(defaultAdmin, metav1.GetOptions{ TypeMeta: metav1.TypeMeta{ APIVersion: "rbac.authorization.k8s.io/v1beta1", Kind: "ClusterRoleBinding", }, }) binding := &rbacv1.ClusterRoleBinding{ TypeMeta: metav1.TypeMeta{ APIVersion: "rbac.authorization.k8s.io/v1beta1", Kind: "ClusterRoleBinding", }, ObjectMeta: metav1.ObjectMeta{ Name: "default-admin", }, RoleRef: rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", Name: "cluster-admin", }, Subjects: []rbacv1.Subject{ { Kind: rbacv1.UserKind, Name: user, }, }, } if err == nil { log.Infof("Updating default-admin...") _, err = k8sClientset.RbacV1().ClusterRoleBindings().Update(binding) } else { log.Infof("Default-admin not found, creating...") _, err = k8sClientset.RbacV1().ClusterRoleBindings().Create(binding) } if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } func (gcp *Gcp) ConfigK8s() error { ctx := context.Background() k8sClientset, err := gcp.getK8sClientset(ctx) if err != nil { return err } if err = createNamespace(k8sClientset, gcp.kfDef.Namespace); err != nil { return err } if err = createNamespace(k8sClientset, gcp.getIstioNamespace()); err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("cannot create istio namespace")) } // For deploy app, request will use service account credential instead of user credential. bindAccount := gcp.kfDef.Spec.Email pluginSpec, err := gcp.GetPluginSpec() if err != nil { return err } if pluginSpec.SAClientId != "" { log.Infof("Granting service account K8s permission.") bindAccount = pluginSpec.SAClientId } if err = bindAdmin(k8sClientset, bindAccount); err != nil { return err } return nil } // Add a conveniently named context to KUBECONFIG. func (gcp *Gcp) AddNamedContext() error { name := strings.Replace(KUBECONFIG_FORMAT, "{project}", gcp.kfDef.Spec.Project, 1) name = strings.Replace(name, "{zone}", gcp.kfDef.Spec.Zone, 1) name = strings.Replace(name, "{cluster}", gcp.kfDef.Name, 1) log.Infof("KUBECONFIG name is %v", name) buf, err := ioutil.ReadFile(kftypesv3.KubeConfigPath()) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Reading KUBECONFIG error: %v", err), } } var config map[string]interface{} if err = yaml.Unmarshal(buf, &config); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Unmarshaling KUBECONFIG error: %v", err), } } configNameChecker := func(config map[string]interface{}, entryName string, name string) error { e, ok := config[entryName] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Not able to find %v in KUBECONFIG", entryName), } } entries := e.([]interface{}) for _, entry := range entries { en := entry.(map[string]interface{}) if mm, ok := en["name"]; ok { n := mm.(string) if n == name { return nil } } else { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Not able to find name in the entry", } } } return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Not able to find %v from %v in KUBECONFIG", name, entryName), } } if err = configNameChecker(config, "clusters", name); err != nil { return err } if err = configNameChecker(config, "users", name); err != nil { return err } if err = configNameChecker(config, "contexts", name); err != nil { return err } e, ok := config["contexts"] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Not able to find contexts in KUBECONFIG", } } contexts := e.([]interface{}) context := make(map[string]interface{}) context["name"] = gcp.kfDef.Name context["context"] = map[string]string{ "cluster": name, "user": name, "namespace": gcp.kfDef.Namespace, } for idx, ctx := range contexts { c := ctx.(map[string]interface{}) if c["name"] == gcp.kfDef.Name { // Remove the entry to override. contexts = append(contexts[:idx], contexts[idx+1:]...) break } } contexts = append(contexts, context) config["contexts"] = contexts config["current-context"] = gcp.kfDef.Name buf, err = yaml.Marshal(config) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when marshaling KUBECONFIG: %v", err), } } if err = ioutil.WriteFile(kftypesv3.KubeConfigPath(), buf, 0644); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when writing KUBECONFIG: %v", err), } } log.Infof("KUBECONFIG context %v is created and currently using", gcp.kfDef.Name) return nil } func (gcp *Gcp) updateDM(resources kftypesv3.ResourceEnum) error { ctx := context.Background() gcpClient := oauth2.NewClient(ctx, gcp.tokenSource) dmOperationEntries := []*dmOperationEntry{} deploymentmanagerService, err := deploymentmanager.New(gcp.client) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error creating deploymentmanagerService: %v", err), } } // DM entries are optional, defined in kfdef config. We only make DM changes when DM config was generated during kfctl build if _, storageStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, STORAGE_FILE)); !os.IsNotExist(storageStatErr) { if storageStatErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error creating deploymentmanager storage: %v", storageStatErr), } } storageEntry, err := gcp.updateDeployment(deploymentmanagerService, gcp.kfDef.Name+"-storage", STORAGE_FILE) if err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("could not update %v", STORAGE_FILE)) } dmOperationEntries = append(dmOperationEntries, storageEntry) } if _, mainStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, CONFIG_FILE)); !os.IsNotExist(mainStatErr) { if mainStatErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error creating deploymentmanager Service: %v", mainStatErr), } } dmEntry, err := gcp.updateDeployment(deploymentmanagerService, gcp.kfDef.Name, CONFIG_FILE) if err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("could not update %v", CONFIG_FILE)) } dmOperationEntries = append(dmOperationEntries, dmEntry) } if _, networkStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, NETWORK_FILE)); !os.IsNotExist(networkStatErr) { if networkStatErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error creating deploymentmanager Network: %v", networkStatErr), } } networkEntry, err := gcp.updateDeployment(deploymentmanagerService, gcp.kfDef.Name+"-network", NETWORK_FILE) if err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("could not update %v", NETWORK_FILE)) } dmOperationEntries = append(dmOperationEntries, networkEntry) } if _, gcfsStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, GCFS_FILE)); !os.IsNotExist(gcfsStatErr) { if gcfsStatErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error creating deploymentmanager gcfs: %v", gcfsStatErr), } } gcfsEntry, err := gcp.updateDeployment(deploymentmanagerService, gcp.kfDef.Name+"-gcfs", GCFS_FILE) if err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("could not update %v", GCFS_FILE)) } dmOperationEntries = append(dmOperationEntries, gcfsEntry) } if err = blockingWait(gcp.kfDef.Spec.Project, deploymentmanagerService, dmOperationEntries); err != nil { return kfapis.NewKfErrorWithMessage(err, "could not update deployment manager entries") } // IAM changes are optional, defined in kfdef config. We only make IAM changes when IAM config was generated during kfctl build if _, iamStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, "iam_bindings.yaml")); !os.IsNotExist(iamStatErr) { if iamStatErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error loading IAM template: %v", iamStatErr), } } exp := backoff.NewExponentialBackOff() exp.InitialInterval = 1 * time.Second exp.MaxInterval = 3 * time.Second exp.MaxElapsedTime = time.Minute exp.Reset() err = backoff.Retry(func() error { // Get current policy policy, policyErr := utils.GetIamPolicy(gcp.kfDef.Spec.Project, gcpClient) if policyErr != nil { return kfapis.NewKfErrorWithMessage(policyErr, "GetIamPolicy error") } utils.ClearIamPolicy(policy, gcp.kfDef.Name, gcp.kfDef.Spec.Project) if err := utils.SetIamPolicy(gcp.kfDef.Spec.Project, policy, gcpClient); err != nil { return kfapis.NewKfErrorWithMessage(err, "Set Cleared IamPolicy error: %v") } return nil }, exp) if err != nil { return err } appDir := gcp.kfDef.Spec.AppDir gcpConfigDir := path.Join(appDir, GCP_CONFIG) iamPolicy, iamPolicyErr := utils.ReadIamBindingsYAML( filepath.Join(gcpConfigDir, "iam_bindings.yaml")) if iamPolicyErr != nil { return &kfapis.KfError{ Code: iamPolicyErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("Read IAM policy YAML error: %v", iamPolicyErr.(*kfapis.KfError).Message), } } exp.Reset() err = backoff.Retry(func() error { // Need to read policy again as latest Etag changed. newPolicy, policyErr := utils.GetIamPolicy(gcp.kfDef.Spec.Project, gcpClient) if policyErr != nil { return &kfapis.KfError{ Code: policyErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("GetIamPolicy error: %v", policyErr.(*kfapis.KfError).Message), } } utils.RewriteIamPolicy(newPolicy, iamPolicy) if err := utils.SetIamPolicy(gcp.kfDef.Spec.Project, newPolicy, gcpClient); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Set New IamPolicy error: %v", err.(*kfapis.KfError).Message), } } return nil }, exp) if err != nil { return err } } if err := gcp.ConfigK8s(); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Configure K8s is failed: %v", err.(*kfapis.KfError).Message), } } if gcp.runGetCredentials { log.Infof("Running get-credentials to build .kubeconfig") credCmd := exec.Command("gcloud", "container", "clusters", "get-credentials", gcp.kfDef.Name, "--zone="+gcp.kfDef.Spec.Zone, "--project="+gcp.kfDef.Spec.Project) credCmd.Stdout = os.Stdout credCmd.Stderr = os.Stderr log.Infof("Running get-credentials %v --zone=%v --project=%v ...", gcp.kfDef.Name, gcp.kfDef.Spec.Zone, gcp.kfDef.Spec.Project) if err := credCmd.Run(); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when running gcloud container clusters get-credentials: %v", err), } } if _, err := os.Stat(kftypesv3.KubeConfigPath()); !os.IsNotExist(err) { gcp.AddNamedContext() } } else { log.Debugf("Not running gcloud get-credentials") } return nil } // Apply applies the gcp kfapp. // Remind: Need to be thread-safe: this entry is share among kfctl and deploy app func (gcp *Gcp) Apply(resources kftypesv3.ResourceEnum) error { if err := gcp.initGcpClient(); err != nil { log.Errorf("There was a problem initializing the GCP client; %v", err) return errors.WithMessagef(err, "Gcp.Apply Could not initatie a GCP client") } p, err := gcp.GetPluginSpec() if err != nil { return err } if err = p.IsValid(); err != nil { log.Errorf("GcpPluginSpec isn't valid; error %v", err) return err } // Update deployment manager updateDMErr := gcp.updateDM(resources) if updateDMErr != nil { return &kfapis.KfError{ Code: updateDMErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("gcp apply could not update deployment manager: %v", updateDMErr.(*kfapis.KfError).Message), } } // Insert secrets into the cluster secretsErr := gcp.createSecrets() if secretsErr != nil { return &kfapis.KfError{ Code: secretsErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("gcp apply could not create secrets: %v", secretsErr.(*kfapis.KfError).Message), } } gcpAdminSa := fmt.Sprintf("%v-admin@%v.iam.gserviceaccount.com", gcp.kfDef.Name, gcp.kfDef.Spec.Project) gcpUserSa := fmt.Sprintf("%v-user@%v.iam.gserviceaccount.com", gcp.kfDef.Name, gcp.kfDef.Spec.Project) if err = gcp.allowAdmineditUserSA(gcpAdminSa, gcpUserSa); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Fail to setup workload identity:: %v", err.(*kfapis.KfError).Message), } } // Create the role binding for k8s service account kubeflowWorkloadIdentityMapping := map[string]string{ "kf-admin": gcpAdminSa, "kf-user": gcpUserSa, } if err = gcp.setupWorkloadIdentity(gcp.kfDef.Namespace, kubeflowWorkloadIdentityMapping); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Fail to setup workload identity:: %v", err.(*kfapis.KfError).Message), } } istioWorkloadIdentityMapping := map[string]string{ "kf-admin": gcpAdminSa, } if err = gcp.setupWorkloadIdentity(gcp.getIstioNamespace(), istioWorkloadIdentityMapping); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Fail to setup workload identity:: %v", err.(*kfapis.KfError).Message), } } return nil } // Try to get information for the deployment. If returned, delete it. func deleteDeployment(deploymentmanagerService *deploymentmanager.Service, ctx context.Context, project string, name string) error { _, err := deploymentmanagerService.Deployments.Get(project, name).Context(ctx).Do() if err != nil { e := err.(*googleapi.Error) if e.Code == 404 { // Don't treat not found deployment deletion as error to make kfctl delete idempotent. log.Infof("Deployment %v/%v is not found during deletion.", project, name) return nil } else { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Deployment %v/%v has unexpected error: %v", project, name, err), } } } op, err := deploymentmanagerService.Deployments.Delete(project, name).Context(ctx).Do() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Gcp.Delete is failed for %v/%v: %v", project, name, err), } } deleteEntry := []*dmOperationEntry{&dmOperationEntry{ operationName: op.Name, action: "Deleting " + name, }} if err = blockingWait(project, deploymentmanagerService, deleteEntry); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Gcp.Delete is failed for %v/%v: %v", project, name, err.(*kfapis.KfError).Message), } } return nil } // Delete endpoint service from resources. func (gcp *Gcp) deleteEndpoints(ctx context.Context) error { servicemanagementService, err := servicemanagement.New(gcp.client) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("creating servicemanagement API client error: %v", err), } } log.Infof("Deleting endpoint: %v", gcp.kfDef.Spec.Hostname) services := servicemanagement.NewServicesService(servicemanagementService) op, deleteErr := services.Delete(gcp.kfDef.Spec.Hostname).Context(ctx).Do() if deleteErr != nil { log.Warningf("Endpoint deletion error: %v", deleteErr) nextPage := "" // Use a loop to read multi-page managed services list. for { log.Info("Checking all endpoints...") list := services.List().ProducerProjectId(gcp.kfDef.Spec.Project) if nextPage != "" { list = list.PageToken(nextPage) } listResp, err := list.Do() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("listing managed services error: %v", err), } } for _, s := range listResp.Services { if s.ServiceName == gcp.kfDef.Spec.Hostname { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("issuing endpoint deletion error: %v", deleteErr), } } } // Explicitly copy it to prevent memory leak. nextPage = "" + listResp.NextPageToken if nextPage == "" { break } } // Delete is not successful and we are not able to find endpoint in managed // services, treat it as OK. log.Infof("Endpoint %v deletion is failed but it is not found in managed services, treating it as successful.", gcp.kfDef.Spec.Hostname) return nil } opService := servicemanagement.NewOperationsService(servicemanagementService) opName := "" + op.Name return backoff.Retry(func() error { newOp, retryErr := opService.Get(opName).Context(ctx).Do() if retryErr != nil { log.Errorf("Long running endpoint deletion error: %v", retryErr) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("long running endpoint deletion error: %v", retryErr), } } if newOp.Error != nil { return backoff.Permanent(&kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("long running endpoint deletion error: %v", newOp.Error.Message), }) } if newOp.Done { if newOp.HTTPStatusCode != 200 { return backoff.Permanent(&kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Abnormal response code: %v", newOp.HTTPStatusCode), }) } log.Infof("Endpoint deletion %v is completed: %v", gcp.kfDef.Spec.Hostname, string(newOp.Response)) return nil } log.Infof("Endpoint deletion is running: %v (op = %v)", gcp.kfDef.Spec.Hostname, newOp.Name) opName = newOp.Name return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Endpoint deletion is running..."), } }, newDefaultBackoff()) } func (gcp *Gcp) Delete(resources kftypesv3.ResourceEnum) error { if err := gcp.initGcpClient(); err != nil { log.Errorf("There was a problem initializing the GCP client; %v", err) return errors.WithMessagef(err, "Gcp.gcpInitProject Could not initatie a GCP client") } ctx := context.Background() deploymentmanagerService, err := deploymentmanager.New(gcp.client) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error creating deploymentmanagerService: %v", err), } } // cluster and storage deployments are required to be deleted. network and gcfs deployments are optional. project := gcp.kfDef.Spec.Project deletingDeployments := []string{ gcp.kfDef.Name, } if gcp.kfDef.Spec.DeleteStorage { deletingDeployments = append(deletingDeployments, gcp.kfDef.Name+"-storage") } if _, networkStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, NETWORK_FILE)); !os.IsNotExist(networkStatErr) { deletingDeployments = append(deletingDeployments, gcp.kfDef.Name+"-network") } if _, gcfsStatErr := os.Stat(path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG, GCFS_FILE)); !os.IsNotExist(gcfsStatErr) { deletingDeployments = append(deletingDeployments, gcp.kfDef.Name+"-gcfs") } for _, d := range deletingDeployments { if err = deleteDeployment(deploymentmanagerService, ctx, project, d); err != nil { return err } } policy, err := utils.GetIamPolicy(project, gcp.client) if err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Error when getting IAM policy: %v", err.(*kfapis.KfError).Message), } } saSet := mapset.NewSet( "serviceAccount:"+getSA(gcp.kfDef.Name, "admin", project), "serviceAccount:"+getSA(gcp.kfDef.Name, "user", project), "serviceAccount:"+getSA(gcp.kfDef.Name, "vm", project)) for idx, binding := range policy.Bindings { cleanedMembers := []string{} for _, member := range binding.Members { if saSet.Contains(member) { log.Infof("Removing %v from %v", member, binding.Role) } else { cleanedMembers = append(cleanedMembers, member) } } policy.Bindings[idx].Members = cleanedMembers } if err = utils.SetIamPolicy(project, policy, gcp.client); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Error when cleaning IAM policy: %v", err.(*kfapis.KfError).Message), } } if err = gcp.deleteEndpoints(ctx); err != nil { return err } return nil } func (gcp *Gcp) Dump(resources kftypesv3.ResourceEnum) error { return nil } func (gcp *Gcp) copyFile(source string, dest string) error { from, err := os.Open(source) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot open input for copying: %v", err), } } defer from.Close() to, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE, 0666) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot create dest file %v : %v", dest, err), } } defer to.Close() _, err = io.Copy(to, from) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("copy failed source %v dest %v: %v", source, dest, err), } } return nil } // Helper function to generate account field. func (gcp *Gcp) getAccount() string { iapAcct := "serviceAccount:" + gcp.kfDef.Spec.Email if !strings.Contains(gcp.kfDef.Spec.Email, "gserviceaccount.com") { iapAcct = "user:" + gcp.kfDef.Spec.Email } return iapAcct } // Write IAM binding rules based on GCP app config. func (gcp *Gcp) writeIamBindingsFile(src string, dest string) error { buf, err := ioutil.ReadFile(src) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when reading template %v: %v", src, err), } } var data map[string]interface{} if err = yaml.Unmarshal(buf, &data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when unmarshaling template %v: %v", src, err), } } e, ok := data["bindings"] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Invalid IAM bindings format: not able to find `bindings` entry.", } } roles := map[string]string{ "set-kubeflow-admin-service-account": "serviceAccount:" + getSA(gcp.kfDef.Name, "admin", gcp.kfDef.Spec.Project), "set-kubeflow-user-service-account": "serviceAccount:" + getSA(gcp.kfDef.Name, "user", gcp.kfDef.Spec.Project), "set-kubeflow-vm-service-account": "serviceAccount:" + getSA(gcp.kfDef.Name, "vm", gcp.kfDef.Spec.Project), "set-kubeflow-iap-account": gcp.getAccount(), } bindings := e.([]interface{}) for idx, b := range bindings { binding := b.(map[string]interface{}) if mem, ok := binding["members"]; ok { members := mem.([]interface{}) var newMembers []string for _, m := range members { member := m.(string) if acct, ok := roles[member]; ok { newMembers = append(newMembers, acct) } else { newMembers = append(newMembers, member) } } binding["members"] = newMembers bindings[idx] = binding } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: "Invalid IAM bindings format: not able to find `members` entry.", } } } data["bindings"] = bindings if buf, err = yaml.Marshal(data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when marshaling IAM bindings: %v", err), } } if err = ioutil.WriteFile(dest, buf, 0644); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when writing IAM bindings: %v", err), } } return nil } // Replace placeholders and write to cluster-kubeflow.yaml // // TODO(jlewi): Is it possible to deserialize YAML to a partially known struct? func (gcp *Gcp) writeClusterConfig(src string, dest string, gcpPluginSpec gcpplugin.GcpPluginSpec) error { buf, err := ioutil.ReadFile(src) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when reading template %v: %v", src, err), } } var data map[string]interface{} if err = yaml.Unmarshal(buf, &data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when unmarshaling template %v: %v", src, err), } } res, ok := data["resources"] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Invalid cluster config - not able to find resources entry.", } } resources := res.([]interface{}) for idx, re := range resources { resource := re.(map[string]interface{}) var properties map[string]interface{} if props, ok := resource["properties"]; ok { properties = props.(map[string]interface{}) } else { properties = make(map[string]interface{}) } properties["gkeApiVersion"] = kftypesv3.DefaultGkeApiVer properties["zone"] = gcp.kfDef.Spec.Zone properties["users"] = []string{ gcp.getAccount(), } properties["ipName"] = gcp.kfDef.Spec.IpName resource["properties"] = properties properties["enable-workload-identity"] = true properties["identity-namespace"] = gcp.kfDef.Spec.Project + ".svc.id.goog" resources[idx] = resource } data["resources"] = resources if buf, err = yaml.Marshal(data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when marshaling for %v: %v", dest, err), } } if err = ioutil.WriteFile(dest, buf, 0644); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when writing to %v: %v", dest, err), } } return nil } // Replace placeholders and write to storage-kubeflow.yaml func (gcp *Gcp) writeStorageConfig(src string, dest string) error { buf, err := ioutil.ReadFile(src) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when reading storage-kubeflow template: %v", err), } } var data map[string]interface{} if err = yaml.Unmarshal(buf, &data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when unmarshaling template %v: %v", src, err), } } res, ok := data["resources"] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Invalid storage config - not able to find resources entry.", } } resources := res.([]interface{}) for idx, re := range resources { resource := re.(map[string]interface{}) var properties map[string]interface{} if props, ok := resource["properties"]; ok { properties = props.(map[string]interface{}) } else { properties = make(map[string]interface{}) } properties["zone"] = gcp.kfDef.Spec.Zone properties["createPipelinePersistentStorage"] = true resource["properties"] = properties resources[idx] = resource } data["resources"] = resources if buf, err = yaml.Marshal(data); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when marshaling for %v: %v", dest, err), } } if err = ioutil.WriteFile(dest, buf, 0644); err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Error when writing to %v: %v", dest, err), } } return nil } func (gcp *Gcp) generateDMConfigs() error { pluginSpec, err := gcp.GetPluginSpec() if err != nil { return nil } // Skip DM config build if not specified in kfdef if pluginSpec.DeploymentManagerConfig == nil { return nil } appDir := gcp.kfDef.Spec.AppDir gcpConfigDir := path.Join(appDir, GCP_CONFIG) gcpConfigDirErr := os.MkdirAll(gcpConfigDir, os.ModePerm) if gcpConfigDirErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot create directory %v using appdir %v", gcpConfigDirErr, appDir), } } repo, foundRepo := gcp.kfDef.GetRepoCache(pluginSpec.DeploymentManagerConfig.RepoRef.Name) if !foundRepo { err := fmt.Errorf("Repo %v not found in KfDef.Status.Caches", pluginSpec.DeploymentManagerConfig.RepoRef.Name) log.Errorf("%v", err) return errors.WithStack(err) } sourceDir := path.Join(repo.LocalPath, pluginSpec.DeploymentManagerConfig.RepoRef.Path) files := []string{"cluster.jinja", "cluster.jinja.schema", "storage.jinja", "storage.jinja.schema"} for _, file := range files { sourceFile := filepath.Join(sourceDir, file) destFile := filepath.Join(gcpConfigDir, file) copyErr := gcp.copyFile(sourceFile, destFile) if copyErr != nil { return &kfapis.KfError{ Code: copyErr.(*kfapis.KfError).Code, Message: fmt.Sprintf("could not copy %v to %v using repo local path %v: %v", sourceFile, destFile, repo.LocalPath, copyErr.(*kfapis.KfError).Message), } } } // Reading from templates and write to gcp_config directory with content had placeholders // replaced. from := filepath.Join(sourceDir, "iam_bindings_template.yaml") to := filepath.Join(gcpConfigDir, "iam_bindings.yaml") if err := gcp.writeIamBindingsFile(from, to); err != nil { return err } from = filepath.Join(sourceDir, CONFIG_FILE) to = filepath.Join(gcpConfigDir, CONFIG_FILE) if err := gcp.writeClusterConfig(from, to, *pluginSpec); err != nil { return err } if pluginSpec.GetCreatePipelinePersistentStorage() { log.Infof("Configuring pipelines persistent storage") from = filepath.Join(sourceDir, STORAGE_FILE) to = filepath.Join(gcpConfigDir, STORAGE_FILE) if err := gcp.writeStorageConfig(from, to); err != nil { return err } } return nil } // createOrUpdateSecret creates or updates the existing secret. func createOrUpdateSecret(client *clientset.Clientset, secret *v1.Secret) error { // Try creating the secret _, err := client.CoreV1().Secrets(secret.Namespace).Create(secret) if err != nil { if k8serrors.IsAlreadyExists(err) { _, err = client.CoreV1().Secrets(secret.Namespace).Update(secret) if err != nil { log.Errorf("Error trying to update secret %v.%v; error %v", secret.Namespace, secret.Name, err) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } else { log.Errorf("Error trying to create secret %v.%v; error %v", secret.Namespace, secret.Name, err) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } return nil } // TODO(jlewi): We should replace all calls to this method with createOrUpdateSecret func insertSecret(client *clientset.Clientset, secretName string, namespace string, data map[string][]byte) error { secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, Namespace: namespace, }, Data: data, } _, err := client.CoreV1().Secrets(namespace).Create(secret) if err == nil { return nil } else { if k8serrors.IsAlreadyExists(err) { log.Infof("Secret %v.%v already exists", namespace, secretName) return nil } return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } // Create key for service account and write to GCP as secret. func (gcp *Gcp) createGcpServiceAcctSecret(ctx context.Context, client *clientset.Clientset, email string, secretName string, namespace string) error { _, err := client.CoreV1().Secrets(namespace).Get(secretName, metav1.GetOptions{}) if err == nil { log.Infof("Secret for %v already exists ...", secretName) return nil } log.Infof("Secret for %v not found, creating ...", secretName) oClient := oauth2.NewClient(ctx, gcp.tokenSource) iamService, err := iam.New(oClient) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Get Oauth Client error: %v", err), } } name := fmt.Sprintf("projects/%v/serviceAccounts/%v", gcp.kfDef.Spec.Project, email) req := &iam.CreateServiceAccountKeyRequest{ KeyAlgorithm: "KEY_ALG_RSA_2048", PrivateKeyType: "TYPE_GOOGLE_CREDENTIALS_FILE", } saKey, err := iamService.Projects.ServiceAccounts.Keys.Create(name, req).Context(ctx).Do() if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Service account key creation error: %v", err), } } privateKeyData, err := base64.StdEncoding.DecodeString(saKey.PrivateKeyData) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("PrivateKeyData decoding error: %v", err), } } return insertSecret(client, secretName, namespace, map[string][]byte{ secretName + ".json": privateKeyData, }) } // User CLIENT_ID and CLIENT_SECRET from GCP to create a secret for IAP. func (gcp *Gcp) createIapSecret(ctx context.Context, client *clientset.Clientset) error { p, err := gcp.GetPluginSpec() if err != nil { return err } if p.Auth == nil { return errors.WithStack(fmt.Errorf("GcpPluginSpec has no Auth")) } if p.Auth.IAP == nil { return errors.WithStack(fmt.Errorf("GcpPluginSpec has no Auth.IAP")) } oauthSecretNamespace := gcp.getIstioNamespace() log.Infof("OAuthSecretNS: %v", oauthSecretNamespace) if _, err := client.CoreV1().Secrets(oauthSecretNamespace). Get(KUBEFLOW_OAUTH, metav1.GetOptions{}); err == nil { log.Infof("Secret for %v already exits ...", KUBEFLOW_OAUTH) return nil } oauthSecret, err := gcp.kfDef.GetSecret(p.Auth.IAP.OAuthClientSecret.Name) if err != nil { log.Errorf("Could not read IAP OAuth ClientSecret from KfDef; error %v", err) return err } secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: KUBEFLOW_OAUTH, Namespace: oauthSecretNamespace, }, Data: map[string][]byte{ strings.ToLower(CLIENT_ID): []byte(p.Auth.IAP.OAuthClientId), strings.ToLower(CLIENT_SECRET): []byte(oauthSecret), }, } return createOrUpdateSecret(client, secret) } func base64EncryptPassword(password string) (string, error) { passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), 10) if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error when hashing password: %v", err), } } encodedPassword := base64.StdEncoding.EncodeToString(passwordHash) return encodedPassword, nil } // TODO(jlewi): Add a unittest to this function. func (gcp *Gcp) buildBasicAuthSecret() (*v1.Secret, error) { p, err := gcp.GetPluginSpec() if err != nil { return nil, err } if p.Auth == nil || p.Auth.BasicAuth == nil || p.Auth.BasicAuth.Password.Name == "" { err := errors.WithStack(fmt.Errorf("BasicAuth.Password.Name must be set")) log.Errorf("%v", err) return nil, err } password, err := gcp.kfDef.GetSecret(p.Auth.BasicAuth.Password.Name) if err != nil { log.Errorf("There was a problem getting the password for basic auth; error %v", err) return nil, err } ss, err := gcp.kfDef.GetSecretSource(p.Auth.BasicAuth.Password.Name) if err != nil { log.Errorf("There was a problem getting the password for basic auth; error %v", err) return nil, err } // For backward compatibility, we encode passward that is not hashed. var encodedPassword string if ss.HashedSource != nil { encodedPassword = password } else { encodedPassword, err = base64EncryptPassword(password) if err != nil { log.Errorf("There was a problem encrypting the password; %v", err) return nil, errors.WithStack(err) } } secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: BASIC_AUTH_SECRET, Namespace: gcp.kfDef.Namespace, }, Data: map[string][]byte{ "username": []byte(p.Auth.BasicAuth.Username), "passwordhash": []byte(encodedPassword), }, } return secret, nil } // createBasicAuthSecret creates a secret containing basic auth information. func (gcp *Gcp) createBasicAuthSecret(client *clientset.Clientset) error { secret, err := gcp.buildBasicAuthSecret() if err != nil { return err } return createOrUpdateSecret(client, secret) } func (gcp *Gcp) getIstioNamespace() string { if gcp.kfDef.UsingStacks() { // TODO(jlewi): With stacks we currently assume the iap-ingress is installed in istio-namespace. // The namespace would now be set inside the kustomization.yaml file of the package. So if needed we // could read the value from there. log.Warnf("Assuming iap-ingress is installed in namespace: %v", DefaultIstioNamespace) return DefaultIstioNamespace } if ingressNamespace, ok := gcp.kfDef.GetApplicationParameter("iap-ingress", "namespace"); ok { return ingressNamespace } if ingressNamespace, ok := gcp.kfDef.GetApplicationParameter("basic-auth-ingress", "namespace"); ok { return ingressNamespace } return gcp.kfDef.Namespace } func (gcp *Gcp) createSecrets() error { ctx := context.Background() k8sClient, err := gcp.getK8sClientset(ctx) if err != nil { return kfapis.NewKfErrorWithMessage(err, "set K8s clientset error") } log.Infof("Creating GCP secrets...") // Always create secrets in kubeflow namespace for backward compatiblility. adminEmail := getSA(gcp.kfDef.Name, "admin", gcp.kfDef.Spec.Project) userEmail := getSA(gcp.kfDef.Name, "user", gcp.kfDef.Spec.Project) if err := gcp.createGcpServiceAcctSecret(ctx, k8sClient, adminEmail, ADMIN_SECRET_NAME, gcp.kfDef.Namespace); err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("cannot create admin secret %v", ADMIN_SECRET_NAME)) } if err := gcp.createGcpServiceAcctSecret(ctx, k8sClient, userEmail, USER_SECRET_NAME, gcp.kfDef.Namespace); err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("cannot create user secret %v", USER_SECRET_NAME)) } if gcp.kfDef.Spec.UseBasicAuth { log.Infof("Creating GCP secrets for basic auth...") if err := gcp.createBasicAuthSecret(k8sClient); err != nil { return kfapis.NewKfErrorWithMessage(err, "cannot create basic auth login secret") } } else { log.Infof("Creating GCP secrets for IAP...") if err := gcp.createIapSecret(ctx, k8sClient); err != nil { return kfapis.NewKfErrorWithMessage(err, "cannot create IAP auth secret") } } return nil } // setupWorkloadIdentity creates the k8s service accounts and IAM bindings for them. k8sToGcpSA: k8sServiceAccounts to gcpServiceAccounts mapping func (gcp *Gcp) allowAdmineditUserSA(gcpAdminSa string, gcpUserSa string) error { ctx := context.Background() oClient := oauth2.NewClient(ctx, gcp.tokenSource) iamService, err := iam.New(oClient) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Get Oauth Client error: %v", err), } } log.Infof("Make admin account %v the owner of user account %v", gcpAdminSa, gcpUserSa) policy, err := utils.GetServiceAccountIamPolicy(iamService, gcp.kfDef.Spec.Project, gcpUserSa) if err != nil { return err } newBinding := iam.Binding{} newBinding.Role = "roles/owner" newBinding.Members = []string{ fmt.Sprintf("serviceAccount:%v", gcpAdminSa), } policy.Bindings = append(policy.Bindings, &newBinding) log.Infof("New policy: %v", *policy) err = utils.SetServiceAccountIamPolicy(iamService, policy, gcp.kfDef.Spec.Project, gcpUserSa) if err != nil { return err } return nil } // setupWorkloadIdentity creates the k8s service accounts and IAM bindings for them. k8sToGcpSA: k8sServiceAccounts to gcpServiceAccounts mapping func (gcp *Gcp) setupWorkloadIdentity(namespace string, k8sSa2gcpSa map[string]string) error { ctx := context.Background() k8sClient, err := gcp.getK8sClientset(ctx) if err != nil { return kfapis.NewKfErrorWithMessage(err, "Get K8s clientset error") } oClient := oauth2.NewClient(ctx, gcp.tokenSource) iamService, err := iam.New(oClient) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Get Oauth Client error: %v", err), } } for k8sSa, gcpSa := range k8sSa2gcpSa { createOrUpdateK8sServiceAccount(k8sClient, namespace, k8sSa, gcpSa) // Create IAM bindings under each GCP service account (different from IAM bindings for projects) // Could we combine the updates into a single set of Get/Set requests? // Can we also refactor the code so that we have a separate functions that generate the modified policy but don't apply it and then write a unittest that the modified policy is correct? log.Infof("Setting up iam policy for serviceaccount: %v in namespace %v", gcpSa, namespace) policy, err := utils.GetServiceAccountIamPolicy(iamService, gcp.kfDef.Spec.Project, gcpSa) if err != nil { return err } err = utils.UpdateWorkloadIdentityBindingsPolicy(policy, gcp.kfDef.Spec.Project, namespace, k8sSa) if err != nil { return err } log.Infof("New policy: %v", *policy) err = utils.SetServiceAccountIamPolicy(iamService, policy, gcp.kfDef.Spec.Project, gcpSa) if err != nil { return err } } return nil } // createOrUpdateK8sServiceAccount creates or updates k8s service account with annotation // iam.gke.io/gcp-service-account=gsa // TODO(lunkai): Ideally the k8s service account should be specified by kustomize. func createOrUpdateK8sServiceAccount(k8sClientset *clientset.Clientset, namespace string, name string, gsa string) error { log.Infof("Creating service account %v in namespace %v", name, namespace) currSA, err := k8sClientset.CoreV1().ServiceAccounts(namespace).Get(name, metav1.GetOptions{}) if err == nil { log.Infof("Service account already exists...") if currSA.Annotations == nil { currSA.Annotations = map[string]string{} } currSA.Annotations["iam.gke.io/gcp-service-account"] = gsa _, err = k8sClientset.CoreV1().ServiceAccounts(namespace).Update(currSA) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } return nil } log.Infof("Get service account error: %v", err) _, err = k8sClientset.CoreV1().ServiceAccounts(namespace).Create( &v1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, Annotations: map[string]string{ "iam.gke.io/gcp-service-account": gsa, }, }, }, ) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } } // SetupWorkloadIdentityPermission bind gcp admin service account to owner of gcp "user" service account, so controller can edit WorkloadIdentity func (gcp *Gcp) SetupWorkloadIdentityPermission() error { kubeflowWorkloadIdentityMapping := map[string]string{ "profiles-controller-service-account": fmt.Sprintf("%v-admin@%v.iam.gserviceaccount.com", gcp.kfDef.Name, gcp.kfDef.Spec.Project), } if err := gcp.setupWorkloadIdentity(gcp.kfDef.Namespace, kubeflowWorkloadIdentityMapping); err != nil { return &kfapis.KfError{ Code: err.(*kfapis.KfError).Code, Message: fmt.Sprintf("Fail to setup workload identity:: %v", err.(*kfapis.KfError).Message), } } return nil } func generatePodDefault(group string, version string, kind string, namespace string) *unstructured.Unstructured { log.Infof("Generating %v in namespace %v; APIVersion %v/%v", kind, namespace, group, version) // TODO(gabrielwen): Clean up after v2 dependencies are fixed. // https://github.com/kubeflow/kubeflow/issues/3713 unstructuredContent := map[string]interface{}{ "apiVersion": group + "/" + version, "kind": kind, "metadata": map[string]interface{}{ "name": PodDefaultName, "namespace": namespace, }, "spec": map[string]interface{}{ "selector": map[string]interface{}{ "matchLabels": map[string]interface{}{ "add-gcp-secret": "true", }, }, "desc": "add gcp credential", "env": []interface{}{ map[string]interface{}{ "name": "GOOGLE_APPLICATION_CREDENTIALS", "value": "/secret/gcp/user-gcp-sa.json", }, }, "volumeMounts": []interface{}{ map[string]interface{}{ "name": "secret-volume", "mountPath": "/secret/gcp", }, }, "volumes": []interface{}{ map[string]interface{}{ "name": "secret-volume", "secret": map[string]interface{}{ "secretName": USER_SECRET_NAME, }, }, }, }, } podDefault := &unstructured.Unstructured{ Object: unstructuredContent, } return podDefault } // Configure PodDefault to add secret. func (gcp *Gcp) ConfigPodDefault() error { if gcp.kfDef.Spec.Email == "" { return nil } ctx := context.Background() k8sClient, err := gcp.getK8sClientset(ctx) if err != nil { return kfapis.NewKfErrorWithMessage(err, "set K8s clientset error") } defaultNamespace := kftypesv3.EmailToDefaultName(gcp.kfDef.Spec.Email) _, err = k8sClient.CoreV1().Namespaces().Get(defaultNamespace, metav1.GetOptions{}) if err != nil { log.Warnf("Default namespace %v creation skipped", defaultNamespace) return nil } log.Infof("Downloading secret %v from namespace %v", USER_SECRET_NAME, gcp.kfDef.Namespace) secret, err := k8sClient.CoreV1().Secrets(gcp.kfDef.Namespace).Get(USER_SECRET_NAME, metav1.GetOptions{}) if err != nil { return kfapis.NewKfErrorWithMessage(err, "User service account secret is not created.") } log.Infof("Creating secret %v to namespace %v", USER_SECRET_NAME, defaultNamespace) if err = insertSecret(k8sClient, USER_SECRET_NAME, defaultNamespace, secret.Data); err != nil { return kfapis.NewKfErrorWithMessage(err, fmt.Sprintf("cannot create secret %v in namespace %v", USER_SECRET_NAME, defaultNamespace)) } group := "kubeflow.org" version := "v1alpha1" kind := "PodDefault" podDefault := generatePodDefault(group, version, kind, defaultNamespace) cluster, err := utils.GetClusterInfo(ctx, gcp.kfDef.Spec.Project, gcp.kfDef.Spec.Zone, gcp.kfDef.Name, gcp.tokenSource) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("get Cluster error: %v", err), } } body, err := podDefault.MarshalJSON() if err != nil { return kfapis.NewKfErrorWithMessage(err, "Marshal error for PodDefault config.") } // Need to re-configure restful client to remap group/kind/version. config, err := utils.BuildConfigFromClusterInfo(ctx, cluster, gcp.tokenSource) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("build ClientConfig error: %v", err), } } _discoveryClient, err := discovery.NewDiscoveryClientForConfig(config) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("build DiscoveryClient error: %v", err), } } _cached := memory.NewMemCacheClient(_discoveryClient) _cached.Invalidate() mapper := restmapper.NewDeferredDiscoveryRESTMapper(_cached) gk := schema.GroupKind{ Group: group, Kind: kind, } mapping, err := mapper.RESTMapping(gk, version) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("config Group/Version/Kind error: %v", err), } } c := restv2.CopyConfig(config) c.GroupVersion = &schema.GroupVersion{ Group: group, Version: version, } c.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs} c.APIPath = "/apis" crdClient, err := restv2.RESTClientFor(c) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("config RestClient error: %v", err), } } getReq := crdClient.Get().Resource(mapping.Resource.Resource).Namespace(defaultNamespace).Name(PodDefaultName) if err := getReq.Do().Error(); err == nil { // pod default already exists. return nil } req := crdClient.Post().Resource(mapping.Resource.Resource).Body(body) req = req.Namespace(defaultNamespace) result := req.Do() return result.Error() } // setGcpPluginDefaults sets the GcpPlugin defaults. func (gcp *Gcp) setGcpPluginDefaults() error { // Set the defaults that will be used if not explicitly set. // If the plugin is provided these values will be overwritten, pluginSpec := &gcpplugin.GcpPluginSpec{} err := gcp.kfDef.GetPluginSpec(GcpPluginName, pluginSpec) if err != nil && !kfapis.IsNotFound(err) { log.Errorf("There was a problem getting the gcp plugin %v", err) return errors.WithStack(err) } if pluginSpec.CreatePipelinePersistentStorage == nil { pluginSpec.CreatePipelinePersistentStorage = proto.Bool(pluginSpec.GetCreatePipelinePersistentStorage()) log.Infof("CreatePipelinePersistentStorage not set defaulting to %v", *pluginSpec.CreatePipelinePersistentStorage) } if pluginSpec.EnableWorkloadIdentity == nil { pluginSpec.EnableWorkloadIdentity = proto.Bool(pluginSpec.GetEnableWorkloadIdentity()) log.Infof("EnableWorkloadIdentity not set defaulting to %v", *pluginSpec.EnableWorkloadIdentity) } if pluginSpec.Auth == nil { pluginSpec.Auth = &gcpplugin.Auth{} } if pluginSpec.Auth.BasicAuth == nil && pluginSpec.Auth.IAP == nil { log.Warnf("Backfilling auth; this is deprecated; Auth should be explicitly set in Gcp plugin") if gcp.kfDef.Spec.UseBasicAuth { pluginSpec.Auth.BasicAuth = &gcpplugin.BasicAuth{} pluginSpec.Auth.BasicAuth.Username = os.Getenv(kftypesv3.KUBEFLOW_USERNAME) if pluginSpec.Auth.BasicAuth.Username == "" { log.Errorf("Could not configure basic auth; environment variable %s not set", kftypesv3.KUBEFLOW_USERNAME) return errors.WithStack(fmt.Errorf("Could not configure basic auth; environment variable %s not set", kftypesv3.KUBEFLOW_USERNAME)) } pluginSpec.Auth.BasicAuth.Password = &kfconfig.SecretRef{ Name: BasicAuthPasswordSecretName, } password := os.Getenv(kftypesv3.KUBEFLOW_PASSWORD) if password == "" { log.Errorf("Could not configure basic auth; environment variable %s not set", kftypesv3.KUBEFLOW_PASSWORD) return errors.WithStack(fmt.Errorf("Could not configure basic auth; environment variable %s not set", kftypesv3.KUBEFLOW_PASSWORD)) } gcp.kfDef.SetSecret(kfconfig.Secret{ Name: BasicAuthPasswordSecretName, SecretSource: &kfconfig.SecretSource{ EnvSource: &kfconfig.EnvSource{ Name: kftypesv3.KUBEFLOW_PASSWORD, }, }, }) } else { pluginSpec.Auth.IAP = &gcpplugin.IAP{} pluginSpec.Auth.IAP.OAuthClientId = os.Getenv(CLIENT_ID) if pluginSpec.Auth.IAP.OAuthClientId == "" { log.Errorf("Could not configure IAP auth; environment variable %s not set", CLIENT_ID) return errors.WithStack(fmt.Errorf("Could not configure IAP auth; environment variable %s not set", CLIENT_ID)) } pluginSpec.Auth.IAP.OAuthClientSecret = &kfconfig.SecretRef{ Name: CLIENT_SECRET, } gcp.kfDef.SetSecret(kfconfig.Secret{ Name: CLIENT_SECRET, SecretSource: &kfconfig.SecretSource{ EnvSource: &kfconfig.EnvSource{ Name: CLIENT_SECRET, }, }, }) } } // Set the email if gcp.kfDef.Spec.Email == "" && gcp.gcpAccountGetter != nil { email, err := gcp.gcpAccountGetter() if err != nil { log.Errorf("Cannot get gcloud account email. Error: %v", err) return err } gcp.kfDef.Spec.Email = strings.TrimSpace(email) pluginSpec.Email = strings.TrimSpace(email) log.Infof("Setting Email to default: %v", gcp.kfDef.Spec.Email) } else if gcp.kfDef.Spec.Email == "" { log.Warnf("GcpAccountGetter not set; can't get default email") } // Set the project if gcp.kfDef.Spec.Project == "" && gcp.gcpProjectGetter != nil { project, err := gcp.gcpProjectGetter() if err != nil { log.Errorf("Cannot get gcloud project. Error: %v", err) return err } gcp.kfDef.Spec.Project = strings.TrimSpace(project) pluginSpec.Project = strings.TrimSpace(project) log.Infof("Setting Project to default: %v", gcp.kfDef.Spec.Project) } else if gcp.kfDef.Spec.Project == "" { log.Warnf("GcpProjectGetter not set; can't get default project") } // Set the zone if gcp.kfDef.Spec.Zone == "" && gcp.gcpZoneGetter != nil { zone, err := gcp.gcpZoneGetter() if err != nil { log.Errorf("Cannot get gcloud compute/zone. Error: %v", err) return err } gcp.kfDef.Spec.Zone = strings.TrimSpace(zone) pluginSpec.Zone = strings.TrimSpace(zone) log.Infof("Setting Zone to default: %v", gcp.kfDef.Spec.Zone) } else if gcp.kfDef.Spec.Zone == "" { log.Warnf("GcpZoneGetter not set; can't get default zone") } return gcp.kfDef.SetPluginSpec(GcpPluginName, pluginSpec) } // Generate generates the gcp kfapp manifest. // Remind: Need to be thread-safe: this entry is share among kfctl and deploy app func (gcp *Gcp) Generate(resources kftypesv3.ResourceEnum) error { gcpDir := path.Join(gcp.kfDef.Spec.AppDir, GCP_CONFIG) if _, err := os.Stat(gcpDir); err == nil { // Noop if the directory already exists. log.Infof("Folder %v exists, skip gcp.Generate", gcpDir) return nil } else if !os.IsNotExist(err) { log.Errorf("Stat folder %v error: %v; try deleting it...", gcpDir, err) _ = os.RemoveAll(gcpDir) } if err := gcp.kfDef.SyncCache(); err != nil { log.Errorf("Failed to synchronize the cache; error %v", err) return errors.WithStack(err) } if err := gcp.setGcpPluginDefaults(); err != nil { return errors.WithStack(err) } pluginSpec := &gcpplugin.GcpPluginSpec{} err := gcp.kfDef.GetPluginSpec(GcpPluginName, pluginSpec) if err != nil { log.Errorf("Could not get GcpPluginSpec; error %v", err) return err } // the runGetGCPCredentials don't seem to work because those are shelled out commands // Added an alternate way to set using enironment variables if gcp.kfDef.Spec.Project == "" { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "GCP Project is not set, please set it in KFDef or use gcloud config set project to set a default.", } } if gcp.kfDef.Spec.Email == "" { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "GCP account could not be determined, please set Email in KFDef or use gcloud config set account to set a default.", } } if gcp.kfDef.Spec.Zone == "" { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "GCP Zone is not set, please set it in KFDef or use gcloud config set compute/zone to set a default.", } } // Set default IPName and Hostname // This needs to happen before calling generateDM configs. if gcp.kfDef.Spec.IpName == "" { gcp.kfDef.Spec.IpName = gcp.kfDef.Name + "-ip" pluginSpec.IpName = gcp.kfDef.Spec.IpName } gcp.kfDef.Spec.Hostname = gcp.kfDef.Name + ".endpoints." + gcp.kfDef.Spec.Project + ".cloud.goog" pluginSpec.Hostname = gcp.kfDef.Spec.Hostname switch resources { case kftypesv3.ALL: fallthrough case kftypesv3.PLATFORM: gcpConfigFilesErr := gcp.generateDMConfigs() if gcpConfigFilesErr != nil { code := http.StatusInternalServerError if v, ok := gcpConfigFilesErr.(*kfapis.KfError); ok { code = v.Code } return &kfapis.KfError{ Code: code, Message: fmt.Sprintf("could not generate deployment manager configs under %v Error: %v", GCP_CONFIG, gcpConfigFilesErr), } } } if err := gcp.kfDef.SetApplicationParameter("profiles", "admin", gcp.kfDef.Spec.Email); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("profiles", "gcp-sa", fmt.Sprintf( "%v-user@%v.iam.gserviceaccount.com", gcp.kfDef.Name, gcp.kfDef.Spec.Project)); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("default-install", "user", gcp.kfDef.Spec.Email); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("default-install", "profile-name", kftypesv3.EmailToDefaultName(gcp.kfDef.Spec.Email)); err != nil { return errors.WithStack(err) } if gcp.kfDef.Spec.UseBasicAuth { if err := gcp.kfDef.SetApplicationParameter("basic-auth-ingress", "ipName", gcp.kfDef.Spec.IpName); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("basic-auth-ingress", "hostname", gcp.kfDef.Spec.Hostname); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("basic-auth-ingress", "project", gcp.kfDef.Spec.Project); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("istio", "clusterRbacConfig", "OFF"); err != nil { return errors.WithStack(err) } } else { if err := gcp.kfDef.SetApplicationParameter("iap-ingress", "ipName", gcp.kfDef.Spec.IpName); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("iap-ingress", "hostname", gcp.kfDef.Spec.Hostname); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("iap-ingress", "project", gcp.kfDef.Spec.Project); err != nil { return errors.WithStack(err) } // appName is used to give a unique name to the cloud endpoint. if err := gcp.kfDef.SetApplicationParameter("iap-ingress", "appName", gcp.kfDef.Name); err != nil { return errors.WithStack(err) } } if *pluginSpec.CreatePipelinePersistentStorage { log.Infof("Configuring pipeline, minio, and mysql applications") minioPdName := gcp.kfDef.Name + "-storage-artifact-store" mysqlPdName := gcp.kfDef.Name + "-storage-metadata-store" if err := gcp.kfDef.SetApplicationParameter("minio", "minioPd", minioPdName); err != nil { return errors.WithStack(err) } if err := gcp.kfDef.SetApplicationParameter("mysql", "mysqlPd", mysqlPdName); err != nil { return errors.WithStack(err) } } // TODO(jlewi): Why are we setting usage Id here (gcp.go) and not in kustomize.go so we do it for all platforms? rand.Seed(time.Now().UnixNano()) if err := gcp.kfDef.SetApplicationParameter("spartakus", "usageId", strconv.Itoa(rand.Int())); err != nil { if kfconfig.IsAppNotFound(err) { log.Infof("Spartakus not included; not setting usageId") } } if err := gcp.kfDef.SetPluginSpec(GcpPluginName, pluginSpec); err != nil { return errors.WithStack(err) } return nil } func (gcp *Gcp) gcpInitProject() error { if err := gcp.initGcpClient(); err != nil { log.Errorf("There was a problem initializing the GCP client; %v", err) return errors.WithMessagef(err, "Gcp.gcpInitProject Could not initatie a GCP client") } ctx := context.Background() serviceusageService, serviceusageServiceErr := serviceusage.New(gcp.client) if serviceusageServiceErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not create service usage service %v", serviceusageServiceErr), } } enabledApis := []string{ "deploymentmanager.googleapis.com", "servicemanagement.googleapis.com", "container.googleapis.com", "cloudresourcemanager.googleapis.com", "endpoints.googleapis.com", "file.googleapis.com", "ml.googleapis.com", "iam.googleapis.com", "sqladmin.googleapis.com", } op, opErr := serviceusageService.Services.BatchEnable("projects/"+gcp.kfDef.Spec.Project, &serviceusage.BatchEnableServicesRequest{ ServiceIds: enabledApis, }).Context(ctx).Do() if opErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("issuing batch API enabling services error: %v", opErr), } } opService := serviceusage.NewOperationsService(serviceusageService) opName := "" + op.Name return backoff.Retry(func() error { newOp, retryErr := opService.Get(opName).Context(ctx).Do() if retryErr != nil { log.Errorf("Long running batch API enabling services error: %v", retryErr) return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("long running batch API enabling services error: %v", retryErr), } } if newOp.Error != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("long running batch API enabling services error: %v", newOp.Error.Message), } } if newOp.Done { if newOp.HTTPStatusCode != 200 { return backoff.Permanent(&kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Abnormal response code: %v", newOp.HTTPStatusCode), }) } log.Infof("Batch API enabling is completed: %v", enabledApis) return nil } log.Infof("Batch API enabling is running: %v (op = %v)", enabledApis, newOp.Name) opName = "" + newOp.Name return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("batch API enabling is running..."), } }, newDefaultBackoff()) } // Init initializes a gcp kfapp func (gcp *Gcp) Init(resources kftypesv3.ResourceEnum) error { if !gcp.kfDef.Spec.SkipInitProject { log.Infof("Not skipping GCP project init, running gcpInitProject.") initProjectErr := gcp.gcpInitProject() if initProjectErr != nil { return initProjectErr } } else { if err := gcp.initGcpClient(); err != nil { log.Errorf("There was a problem initializing the GCP client; %v", err) return errors.WithMessagef(err, "Gcp.gcpInitProject Could not initatie a GCP client") } } return nil } ================================================ FILE: pkg/kfapp/gcp/gcp_test.go ================================================ package gcp import ( "encoding/json" "github.com/gogo/protobuf/proto" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/kfconfig/gcpplugin" "os" "reflect" "testing" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestGcp_buildBasicAuthSecret(t *testing.T) { type testCase struct { Gcp *Gcp GcpPluginSpec *gcpplugin.GcpPluginSpec Expected *v1.Secret } encodedPassword, err := base64EncryptPassword("somepassword") if err != nil { t.Fatalf("Could not encode password; %v", err) } cases := []testCase{ { Gcp: &Gcp{ kfDef: &kfconfig.KfConfig{ ObjectMeta: metav1.ObjectMeta{ Namespace: "gcpnamespace", }, Spec: kfconfig.KfConfigSpec{ Plugins: []kfconfig.Plugin{ { Name: "gcp", }, }, Secrets: []kfconfig.Secret{ { Name: "passwordSecret", SecretSource: &kfconfig.SecretSource{ LiteralSource: &kfconfig.LiteralSource{ Value: "somepassword", }, }, }, }, }, }, }, GcpPluginSpec: &gcpplugin.GcpPluginSpec{ Auth: &gcpplugin.Auth{ BasicAuth: &gcpplugin.BasicAuth{ Username: "kfuser", Password: &kfconfig.SecretRef{ Name: "passwordSecret", }, }, }, }, Expected: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "kubeflow-login", Namespace: "gcpnamespace", }, Data: map[string][]byte{ "passwordhash": []byte(encodedPassword), "username": []byte("kfuser"), }, }, }, } for _, c := range cases { err := c.Gcp.kfDef.SetPluginSpec("KfGcpPlugin", c.GcpPluginSpec) if err != nil { t.Fatalf("Could not set pluginspec") } actual, err := c.Gcp.buildBasicAuthSecret() if err != nil { t.Fatalf("Could not get build secret; error %v", err) } if !reflect.DeepEqual(actual.TypeMeta, c.Expected.TypeMeta) { pGot, _ := Pformat(actual.TypeMeta) pWant, _ := Pformat(c.Expected.TypeMeta) t.Errorf("Error building secret TypeMeta got;\n%v\nwant;\n%v", pGot, pWant) } for _, k := range []string{"username", "passwordHash"} { if string(actual.Data[k]) != string(c.Expected.Data[k]) { pGot, _ := actual.Data[k] pWant, _ := c.Expected.Data[k] t.Errorf("Error building secret Key %v got;\n%v\nwant;\n%v", k, pGot, pWant) } } } } func TestGcp_setGcpPluginDefaults(t *testing.T) { type testCase struct { Name string Input *kfconfig.KfConfig InputSpec *gcpplugin.GcpPluginSpec Env map[string]string EmailGetter func() (string, error) ProjectGetter func() (string, error) ZoneGetter func() (string, error) Expected *gcpplugin.GcpPluginSpec ExpectedEmail string ExpectedProject string ExpectedZone string } cases := []testCase{ { Name: "no-plugin-basic-auth", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: true, }, }, Env: map[string]string{ kftypes.KUBEFLOW_USERNAME: "someuser", kftypes.KUBEFLOW_PASSWORD: "password", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ BasicAuth: &gcpplugin.BasicAuth{ Username: "someuser", Password: &kfconfig.SecretRef{ Name: BasicAuthPasswordSecretName, }, }, }, }, }, { Name: "no-plugin-iap", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ IAP: &gcpplugin.IAP{ OAuthClientId: "someclient", OAuthClientSecret: &kfconfig.SecretRef{ Name: CLIENT_SECRET, }, }, }, }, }, { Name: "set-email", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ IAP: &gcpplugin.IAP{ OAuthClientId: "someclient", OAuthClientSecret: &kfconfig.SecretRef{ Name: CLIENT_SECRET, }, }, }, Project: "myproject", Email: "myemail", Zone: "us-east1-b", }, EmailGetter: func() (string, error) { return "myemail", nil }, ProjectGetter: func() (string, error) { return "\nmyproject ", nil }, ZoneGetter: func() (string, error) { return "\nus-east1-b\n", nil }, ExpectedEmail: "myemail", ExpectedProject: "myproject", ExpectedZone: "us-east1-b", }, { // Make sure emails get trimmed. Name: "trim-email", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ IAP: &gcpplugin.IAP{ OAuthClientId: "someclient", OAuthClientSecret: &kfconfig.SecretRef{ Name: CLIENT_SECRET, }, }, }, Email: "myemail", }, EmailGetter: func() (string, error) { return "\nmyemail\n", nil }, ExpectedEmail: "myemail", }, // Verify that we don't override createPipelinePersistentStorage. { // Make sure emails get trimmed. Name: "no-override", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, }, InputSpec: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(false), }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(false), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ IAP: &gcpplugin.IAP{ OAuthClientId: "someclient", OAuthClientSecret: &kfconfig.SecretRef{ Name: CLIENT_SECRET, }, }, }, Email: "myemail", }, EmailGetter: func() (string, error) { return "\nmyemail\n", nil }, ExpectedEmail: "myemail", }, { Name: "iap-not-overwritten", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, }, InputSpec: &gcpplugin.GcpPluginSpec{ Auth: &gcpplugin.Auth{ IAP: &gcpplugin.IAP{ OAuthClientId: "original_client", OAuthClientSecret: &kfconfig.SecretRef{ Name: "original_secret", }, }, }, }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ IAP: &gcpplugin.IAP{ OAuthClientId: "original_client", OAuthClientSecret: &kfconfig.SecretRef{ Name: "original_secret", }, }, }, }, }, { Name: "basic-auth-not-overwritten", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: true, }, }, InputSpec: &gcpplugin.GcpPluginSpec{ Auth: &gcpplugin.Auth{ BasicAuth: &gcpplugin.BasicAuth{ Username: "original_user", Password: &kfconfig.SecretRef{ Name: "original_secret", }, }, }, }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ BasicAuth: &gcpplugin.BasicAuth{ Username: "original_user", Password: &kfconfig.SecretRef{ Name: "original_secret", }, }, }, }, }, { Name: "dm-configs-not-overwritten", Input: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: true, }, }, InputSpec: &gcpplugin.GcpPluginSpec{ Auth: &gcpplugin.Auth{ BasicAuth: &gcpplugin.BasicAuth{ Username: "original_user", Password: &kfconfig.SecretRef{ Name: "original_secret", }, }, }, DeploymentManagerConfig: &gcpplugin.DeploymentManagerConfig{ RepoRef: &kfconfig.RepoRef{ Name: "somerepo", Path: "somepath", }, }, }, Env: map[string]string{ CLIENT_ID: "someclient", }, Expected: &gcpplugin.GcpPluginSpec{ CreatePipelinePersistentStorage: proto.Bool(true), EnableWorkloadIdentity: proto.Bool(true), Auth: &gcpplugin.Auth{ BasicAuth: &gcpplugin.BasicAuth{ Username: "original_user", Password: &kfconfig.SecretRef{ Name: "original_secret", }, }, }, DeploymentManagerConfig: &gcpplugin.DeploymentManagerConfig{ RepoRef: &kfconfig.RepoRef{ Name: "somerepo", Path: "somepath", }, }, }, }, } for index, c := range cases { if index > 0 { // Unset previous environment variables for k, _ := range cases[index-1].Env { os.Unsetenv(k) } } for k, v := range c.Env { os.Setenv(k, v) } i := c.Input.DeepCopy() if c.InputSpec != nil { i.SetPluginSpec(GcpPluginName, c.InputSpec) } gcp := &Gcp{ kfDef: i, gcpAccountGetter: c.EmailGetter, gcpProjectGetter: c.ProjectGetter, gcpZoneGetter: c.ZoneGetter, } if err := gcp.setGcpPluginDefaults(); err != nil { t.Errorf("Case %v; setGcpPluginDefaults() error %v", c.Name, err) continue } plugin := &gcpplugin.GcpPluginSpec{} err := i.GetPluginSpec(GcpPluginName, plugin) if err != nil { t.Errorf("Case %v; GetPluginSpec() error %v", c.Name, err) continue } if !reflect.DeepEqual(plugin, c.Expected) { pGot, _ := Pformat(plugin) pWant, _ := Pformat(c.Expected) t.Errorf("Case %v; got:\n%v\nwant:\n%v", c.Name, pGot, pWant) } if c.ExpectedEmail != "" && c.ExpectedEmail != i.Spec.Email { t.Errorf("Case %v; email: got %v; want %v", c.Name, i.Spec.Email, c.ExpectedEmail) } if c.ExpectedProject != "" && c.ExpectedProject != i.Spec.Project { t.Errorf("Case %v; project: got %v; want %v", c.Name, i.Spec.Project, c.ExpectedProject) } if c.ExpectedZone != "" && c.ExpectedZone != i.Spec.Zone { t.Errorf("Case %v; zone: got %v; want %v", c.Name, i.Spec.Zone, c.ExpectedZone) } } } func TestGcp_setPodDefault(t *testing.T) { group := "kubeflow.org" version := "v1alpha1" kind := "PodDefault" namespace := "foo-bar-baz" expected := map[string]interface{}{ "apiVersion": group + "/" + version, "kind": kind, "metadata": map[string]interface{}{ "name": "add-gcp-secret", "namespace": namespace, }, "spec": map[string]interface{}{ "selector": map[string]interface{}{ "matchLabels": map[string]interface{}{ "add-gcp-secret": "true", }, }, "desc": "add gcp credential", "env": []interface{}{ map[string]interface{}{ "name": "GOOGLE_APPLICATION_CREDENTIALS", "value": "/secret/gcp/user-gcp-sa.json", }, }, "volumeMounts": []interface{}{ map[string]interface{}{ "name": "secret-volume", "mountPath": "/secret/gcp", }, }, "volumes": []interface{}{ map[string]interface{}{ "name": "secret-volume", "secret": map[string]interface{}{ "secretName": "user-gcp-sa", }, }, }, }, } actual := generatePodDefault(group, version, kind, namespace) if !reflect.DeepEqual(actual.UnstructuredContent(), expected) { pGot, _ := Pformat(actual.UnstructuredContent()) pWant, _ := Pformat(expected) t.Errorf("PodDefault not matching; got\n%v\nwant\n%v", pGot, pWant) } } // Pformat returns a pretty format output of any value. // TODO(jlewi): Use utils.PrettyPrint func Pformat(value interface{}) (string, error) { if s, ok := value.(string); ok { return s, nil } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { return "", err } return string(valueJson), nil } ================================================ FILE: pkg/kfapp/gcp/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/kfapp/gcp/testdata/kfctl_gcp.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1alpha1 kind: KfDef spec: plugins: - name: gcp args: auth: basicAuth: username: someuser password: name: password ================================================ FILE: pkg/kfapp/kfapp.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 kfdef package kfapp ================================================ FILE: pkg/kfapp/kfdef.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 kfdef package kfapp ================================================ FILE: pkg/kfapp/kustomize/kustomize.go ================================================ /* 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. */ package kustomize import ( "bufio" "bytes" "encoding/hex" "fmt" "io/ioutil" "math/rand" "os" "path" "path/filepath" "strconv" "strings" "time" errutil "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/cenkalti/backoff" "github.com/ghodss/yaml" "github.com/imdario/mergo" kfapisv3 "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfdefsv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/utils" "github.com/otiai10/copy" "github.com/pkg/errors" log "github.com/sirupsen/logrus" crdclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" corev1 "k8s.io/client-go/kubernetes/typed/core/v1" rbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1" "k8s.io/client-go/rest" "sigs.k8s.io/kustomize/v3/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/v3/k8sdeps/transformer" "sigs.k8s.io/kustomize/v3/pkg/fs" "sigs.k8s.io/kustomize/v3/pkg/image" "sigs.k8s.io/kustomize/v3/pkg/loader" "sigs.k8s.io/kustomize/v3/pkg/plugins" "sigs.k8s.io/kustomize/v3/pkg/resmap" "sigs.k8s.io/kustomize/v3/pkg/resource" "sigs.k8s.io/kustomize/v3/pkg/target" "sigs.k8s.io/kustomize/v3/pkg/types" "sigs.k8s.io/kustomize/v3/pkg/validators" "sigs.k8s.io/kustomize/v3/plugin/builtin" ) // kustomize implements KfApp Interface // It should include functionality needed for the kustomize platform // In addition to `kustomize build`, there is `kustomize edit ...` // As noted below there are lots of different ways to use edit // kustomize edit add configmap my-configmap --from-file=my-key=file/path --from-literal=my-literal=12345 // kustomize edit add configmap my-configmap --from-file=file/path // kustomize edit add configmap my-configmap --from-env-file=env/path.env // kustomize edit add configmap NAME --from-literal=k=v // kustomize edit add resource // kustomize edit add patch // kustomize edit add base ,, // kustomize edit set nameprefix type MapType int const ( basesMap MapType = 0 commonAnnotationsMap MapType = 1 commonLabelsMap MapType = 2 imagesMap MapType = 3 resourcesMap MapType = 4 crdsMap MapType = 5 varsMap MapType = 6 configurationsMap MapType = 7 configMapGeneratorMap MapType = 8 secretsMapGeneratorMap MapType = 9 patchesStrategicMergeMap MapType = 10 patchesJson6902Map MapType = 11 OverlayParamName = "overlay" ) type kustomize struct { kfDef *kfconfig.KfConfig out *os.File err *os.File componentPathMap map[string]string componentMap map[string]bool packageMap map[string]*[]string restConfig *rest.Config // when set to true, apply() will skip local kube config, directly build config from restConfig configOverwrite bool } const ( defaultUserId = "anonymous" outputDir = "kustomize" ) // Setter defines an interface for modifying the plugin. type Setter interface { SetK8sRestConfig(r *rest.Config) } // GetKfApp is the common entry point for all implementations of the KfApp interface func GetKfApp(kfdef *kfconfig.KfConfig) kftypesv3.KfApp { _kustomize := &kustomize{ kfDef: kfdef, out: os.Stdout, err: os.Stderr, } // We explicitly do not initiate restConfig here. // We want to delay creating the clients until we actually need them. // This is for two reasons // 1. We want to allow injecting the config and not relying on // $HOME/.kube/config always // 2. We want to be able to generate the manifests without the K8s cluster existing. // build restConfig using $HOME/.kube/config if the file exists return _kustomize } // initK8sClients initializes the K8s clients if they haven't already been initialized. // it is a null op otherwise. func (kustomize *kustomize) initK8sClients() error { if kustomize.restConfig == nil { log.Infof("Initializing a default restConfig for Kubernetes") kustomize.restConfig = kftypesv3.GetConfig() } return nil } func (kustomize *kustomize) render(app kfconfig.Application) ([]byte, error) { kustomizeDir := path.Join(kustomize.kfDef.Spec.AppDir, outputDir) resMap, err := EvaluateKustomizeManifest(path.Join(kustomizeDir, app.Name)) if err != nil { log.Errorf("Error evaluating kustomization manifest for %v: %v", app.Name, err) return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error evaluating kustomization manifest for %v: %v", app.Name, err), } } sortResourceByKind(resMap, utils.InstallOrder) // check to set owner references for resources if installed through kubeflow operator annotations := kustomize.kfDef.GetAnnotations() setOperatorAnnotation := false if setOperator, ok := annotations[strings.Join([]string{utils.KfDefAnnotation, utils.SetAnnotation}, "/")]; ok { if setOperatorBool, err := strconv.ParseBool(setOperator); err == nil { setOperatorAnnotation = setOperatorBool } } //TODO this should be streamed var data []byte if setOperatorAnnotation { // retrieve the UID of the KfDef resource using dynamic client config, _ := rest.InClusterConfig() dyn, err := dynamic.NewForConfig(config) if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("failed to create dynamic client: %v", err), } } kfDefRes := schema.GroupVersionResource{Group: "kfdef.apps.kubeflow.org", Version: "v1", Resource: "kfdefs"} instance, err := dyn.Resource(kfDefRes).Namespace(kustomize.kfDef.GetNamespace()).Get(kustomize.kfDef.GetName(), metav1.GetOptions{}) if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("failed to get the KfDef object: %v", err), } } data, err = GenerateYamlWithOperatorAnnotation(resMap, instance) if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("can not encode component %v as yaml: %v", app.Name, err), } } } else { data, err = resMap.AsYaml() if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("can not encode component %v as yaml: %v", app.Name, err), } } } return data, nil } // Dump prints the kustomize generated resources to stdout func (kustomize *kustomize) Dump(resources kftypesv3.ResourceEnum) error { applications := make(map[string]bool) for _, app := range kustomize.kfDef.Spec.Applications { if applications[app.Name] == true { // if the application name already continue } applications[app.Name] = true data, err := kustomize.render(app) if err != nil { return err } fmt.Println(string(data)) fmt.Println("---") } return nil } // Apply deploys kustomize generated resources to the kubenetes api server func (kustomize *kustomize) Apply(resources kftypesv3.ResourceEnum) error { var restConfig *rest.Config = nil if kustomize.configOverwrite && kustomize.restConfig != nil { restConfig = kustomize.restConfig } apply, err := utils.NewApply(kustomize.kfDef.ObjectMeta.Namespace, restConfig) if err != nil { return err } // Read clusterName and write to KfDef. kubeconfig := kftypesv3.GetKubeConfig() if kubeconfig == nil { log.Warnf("Unable to load .kubeconfig.") } else { currentCtx := kubeconfig.CurrentContext if ctx, ok := kubeconfig.Contexts[currentCtx]; !ok || ctx == nil { log.Errorf("Cannot find current-context in kubeconfig.") } else { log.Infof("Log cluster name into KfDef: %v", ctx.Cluster) kustomize.kfDef.ClusterName = ctx.Cluster } } applications := make(map[string]bool) for _, app := range kustomize.kfDef.Spec.Applications { if applications[app.Name] == true { // if the application name already continue } applications[app.Name] = true log.Infof("Deploying application %v", app.Name) data, err := kustomize.render(app) if err != nil { return err } // TODO(https://github.com/kubeflow/manifests/issues/806): Bump the timeout because cert-manager takes // a long time to start. Any application that needs to create a certificate will fail because it won't // be able to create certificates if cert-manager is unavailable. We should try to identify Permanent Errors // and return a PermanentError to avoid retrying and taking 10 minutes to fail. b := utils.NewDefaultBackoff() b.MaxElapsedTime = 10 * time.Minute err = backoff.RetryNotify( func() error { return apply.Apply(data) }, b, func(e error, duration time.Duration) { log.Warnf("Encountered error applying application %v: %v", app.Name, e) log.Warnf("Will retry in %.0f seconds.", duration.Seconds()) }) if err != nil { log.Errorf("Permanently failed applying application %v: %v", app.Name, err) return err } log.Infof("Successfully applied application %v", app.Name) } // Default user namespace when multi-tenancy enabled defaultProfileNamespace := kftypesv3.EmailToDefaultName(kustomize.kfDef.Spec.Email) // Default user namespace when multi-tenancy disabled anonymousNamespace := "anonymous" b := utils.NewDefaultBackoff() err = backoff.Retry(func() error { if !(apply.IfNamespaceExist(defaultProfileNamespace) || apply.IfNamespaceExist(anonymousNamespace)) { msg := "Default user namespace pending creation..." log.Warnf(msg) return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: msg, } } return nil }, b) if err != nil { log.Warnf("Default namespace creation skipped") } return nil } // deleteGlobalResources is called from Delete and deletes CRDs, ClusterRoles, ClusterRoleBindings func (kustomize *kustomize) deleteGlobalResources() error { if err := kustomize.initK8sClients(); err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("kustomize plugin couldn't initialize a K8s client: %v", err), } } apiextclientset, err := crdclientset.NewForConfig(kustomize.restConfig) if err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't get apiextensions client: %v", err), } } do := &metav1.DeleteOptions{} lo := metav1.ListOptions{ LabelSelector: kftypesv3.DefaultAppLabel + "=" + kustomize.kfDef.Name, } crdsErr := apiextclientset.CustomResourceDefinitions().DeleteCollection(do, lo) if crdsErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't delete customresourcedefinitions: %v", crdsErr), } } rbacclient, err := rbacv1.NewForConfig(kustomize.restConfig) if err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't get rbac/v1 client: %v", err), } } crbsErr := rbacclient.ClusterRoleBindings().DeleteCollection(do, lo) if crbsErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't delete clusterrolebindings: %v", crbsErr), } } crsErr := rbacclient.ClusterRoles().DeleteCollection(do, lo) if crsErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't delete clusterroles: %v", crsErr), } } return nil } // Delete is called from 'kfctl delete ...'. Will delete all resources deployed from the Apply method func (kustomize *kustomize) Delete(resources kftypesv3.ResourceEnum) error { annotations := kustomize.kfDef.GetAnnotations() forceDelete := false if forceDel, ok := annotations[strings.Join([]string{utils.KfDefAnnotation, utils.ForceDelete}, "/")]; ok { if forceDelBool, err := strconv.ParseBool(forceDel); err == nil { forceDelete = forceDelBool } } if forceDelete { log.Warnf("Running force deletion.") } // Get bool value indicating whether this func is called from kubeflow operator byOperator := false if byOperatorAnn, ok := annotations[strings.Join([]string{utils.KfDefAnnotation, utils.InstallByOperator}, "/")]; ok { if byOperatorAnnBol, err := strconv.ParseBool(byOperatorAnn); err == nil { byOperator = byOperatorAnnBol } } // Get kubeconfig for cluster and initialize clients msg := "" kubeconfig := kftypesv3.GetKubeConfig() if kubeconfig == nil { msg = "unable to load .kubeconfig." } else { currentCtx := kubeconfig.CurrentContext if ctx, ok := kubeconfig.Contexts[currentCtx]; !ok || ctx == nil { msg = "cannot find current-context in kubeconfig." } else { if kustomize.kfDef.ClusterName != ctx.Cluster { msg = fmt.Sprintf("cluster name doesn't match: KfDef(%v) v.s. current-context(%v)", kustomize.kfDef.ClusterName, ctx.Cluster) } } } if msg != "" { if forceDelete { log.Warnf(msg) } else { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: msg, } } } kustomize.initK8sClients() kubeclient, err := client.New(kustomize.restConfig, client.Options{}) if err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error initializing k8s client: %v", err), } } // Delete in reverse application order kustomizeDir := path.Join(kustomize.kfDef.Spec.AppDir, outputDir) errList := []error{} for idx := range kustomize.kfDef.Spec.Applications { app := &kustomize.kfDef.Spec.Applications[len(kustomize.kfDef.Spec.Applications)-1-idx] log.Infof("Deleting application %v", app.Name) resMap, err := EvaluateKustomizeManifest(path.Join(kustomizeDir, app.Name)) if err != nil { log.Errorf("Error evaluating kustomization manifest for %v: %v", app.Name, err) return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error evaluating kustomization manifest for %v: %v", app.Name, err), } } // Sort resources by kind to make sure we don't experience namespace terminating hanging. sortResourceByKind(resMap, utils.UninstallOrder) yamlBytes, err := resMap.AsYaml() if err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error evaluating kustomization manifest for %v: %v", app.Name, err), } } resources, err := utils.SplitYAML(yamlBytes) if err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error splitting yaml: %v", err), } } for _, r := range resources { err := utils.DeleteResource(r, kubeclient, 5*time.Minute, byOperator) if err != nil { msg := fmt.Sprintf("error evaluating kustomization manifest for %v: %v", app.Name, err) errList = append(errList, errors.New(msg)) log.Warn(msg) } } } aggrError := errutil.NewAggregate(errList) if aggrError != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error deleting kustomize manifests: %v", aggrError), } } // Finally, delete the kubeflow namespace // TODO(yanniszark): Remove this once the Kubeflow namespace is created by kustomize manifests corev1client, err := corev1.NewForConfig(kustomize.restConfig) if err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't get core/v1 client: %v", err), } } namespace := kustomize.kfDef.Namespace ns, nsMissingErr := corev1client.Namespaces().Get(namespace, metav1.GetOptions{}) if nsMissingErr == nil { // if the func is called by the Kubeflow operator, validate it is installed through the operator if byOperator { anns := ns.GetAnnotations() kfdefAnn := strings.Join([]string{utils.KfDefAnnotation, utils.KfDefInstance}, "/") _, found := anns[kfdefAnn] if !found { return nil } } log.Infof("Deleting namespace: %v", namespace) nsErr := corev1client.Namespaces().Delete(ns.Name, metav1.NewDeleteOptions(int64(100))) if nsErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't delete namespace %v: %v", namespace, nsErr), } } } return nil } // sortResourceByKind does in-place sort of resources by Kind. func sortResourceByKind(resMap resmap.ResMap, order utils.SortOrder) { resourcesInUninstallOrder := utils.SortByKind(resMap.Resources(), order) // Need to remove existing resource and append them in order. allIdsToRemove := resMap.AllIds() for _, idToRemove := range allIdsToRemove { resMap.Remove(idToRemove) } for _, resourceToAdd := range resourcesInUninstallOrder { resMap.Append(resourceToAdd) } } // Generate is called from 'kfctl generate ...' and produces yaml output files under /kustomize. // One yaml file per component func (kustomize *kustomize) Generate(resources kftypesv3.ResourceEnum) error { generate := func() error { kustomizeDir := path.Join(kustomize.kfDef.Spec.AppDir, outputDir) if _, err := os.Stat(kustomizeDir); err == nil { // When using the new stacks code the directory might already exist because it could have // been created by calls to SetApplicationParameter. For the legacy code path (no stacks) we preserve // the existing code path of not rerunning generate if the directory already exists. if !kustomize.kfDef.UsingStacks() { // Noop if the directory already exists. log.Infof("Folder %v exists, skip kustomize.Generate", kustomizeDir) return nil } } else if !os.IsNotExist(err) { log.Errorf("Stat folder %v error: %v; try deleting it...", kustomizeDir, err) _ = os.RemoveAll(kustomizeDir) } kustomizeDirErr := os.MkdirAll(kustomizeDir, os.ModePerm) if kustomizeDirErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't create directory %v: %v", kustomizeDir, kustomizeDirErr), } } _, ok := kustomize.kfDef.GetRepoCache(kftypesv3.ManifestsRepoName) if !ok { log.Infof("Repo %v not listed in KfDef.Status; Resync'ing cache", kftypesv3.ManifestsRepoName) if err := kustomize.kfDef.SyncCache(); err != nil { log.Errorf("Syncing the cached failed: %v", err) return errors.WithStack(err) } } // Check again after sync _, ok = kustomize.kfDef.GetRepoCache(kftypesv3.ManifestsRepoName) if !ok { return errors.WithStack(fmt.Errorf("Repo %v not listed in KfDef.Status; ", kftypesv3.ManifestsRepoName)) } // determine whether we are using the new pattern of using kustomize to build stacks. // hasStack := kustomize.kfDef.UsingStacks() for _, app := range kustomize.kfDef.Spec.Applications { log.Infof("Processing application: %v", app.Name) if app.KustomizeConfig == nil { err := fmt.Errorf("application %v is missing KustomizeConfig", app.Name) log.Errorf("%v", err) return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: err.Error(), } } repoName := app.KustomizeConfig.RepoRef.Name repoCache, ok := kustomize.kfDef.GetRepoCache(repoName) if !ok { err := fmt.Errorf("application %v refers to repo %v which wasn't found in KfDef.Status.ReposCache", app.Name, repoName) log.Errorf("%v", err) return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: err.Error(), } } appPath := path.Join(repoCache.LocalPath, app.KustomizeConfig.RepoRef.Path) if kustomize.kfDef.UsingStacks() { if filepath.IsAbs(appPath) { // The appPath needs to be a relative path because we use it as a resource location in the kustomize // file appDir, err := filepath.Abs(kustomize.kfDef.Spec.AppDir) if err != nil { errors.WithStack(fmt.Errorf("There was a problem computing absolute path of %v; error; %v ", kustomize.kfDef.Spec.AppDir, err)) } relPath, err := filepath.Rel(appDir, appPath) if err != nil { errors.WithStack(fmt.Errorf("There was a problem computing filePath.Rel(%v, %v); error; %v ", appDir, appPath, err)) } appPath = relPath } // We handle generating the kustomize dir for application stacks differently. stackAppDir := path.Join(kustomizeDir, app.Name) // Path to the stack inside the cache. stacksCacheDir := filepath.Join("../..", appPath) if _, err := createStackAppKustomization(stackAppDir, stacksCacheDir); err != nil { return errors.WithStack(fmt.Errorf("There was a problem building the kustomize app for the Kubeflow application stack; %v ", err)) } } else { // TODO(jlewi): This code path should eventually go away once we are fully migrated to the use // of stacks. // Copy the component to kustomizeDir if err := copy.Copy(appPath, path.Join(kustomizeDir, app.Name)); err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't copy application %s: %v", app.Name, err), } } if err := GenerateKustomizationFile(kustomize.kfDef, kustomizeDir, app.Name, app.KustomizeConfig.Overlays, app.KustomizeConfig.Parameters); err != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't generate kustomization file for component %s: %v", app.Name, err), } } } } return nil } switch resources { case kftypesv3.PLATFORM: case kftypesv3.ALL: fallthrough case kftypesv3.K8S: generateErr := generate() if generateErr != nil { return fmt.Errorf("Kustomize generate failed: %v", generateErr) } } return nil } // createStackAppKustomization generates a kustomization.yaml file suitable for the kubeflow application stack. // stackAppDir is the directory to create for the kustomize package. // basePath is the path to the kustomize package to use as the base package. // // Returns the path to the kusotmizationFile. // // If the kustomization.yaml already exists then the changes are merged in. func createStackAppKustomization(stackAppDir string, basePath string) (string, error) { kustomizationFile := filepath.Join(stackAppDir, kftypesv3.KustomizationFile) if _, err := os.Stat(stackAppDir); err == nil { // Noop if the directory already exists. log.Infof("folder %v exists", stackAppDir) } else if os.IsNotExist(err) { log.Infof("Creating folder %v", stackAppDir) if stackAppDirErr := os.MkdirAll(stackAppDir, os.ModePerm); stackAppDirErr != nil { return "", &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't create directory %v Error %v", stackAppDir, stackAppDirErr), } } } else { return "", errors.WithStack(errors.Wrapf(err, "Unexpected error trying to access directory: %v", stackAppDir)) } kustomization := &types.Kustomization{} contents, err := ioutil.ReadFile(kustomizationFile) // The kustomization file may not exist yet in which case we keep going because we will just create it. if err == nil { if err := yaml.Unmarshal(contents, kustomization); err != nil { return "", errors.WithStack(errors.Wrapf(err, "Failed to unmashal %v", kustomizationFile)) } } else if err != nil && !os.IsNotExist(err) { return "", errors.WithStack(errors.Wrapf(err, "Failed to read: %v", kustomizationFile)) } // Create the kustomization file for the stack directory. // We explicitly do not set namespace because we want to use the default namespace set in each kustomize // application. kustomization.TypeMeta = types.TypeMeta{ Kind: "Kustomization", APIVersion: "kustomize.config.k8s.io/v1beta1", } hasBasePath := false for _, r := range kustomization.Resources { if string(r) == basePath { hasBasePath = true break } } if !hasBasePath { kustomization.Resources = append(kustomization.Resources, basePath) } yaml, err := yaml.Marshal(kustomization) if err != nil { return "", errors.WithStack(errors.Wrapf(err, "Error trying to marshal kustomization for kubeflow apps stack:")) } kustomizationFileErr := ioutil.WriteFile(kustomizationFile, yaml, 0644) if kustomizationFileErr != nil { return "", &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error writing to %v Error %v", kustomizationFile, kustomizationFileErr), } } return kustomizationFile, nil } // Init is called from 'kfctl init ...' and creates a directory with an app.yaml file that // holds deployment information like components, parameters func (kustomize *kustomize) Init(resources kftypesv3.ResourceEnum) error { return nil } // mapDirs is a recursive method that will return a map of component -> path-to-kustomization.yaml // under the manifests downloaded cache func (kustomize *kustomize) mapDirs(dirPath string, root bool, depth int, leafMap map[string]string) map[string]string { dirName := path.Base(dirPath) // package is component, stop here if depth == 1 && kustomize.packageMap[dirName] != nil && kustomize.componentMap[dirName] { subdirCheck := path.Join(dirPath, dirName) // border case manifests/jupyter/jupyter if _, err := os.Stat(subdirCheck); err != nil { leafMap[dirName] = dirName arrayOfComponents := *kustomize.packageMap[dirName] arrayOfComponents = append(arrayOfComponents, dirName) kustomize.packageMap[dirName] = &arrayOfComponents return leafMap } } files, err := ioutil.ReadDir(dirPath) if err != nil { return leafMap } for _, f := range files { if f.IsDir() { leafDir := path.Join(dirPath, f.Name()) if depth < 2 { kustomize.mapDirs(leafDir, false, depth+1, leafMap) } } } if depth == 2 { repoCache, ok := kustomize.kfDef.GetRepoCache(kftypesv3.ManifestsRepoName) if !ok { log.Fatal("Manifest repo not found in cache") } componentPath := extractSuffix(repoCache.LocalPath, dirPath) packageName := strings.Split(componentPath, "/")[0] if components, exists := kustomize.packageMap[packageName]; exists { leafMap[path.Base(dirPath)] = componentPath arrayOfComponents := *components arrayOfComponents = append(arrayOfComponents, dirName) kustomize.packageMap[packageName] = &arrayOfComponents } } return leafMap } func (kustomize *kustomize) SetK8sRestConfig(r *rest.Config) { kustomize.restConfig = r kustomize.configOverwrite = true } // GetKustomization will read a kustomization.yaml and return Kustomization type func GetKustomization(kustomizationPath string) *types.Kustomization { kustomizationFile := filepath.Join(kustomizationPath, kftypesv3.KustomizationFile) data, err := ioutil.ReadFile(kustomizationFile) if err != nil { log.Warnf("Cannot get kustomization from %v: %v", kustomizationPath, err) return nil } kustomization := &types.Kustomization{} if err = yaml.Unmarshal(data, kustomization); err != nil { log.Warnf("Cannot unmarshal kustomization from %v: %v", kustomizationPath, err) return nil } return kustomization } // ReadUnstructured will read a resource .yaml and return the Unstructured type func ReadUnstructured(kfDefFile string) (*unstructured.Unstructured, error) { data, err := ioutil.ReadFile(kfDefFile) if err != nil { return nil, err } def := &unstructured.Unstructured{} if err = yaml.Unmarshal(data, def); err != nil { return nil, err } return def, nil } // ReadKfDef will read a config .yaml and return the KfDef type func ReadKfDef(kfDefFile string) *kfdefsv3.KfDef { data, err := ioutil.ReadFile(kfDefFile) if err != nil { return nil } kfdef := &kfdefsv3.KfDef{} if err = yaml.Unmarshal(data, kfdef); err != nil { return nil } return kfdef } // WriteKfDef will write a KfDef to a config .yaml func WriteKfDef(kfdef *kfdefsv3.KfDef, kfdefpath string) error { data, err := yaml.Marshal(kfdef) if err != nil { return err } writeErr := ioutil.WriteFile(kfdefpath, data, 0644) if writeErr != nil { return writeErr } return nil } // MergeKustomization will merge the child into the parent // if the child has no bases, then the parent just needs to add the child as base // otherwise the parent needs to merge with behaviors // Multiple overlays are constrained in what they can merge // which exclude NamePrefixes, NameSuffixes, CommonLabels, CommonAnnotations. // Any of these will generate an error func MergeKustomization(compDir string, targetDir string, kfDef *kfconfig.KfConfig, params []kfconfig.NameValue, parent *types.Kustomization, child *types.Kustomization, kustomizationMaps map[MapType]map[string]bool) error { paramMap := make(map[string]string) for _, nv := range params { paramMap[nv.Name] = nv.Value } updateParamFiles := func() error { paramFile := filepath.Join(targetDir, kftypesv3.KustomizationParamFile) if _, err := os.Stat(paramFile); err == nil { params, paramFileErr := readLines(paramFile) if paramFileErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INVALID_ARGUMENT), Message: fmt.Sprintf("could not open %v: %v", paramFile, paramFileErr), } } // in params.env look for name=value that we can substitute from componentParams[component] // or if there is just namespace= or project= - fill in the values from KfDef for i, param := range params { paramName := strings.Split(param, "=")[0] if val, ok := paramMap[paramName]; ok && val != "" { switch paramName { case "generateName": arr := strings.Split(param, "=") if len(arr) == 1 || arr[1] == "" { b := make([]byte, 4) //equals 8 charachters rand.Read(b) s := hex.EncodeToString(b) val += s } } params[i] = paramName + "=" + val } else { switch paramName { case "appName": params[i] = paramName + "=" + kfDef.Name case "namespace": params[i] = paramName + "=" + kfDef.Namespace case "project": params[i] = paramName + "=" + kfDef.Spec.Project } } } paramFileErr = writeLines(params, paramFile) if paramFileErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("could not update %v: %v", paramFile, paramFileErr), } } } return nil } updateGeneratorArgs := func(parentGeneratorArgs *types.GeneratorArgs, childGeneratorArgs types.GeneratorArgs) { if childGeneratorArgs.EnvSources != nil && len(childGeneratorArgs.EnvSources) > 0 { parentGeneratorArgs.EnvSources = make([]string, 0) for _, envSource := range childGeneratorArgs.EnvSources { envAbsolutePathSource := path.Join(targetDir, envSource) parentGeneratorArgs.EnvSources = append(parentGeneratorArgs.EnvSources, extractSuffix(compDir, envAbsolutePathSource)) } } if childGeneratorArgs.EnvSource != "" { envAbsolutePathSource := path.Join(targetDir, childGeneratorArgs.EnvSource) envSource := extractSuffix(compDir, envAbsolutePathSource) parentGeneratorArgs.EnvSource = envSource } if childGeneratorArgs.FileSources != nil && len(childGeneratorArgs.FileSources) > 0 { parentGeneratorArgs.FileSources = make([]string, 0) for _, fileSource := range childGeneratorArgs.FileSources { fileAbsolutePathSource := path.Join(targetDir, fileSource) parentGeneratorArgs.EnvSource = extractSuffix(compDir, fileAbsolutePathSource) } } if childGeneratorArgs.LiteralSources != nil && len(childGeneratorArgs.LiteralSources) > 0 { parentGeneratorArgs.LiteralSources = make([]string, 0) for _, literalSource := range childGeneratorArgs.LiteralSources { parentGeneratorArgs.LiteralSources = append(parentGeneratorArgs.LiteralSources, literalSource) } } } updateConfigMapArgs := func(parentConfigMapArgs *types.ConfigMapArgs, childConfigMapArgs types.ConfigMapArgs) { parentConfigMapArgs.Name = childConfigMapArgs.Name parentConfigMapArgs.Namespace = childConfigMapArgs.Namespace updateGeneratorArgs(&parentConfigMapArgs.GeneratorArgs, childConfigMapArgs.GeneratorArgs) behavior := types.NewGenerationBehavior(childConfigMapArgs.Behavior) switch behavior { case types.BehaviorCreate: if _, ok := kustomizationMaps[configMapGeneratorMap][childConfigMapArgs.Name]; !ok { parent.ConfigMapGenerator = append(parent.ConfigMapGenerator, *parentConfigMapArgs) kustomizationMaps[configMapGeneratorMap][childConfigMapArgs.Name] = true } case types.BehaviorMerge, types.BehaviorReplace, types.BehaviorUnspecified: fallthrough default: parentConfigMapArgs.Behavior = behavior.String() parent.ConfigMapGenerator = append(parent.ConfigMapGenerator, *parentConfigMapArgs) kustomizationMaps[configMapGeneratorMap][childConfigMapArgs.Name] = true } } if err := updateParamFiles(); err != nil { return err } if child.Bases == nil { basePath := extractSuffix(compDir, targetDir) if _, ok := kustomizationMaps[basesMap][basePath]; !ok { parent.Bases = append(parent.Bases, basePath) kustomizationMaps[basesMap][basePath] = true } return nil } for _, value := range child.Bases { baseAbsolutePath := path.Join(targetDir, value) basePath := extractSuffix(compDir, baseAbsolutePath) if _, ok := kustomizationMaps[basesMap][basePath]; !ok { parent.Bases = append(parent.Bases, basePath) kustomizationMaps[basesMap][basePath] = true } else { childPath := extractSuffix(compDir, targetDir) kustomizationMaps[basesMap][childPath] = true } } if child.NamePrefix != "" && parent.NamePrefix == "" { parent.NamePrefix = child.NamePrefix } if child.NameSuffix != "" && parent.NameSuffix == "" { parent.NameSuffix = child.NameSuffix } for k, v := range child.CommonLabels { //allow replacement parent.CommonLabels[k] = v kustomizationMaps[commonLabelsMap][k] = true } for k, v := range child.CommonAnnotations { //allow replacement parent.CommonAnnotations[k] = v kustomizationMaps[commonAnnotationsMap][k] = true } if child.GeneratorOptions != nil && parent.GeneratorOptions == nil { parent.GeneratorOptions = child.GeneratorOptions } for _, value := range child.Resources { resourceAbsoluteFile := filepath.Join(targetDir, string(value)) resourceFile := extractSuffix(compDir, resourceAbsoluteFile) if _, ok := kustomizationMaps[resourcesMap][resourceFile]; !ok { parent.Resources = append(parent.Resources, resourceFile) kustomizationMaps[resourcesMap][resourceFile] = true } } for _, value := range child.Images { imageName := value.Name if _, ok := kustomizationMaps[imagesMap][imageName]; !ok { parent.Images = append(parent.Images, value) kustomizationMaps[imagesMap][imageName] = true } else { kFile := filepath.Join(targetDir, kftypesv3.KustomizationFile) log.Warnf("Ignoring image %v specified in %v", imageName, kFile) } } for _, value := range child.Crds { if _, ok := kustomizationMaps[crdsMap][value]; !ok { parent.Crds = append(parent.Crds, value) kustomizationMaps[crdsMap][value] = true } else { kFile := filepath.Join(targetDir, kftypesv3.KustomizationFile) log.Warnf("Ignoring crd %v specified in %v", value, kFile) } } for _, value := range child.ConfigMapGenerator { parentConfigMapArgs := new(types.ConfigMapArgs) updateConfigMapArgs(parentConfigMapArgs, value) } for _, value := range child.SecretGenerator { secretName := value.Name secretBehavior := types.NewGenerationBehavior(value.Behavior) updateGeneratorArgs(&value.GeneratorArgs, value.GeneratorArgs) switch secretBehavior { case types.BehaviorCreate: if _, ok := kustomizationMaps[secretsMapGeneratorMap][secretName]; !ok { parent.SecretGenerator = append(parent.SecretGenerator, value) kustomizationMaps[secretsMapGeneratorMap][secretName] = true } case types.BehaviorMerge, types.BehaviorReplace: parent.SecretGenerator = append(parent.SecretGenerator, value) kustomizationMaps[secretsMapGeneratorMap][secretName] = true default: value.Behavior = secretBehavior.String() parent.SecretGenerator = append(parent.SecretGenerator, value) kustomizationMaps[secretsMapGeneratorMap][secretName] = true } } for _, value := range child.Vars { varName := value.Name if _, ok := kustomizationMaps[varsMap][varName]; !ok { parent.Vars = append(parent.Vars, value) kustomizationMaps[varsMap][varName] = true } else { kFile := filepath.Join(targetDir, kftypesv3.KustomizationFile) log.Warnf("Ignoring var %v specified in %v", varName, kFile) } } for _, value := range child.PatchesStrategicMerge { patchAbsoluteFile := filepath.Join(targetDir, string(value)) patchFile := extractSuffix(compDir, patchAbsoluteFile) if _, ok := kustomizationMaps[patchesStrategicMergeMap][patchFile]; !ok { patchFileCasted := types.PatchStrategicMerge(patchFile) parent.PatchesStrategicMerge = append(parent.PatchesStrategicMerge, patchFileCasted) kustomizationMaps[patchesStrategicMergeMap][patchFile] = true } } // json patches are aggregated and merged into local patch files for _, value := range child.PatchesJson6902 { patchJson := new(types.PatchJson6902) patchJson.Target = value.Target patchAbsolutePath := filepath.Join(targetDir, value.Path) patchJson.Path = extractSuffix(compDir, patchAbsolutePath) // patchJson.Path can be used for multiple targets, hence kustomizationMaps key is patchJson.Path+"-"+patchJson.Target.Name" patchJsonMapKey := patchJson.Path + "-" + patchJson.Target.Name if _, ok := kustomizationMaps[patchesJson6902Map][patchJsonMapKey]; !ok { parent.PatchesJson6902 = append(parent.PatchesJson6902, *patchJson) kustomizationMaps[patchesJson6902Map][patchJsonMapKey] = true } } for _, value := range child.Configurations { configurationAbsolutePath := filepath.Join(targetDir, value) configurationPath := extractSuffix(compDir, configurationAbsolutePath) if _, ok := kustomizationMaps[configurationsMap][configurationPath]; !ok { parent.Configurations = append(parent.Configurations, configurationPath) kustomizationMaps[configurationsMap][configurationPath] = true } } return nil } // MergeKustomizations will merge base and all overlay kustomization files into // a single kustomization file func MergeKustomizations(kfDef *kfconfig.KfConfig, compDir string, overlayParams []string, params []kfconfig.NameValue) (*types.Kustomization, error) { kustomizationMaps := CreateKustomizationMaps() kustomization := &types.Kustomization{ TypeMeta: types.TypeMeta{ APIVersion: types.KustomizationVersion, Kind: types.KustomizationKind, }, Bases: make([]string, 0), CommonLabels: make(map[string]string), CommonAnnotations: make(map[string]string), PatchesStrategicMerge: make([]types.PatchStrategicMerge, 0), PatchesJson6902: make([]types.PatchJson6902, 0), Images: make([]image.Image, 0), Vars: make([]types.Var, 0), Crds: make([]string, 0), Resources: make([]string, 0), ConfigMapGenerator: make([]types.ConfigMapArgs, 0), SecretGenerator: make([]types.SecretArgs, 0), Configurations: make([]string, 0), } baseDir := path.Join(compDir, "base") base := GetKustomization(baseDir) if base == nil { comp := GetKustomization(compDir) if comp != nil { return comp, nil } } else { err := MergeKustomization(compDir, baseDir, kfDef, params, kustomization, base, kustomizationMaps) if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error merging kustomization at %v: %v", baseDir, err), } } } if params != nil { for _, nv := range params { name := nv.Name switch name { case "namespace": kustomization.Namespace = nv.Value } } } for _, overlayParam := range overlayParams { overlayDir := path.Join(compDir, "overlays", overlayParam) if _, err := os.Stat(overlayDir); err == nil { err := MergeKustomization(compDir, overlayDir, kfDef, params, kustomization, GetKustomization(overlayDir), kustomizationMaps) if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error merging kustomization at %v: %v", overlayDir, err), } } } else { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("no overlay %v for component at %v: %v", overlayParam, compDir, err), } } } if len(kustomization.PatchesJson6902) > 0 { patches := map[string][]types.PatchJson6902{} for _, jsonPatch := range kustomization.PatchesJson6902 { key := jsonPatch.Target.Name + "-" + jsonPatch.Target.Kind if _, exists := patches[key]; !exists { patchArray := make([]types.PatchJson6902, 0) patchArray = append(patchArray, jsonPatch) patches[key] = patchArray } else { patches[key] = append(patches[key], jsonPatch) } } kustomization.PatchesJson6902 = make([]types.PatchJson6902, 0) patchFile := "" for key, values := range patches { aggregatedPatch := new(types.PatchJson6902) aggregatedPatch.Path = key + ".yaml" patchFile = path.Join(compDir, aggregatedPatch.Path) aggregatedPatch.Target = new(types.PatchTarget) aggregatedPatch.Target.Name = values[0].Target.Name aggregatedPatch.Target.Namespace = values[0].Target.Namespace aggregatedPatch.Target.Group = values[0].Target.Group aggregatedPatch.Target.Version = values[0].Target.Version aggregatedPatch.Target.Kind = values[0].Target.Kind aggregatedPatch.Target.Gvk = values[0].Target.Gvk for _, eachPatch := range values { patchPath := path.Join(compDir, eachPatch.Path) if _, err := os.Stat(patchPath); err == nil { data, err := ioutil.ReadFile(patchPath) if err != nil { return nil, err } f, patchErr := os.OpenFile(patchFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if patchErr != nil { return nil, patchErr } if _, err := f.Write(data); err != nil { f.Close() return nil, err } if err := f.Close(); err != nil { return nil, err } } } kustomization.PatchesJson6902 = append(kustomization.PatchesJson6902, *aggregatedPatch) } } return kustomization, nil } // GenerateKustomizationFile will create a kustomization.yaml // It will parse a args structure that provides mixin or multiple overlays to be merged with the base kustomization file // for example // // componentParams: // tf-job-operator: // - name: overlay // value: namespaced-gangscheduled // // TODO(https://github.com/kubeflow/kubeflow/issues/3491): As part of fixing the discovery // logic we should change the KfDef spec to provide a list of applications (not a map). // and preserve order when applying them so we can get rid of the logic hard-coding // moving some applications to the front. // // TODO(jlewi): Why is the path split between root and compPath? // TODO(jlewi): Why is this taking kfDef and writing kfDef? Is this because it is reordering components? // TODO(jlewi): This function appears to special case handling of using kustomize // for KfDef. Presumably this is because of the code in coordinator which is using it to generate // KfDef from overlays. But this function is also used to generate the manifests for the individual // kustomize packages. func GenerateKustomizationFile(kfDef *kfconfig.KfConfig, root string, compPath string, overlays []string, params []kfconfig.NameValue) error { moveToFront := func(item string, list []string) []string { olen := len(list) newlist := make([]string, 0) for i, component := range list { if component == item { newlist = append(newlist, list[i]) newlist = append(newlist, list[0:i]...) newlist = append(newlist, list[i+1:olen]...) break } } return newlist } compDir := path.Join(root, compPath) kustomization, kustomizationErr := MergeKustomizations(kfDef, compDir, overlays, params) if kustomizationErr != nil { return kustomizationErr } if kustomization.Namespace == "" { kustomization.Namespace = kfDef.Namespace } //TODO(#2685) we may want to delegate this to separate tooling so kfctl is not dynamically mixing in overlays. if len(kustomization.PatchesStrategicMerge) > 0 { basename := filepath.Base(string(kustomization.PatchesStrategicMerge[0])) basefile := filepath.Join(compDir, "base", basename) def, err := ReadUnstructured(basefile) if err != nil { return err } apiVersion := def.GetAPIVersion() if apiVersion == kfDef.APIVersion { // This code is only invoked when using Kustomize to generate the KFDef spec. baseKfDef := ReadKfDef(basefile) for _, k := range kustomization.PatchesStrategicMerge { overlayfile := filepath.Join(compDir, string(k)) overlay := ReadKfDef(overlayfile) mergeErr := mergo.Merge(&baseKfDef.Spec, overlay.Spec, mergo.WithAppendSlice) if mergeErr != nil { return mergeErr } } //TODO look at sort options //See https://github.com/kubernetes-sigs/kustomize/issues/821 //TODO upgrade to v2.0.4 when available baseKfDef.Spec.Components = moveToFront("application", baseKfDef.Spec.Components) baseKfDef.Spec.Components = moveToFront("application-crds", baseKfDef.Spec.Components) baseKfDef.Spec.Components = moveToFront("istio", baseKfDef.Spec.Components) baseKfDef.Spec.Components = moveToFront("istio-install", baseKfDef.Spec.Components) baseKfDef.Spec.Components = moveToFront("istio-crds", baseKfDef.Spec.Components) writeErr := WriteKfDef(baseKfDef, basefile) if writeErr != nil { return writeErr } kustomization.PatchesStrategicMerge = nil } } buf, bufErr := yaml.Marshal(kustomization) if bufErr != nil { return bufErr } kustomizationPath := filepath.Join(compDir, kftypesv3.KustomizationFile) kustomizationPathErr := ioutil.WriteFile(kustomizationPath, buf, 0644) return kustomizationPathErr } // EvaluateKustomizeManifest evaluates the kustomize dir compDir, and returns the resources. func EvaluateKustomizeManifest(compDir string) (resmap.ResMap, error) { fsys := fs.MakeRealFS() // We don't enforce the security check because our kustomize packages are such that kustomization.yaml // files may refer to patches and resources that are not in the current directory or below them. // See http://bit.ly/kf_kustomize_v3 lrc := loader.RestrictionNone ldr, err := loader.NewLoader(lrc, validators.MakeFakeValidator(), compDir, fsys) if err != nil { return nil, err } defer ldr.Cleanup() rf := resmap.NewFactory(resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()), transformer.NewFactoryImpl()) pc := plugins.DefaultPluginConfig() kt, err := target.NewKustTarget(ldr, rf, transformer.NewFactoryImpl(), plugins.NewLoader(pc, rf)) if err != nil { return nil, err } allResources, err := kt.MakeCustomizedResMap() if err != nil { return nil, err } err = builtin.NewLegacyOrderTransformerPlugin().Transform(allResources) if err != nil { return nil, err } return allResources, nil } func WriteKustomizationFile(name string, kustomizeDir string, resMap resmap.ResMap) error { // Output the objects. yamlResources, yamlResourcesErr := resMap.AsYaml() if yamlResourcesErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error generating yaml: %v", yamlResourcesErr), } } kustomizeFile := filepath.Join(kustomizeDir, name+".yaml") kustomizationFileErr := ioutil.WriteFile(kustomizeFile, yamlResources, 0644) if kustomizationFileErr != nil { return &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("error writing to %v: %v", kustomizeFile, kustomizationFileErr), } } return nil } // readLines reads a file into an array of strings func readLines(path string) ([]string, error) { var file, err = os.Open(path) if err != nil { return nil, err } defer file.Close() var lines []string scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) } return lines, scanner.Err() } // writeLines writes a string array to the given file - one line per array entry. func writeLines(lines []string, path string) error { file, err := os.Create(path) if err != nil { return err } defer file.Close() w := bufio.NewWriter(file) for _, line := range lines { fmt.Fprintln(w, line) } return w.Flush() } // extractSuffix will return the non-overlapped part of 2 paths eg // /foo/bar/baz/zed and /foo/bar/ will return baz/zed func extractSuffix(dirPath string, subDirPath string) string { suffix := strings.TrimPrefix(subDirPath, dirPath)[1:] return suffix } func CreateKustomizationMaps() map[MapType]map[string]bool { return map[MapType]map[string]bool{ basesMap: make(map[string]bool), commonAnnotationsMap: make(map[string]bool), commonLabelsMap: make(map[string]bool), imagesMap: make(map[string]bool), resourcesMap: make(map[string]bool), crdsMap: make(map[string]bool), varsMap: make(map[string]bool), configurationsMap: make(map[string]bool), configMapGeneratorMap: make(map[string]bool), secretsMapGeneratorMap: make(map[string]bool), patchesStrategicMergeMap: make(map[string]bool), patchesJson6902Map: make(map[string]bool), } } // GenerateYamlWithOperatorAnnotation adds operator info to the annotation to every resource // some code copied from ResMap.AsYaml() func func GenerateYamlWithOperatorAnnotation(resMap resmap.ResMap, instance *unstructured.Unstructured) ([]byte, error) { firstObj := true var b []byte buf := bytes.NewBuffer(b) for _, res := range resMap.Resources() { y, err := res.AsYAML() if err != nil { return nil, err } m := &unstructured.Unstructured{} if err = yaml.Unmarshal(y, m); err != nil { return nil, err } anns := m.GetAnnotations() if anns == nil { anns = map[string]string{} } kfdefAnn := strings.Join([]string{utils.KfDefAnnotation, utils.KfDefInstance}, "/") kfdefCr := strings.Join([]string{instance.GetName(), instance.GetNamespace()}, ".") addAnnotation := true if m.GetKind() == "Namespace" { config, _ := rest.InClusterConfig() corev1client, err := corev1.NewForConfig(config) if err != nil { return nil, &kfapisv3.KfError{ Code: int(kfapisv3.INTERNAL_ERROR), Message: fmt.Sprintf("failed to create corev1 client: %v", err), } } ns, err := corev1client.Namespaces().Get(m.GetName(), metav1.GetOptions{}) if err == nil { log.Infof("Namespace %v already exists.", m.GetName()) nsAnns := ns.GetAnnotations() if nsAnns == nil { addAnnotation = false } else { _, found := nsAnns[kfdefAnn] if !found || nsAnns[kfdefAnn] != kfdefCr { // if the namespace is not created by this operator, should not append the annotation addAnnotation = false } } } } else if m.GetKind() == "CustomResourceDefinition" && m.GetName() == "profiles.kubeflow.org" { // profiles will contain user info and data, should not remove during uninstall addAnnotation = false } if addAnnotation { anns[kfdefAnn] = kfdefCr m.SetAnnotations(anns) } out, err := yaml.Marshal(m) if err != nil { return nil, err } if addAnnotation { log.Infof("KfDef annotation added for resource %v.%v", m.GetName(), m.GetNamespace()) } if firstObj { firstObj = false } else { if _, err = buf.WriteString("---\n"); err != nil { return nil, err } } if _, err = buf.Write(out); err != nil { return nil, err } } return buf.Bytes(), nil } ================================================ FILE: pkg/kfapp/kustomize/kustomize_test.go ================================================ package kustomize import ( "github.com/ghodss/yaml" "github.com/google/go-cmp/cmp" "io/ioutil" "os" "path" "path/filepath" "sigs.k8s.io/kustomize/v3/pkg/types" "strings" "testing" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/otiai10/copy" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) // This test tests that GenerateKustomizationFile will produce correct kustomization.yaml func TestGenerateKustomizationFile(t *testing.T) { type testCase struct { kfDef *kfconfig.KfConfig params []kfconfig.NameValue // The directory of a (testing) kustomize package packageDir string overlays []string // Expected kustomization.yaml expectedFile string } testCases := []testCase{ { kfDef: &kfconfig.KfConfig{ ObjectMeta: metav1.ObjectMeta{ Namespace: "kubeflow", }, Spec: kfconfig.KfConfigSpec{}, }, overlays: []string{ "application", }, packageDir: "testdata/kustomizeExample/pytorch-operator", expectedFile: "testdata/kustomizeExample/pytorch-operator/expected/kustomization.yaml", }, { kfDef: &kfconfig.KfConfig{ ObjectMeta: metav1.ObjectMeta{ Namespace: "kubeflow", }, Spec: kfconfig.KfConfigSpec{}, }, overlays: []string{ "istio", "application", "db", }, packageDir: "testdata/kustomizeExample/metadata", expectedFile: "testdata/kustomizeExample/metadata/expected/kustomization.yaml", }, } packageName := "dummy" for _, c := range testCases { testDir, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } t.Logf("testdir: %v", testDir) err = copy.Copy(c.packageDir, path.Join(testDir, packageName)) if err != nil { t.Fatalf("Failed to copy package to temp dir: %v", err) } err = GenerateKustomizationFile(c.kfDef, testDir, packageName, c.overlays, c.params) if err != nil { t.Fatalf("Failed to GenerateKustomizationFile: %v", err) } data, err := ioutil.ReadFile(path.Join(testDir, packageName, "kustomization.yaml")) if err != nil { t.Fatalf("Failed to read kustomization.yaml: %v", err) } expected, err := ioutil.ReadFile(c.expectedFile) if err != nil { t.Fatalf("Failed to read expected kustomization.yaml: %v", err) } if diff := cmp.Diff(expected, data); diff != "" { t.Fatalf("kustomization.yaml is different from expected. (-want, +got):\n%s", diff) } } } // TestGenerateYamlWithOperatorAnnotation func TestGenerateYamlWithOperatorAnnotation(t *testing.T) { type testCase struct { appDir string expected string } testCases := []testCase{ { appDir: "testdata/operator", expected: "testdata/operator/expected/service.yaml", }, } instance := &unstructured.Unstructured{} instance.SetAPIVersion("kfdef.apps.kubeflow.org/v1") instance.SetKind("KfDef") instance.SetName("operator") instance.SetNamespace("kubeflow") for _, c := range testCases { resMap, err := EvaluateKustomizeManifest(c.appDir) if err != nil { t.Fatalf("Failed to evaluate manifest. Error: %v.", err) } actual, err := GenerateYamlWithOperatorAnnotation(resMap, instance) if err != nil { t.Fatalf("Failed to add owner reference. Error: %v.", err) } expected, err := ioutil.ReadFile(c.expected) if err != nil { t.Fatalf("Failed to read expected file. Error: %v", err) } if diff := cmp.Diff(expected, actual); diff != "" { t.Fatalf("Set operator annotation is different from expected. (-want, +got):\n%s", diff) } } } func TestCreateStackAppKustomization(t *testing.T) { type testCase struct { Name string Input *types.Kustomization BasePath string Expected *types.Kustomization } testCases := []testCase{ { Name: "no-kustomization", Input: nil, BasePath: "../../.cache/stacks/gcp", Expected: &types.Kustomization{ TypeMeta: types.TypeMeta{ APIVersion: "kustomize.config.k8s.io/v1beta1", Kind: "Kustomization", }, Resources: []string{ "../../.cache/stacks/gcp", }, }, }, { Name: "merge-kustomization", Input: &types.Kustomization{ PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("some-patch.yaml"), }, }, BasePath: "../../.cache/stacks/gcp", Expected: &types.Kustomization{ TypeMeta: types.TypeMeta{ APIVersion: "kustomize.config.k8s.io/v1beta1", Kind: "Kustomization", }, Resources: []string{ "../../.cache/stacks/gcp", }, PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("some-patch.yaml"), }, }, }, } for _, c := range testCases { testDir, err := ioutil.TempDir("", "testCreateStackAppKustomization-"+c.Name+"-") if err != nil { t.Fatalf("Failed to create temp dir: %v", err) } t.Logf("testdir: %v", testDir) if c.Input != nil { contents, err := yaml.Marshal(c.Input) if err != nil { t.Fatalf("Error marshalling input kustomization: error; %v", err) } if err := ioutil.WriteFile(filepath.Join(testDir, "kustomization.yaml"), contents, os.ModePerm); err != nil { t.Fatalf("Error writing kustomization: error; %v", err) } } kustomizationFile, err := createStackAppKustomization(testDir, c.BasePath) if err != nil { t.Fatalf("Failed to create kustomization.yaml for Kubeflow apps stack: %v", err) } data, err := ioutil.ReadFile(kustomizationFile) if err != nil { t.Fatalf("Case %v: Failed to read %v: %v", c.Name, kustomizationFile, err) } expected, err := yaml.Marshal(c.Expected) if err != nil { t.Fatalf("Failed to marshal expected value: %v", err) } expectedStr := strings.TrimSpace(string(expected)) dataStr := strings.TrimSpace(string(data)) if diff := cmp.Diff(expectedStr, dataStr); diff != "" { t.Fatalf("kustomization.yaml is different from expected. (-want, +got):\n%s", diff) } } } ================================================ FILE: pkg/kfapp/kustomize/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/grpc-params.env ================================================ METADATA_GRPC_SERVICE_HOST=metadata-grpc-service METADATA_GRPC_SERVICE_PORT=8080 ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/kustomization.yaml ================================================ namePrefix: metadata- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: kustomize.component: metadata configMapGenerator: - name: ui-parameters envs: - params.env - name: grpc-configmap envs: - grpc-params.env generatorOptions: # TFX pipelines use metadata-grpc-configmap for finding grpc server host and # port at runtime. Because they don't know the suffix, we have to disable it. disableNameSuffixHash: true resources: - metadata-deployment.yaml - metadata-service.yaml - metadata-ui-deployment.yaml - metadata-ui-role.yaml - metadata-ui-rolebinding.yaml - metadata-ui-sa.yaml - metadata-ui-service.yaml - metadata-envoy-deployment.yaml - metadata-envoy-service.yaml namespace: kubeflow vars: # These vars are used internally for the kustomize package. # i.e to substitute values into fields kustomize isn't aware of. # The names should be unique enough that we don't get conflicts with other packages - name: ui-namespace objref: kind: Service name: ui apiVersion: v1 fieldref: fieldpath: metadata.namespace - name: ui-clusterDomain objref: kind: ConfigMap name: ui-parameters version: v1 fieldref: fieldpath: data.uiClusterDomain - name: metadata-service objref: kind: Service name: ui apiVersion: v1 fieldref: fieldpath: metadata.name - name: metadata-envoy-service objref: kind: Service name: envoy-service apiVersion: v1 fieldref: fieldpath: metadata.name images: - name: gcr.io/kubeflow-images-public/metadata newName: gcr.io/kubeflow-images-public/metadata newTag: v0.1.11 - name: gcr.io/tfx-oss-public/ml_metadata_store_server newName: gcr.io/tfx-oss-public/ml_metadata_store_server newTag: v0.21.1 - name: gcr.io/ml-pipeline/envoy newName: gcr.io/ml-pipeline/envoy newTag: metadata-grpc - name: mysql newName: mysql newTag: 8.0.3 - name: gcr.io/kubeflow-images-public/metadata-frontend newName: gcr.io/kubeflow-images-public/metadata-frontend newTag: v0.1.8 ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: deployment labels: component: server spec: replicas: 1 selector: matchLabels: component: server template: metadata: labels: component: server annotations: sidecar.istio.io/inject: "false" spec: containers: - name: container image: gcr.io/kubeflow-images-public/metadata:v0.1.11 command: ["./server/server", "--http_port=8080"] ports: - name: backendapi containerPort: 8080 readinessProbe: httpGet: path: /api/v1alpha1/artifact_types port: backendapi httpHeaders: - name: ContentType value: application/json initialDelaySeconds: 3 periodSeconds: 5 timeoutSeconds: 2 livenessProbe: httpGet: path: /api/v1alpha1/artifact_types port: backendapi httpHeaders: - name: ContentType value: application/json initialDelaySeconds: 3 periodSeconds: 5 timeoutSeconds: 2 --- apiVersion: apps/v1 kind: Deployment metadata: name: grpc-deployment labels: component: grpc-server spec: replicas: 1 selector: matchLabels: component: grpc-server template: metadata: labels: component: grpc-server annotations: sidecar.istio.io/inject: "false" spec: containers: - name: container envFrom: - configMapRef: name: grpc-configmap image: gcr.io/tfx-oss-public/ml_metadata_store_server:v0.21.1 command: ["/bin/metadata_store_server"] args: ["--grpc_port=$(METADATA_GRPC_SERVICE_PORT)"] ports: - name: grpc-backendapi containerPort: 8080 #The value of the port number needs to be in sync with value specified in grpc-params.env ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-envoy-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: envoy-deployment labels: component: envoy spec: replicas: 1 selector: matchLabels: component: envoy template: metadata: labels: component: envoy annotations: sidecar.istio.io/inject: "false" spec: containers: - name: container image: gcr.io/ml-pipeline/envoy:metadata-grpc ports: - name: md-envoy containerPort: 9090 - name: envoy-admin containerPort: 9901 ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-envoy-service.yaml ================================================ kind: Service apiVersion: v1 metadata: labels: app: metadata name: envoy-service spec: selector: component: envoy type: ClusterIP ports: - port: 9090 protocol: TCP name: md-envoy ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-service.yaml ================================================ kind: Service apiVersion: v1 metadata: labels: app: metadata name: service spec: selector: component: server type: ClusterIP ports: - port: 8080 protocol: TCP name: backendapi --- kind: Service apiVersion: v1 metadata: labels: app: grpc-metadata name: grpc-service spec: selector: component: grpc-server type: ClusterIP ports: - port: 8080 protocol: TCP name: grpc-backendapi ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: ui labels: app: metadata-ui spec: selector: matchLabels: app: metadata-ui template: metadata: name: ui labels: app: metadata-ui annotations: sidecar.istio.io/inject: "false" spec: containers: - image: gcr.io/kubeflow-images-public/metadata-frontend:v0.1.8 imagePullPolicy: IfNotPresent name: metadata-ui ports: - containerPort: 3000 serviceAccountName: ui ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-role.yaml ================================================ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: labels: app: metadata-ui name: ui rules: - apiGroups: - "" resources: - pods - pods/log verbs: - create - get - list - apiGroups: - "kubeflow.org" resources: - viewers verbs: - create - get - list - watch - delete ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-rolebinding.yaml ================================================ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: labels: app: metadata-ui name: ui roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ui subjects: - kind: ServiceAccount name: ui namespace: kubeflow ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-sa.yaml ================================================ apiVersion: v1 kind: ServiceAccount metadata: name: ui ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/metadata-ui-service.yaml ================================================ apiVersion: v1 kind: Service metadata: name: ui labels: app: metadata-ui spec: ports: - port: 80 targetPort: 3000 selector: app: metadata-ui ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/base/params.env ================================================ uiClusterDomain=cluster.local ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/expected/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 bases: - base commonLabels: app.kubernetes.io/component: metadata app.kubernetes.io/name: metadata kustomize.component: metadata configMapGenerator: - behavior: unspecified envs: - overlays/db/params.env name: metadata-db-parameters configurations: - overlays/istio/params.yaml generatorOptions: disableNameSuffixHash: true images: - name: mysql newName: mysql newTag: 8.0.3 kind: Kustomization namespace: kubeflow patchesStrategicMerge: - overlays/db/metadata-deployment.yaml resources: - overlays/istio/virtual-service.yaml - overlays/istio/virtual-service-metadata-grpc.yaml - overlays/application/application.yaml - overlays/db/metadata-db-pvc.yaml - overlays/db/metadata-db-deployment.yaml - overlays/db/metadata-db-service.yaml secretGenerator: - behavior: unspecified envs: - overlays/db/secrets.env name: metadata-db-secrets vars: - fieldref: fieldPath: metadata.name name: metadata-db-service objref: apiVersion: v1 kind: Service name: metadata-db ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/application/application.yaml ================================================ apiVersion: app.k8s.io/v1beta1 kind: Application metadata: name: metadata spec: addOwnerRef: true componentKinds: - group: core kind: Service - group: apps kind: Deployment - group: core kind: ConfigMap - group: core kind: ServiceAccount descriptor: description: Tracking and managing metadata of machine learning workflows in Kubeflow. keywords: - metadata links: - description: Docs url: https://www.kubeflow.org/docs/components/misc/metadata/ maintainers: - email: zhenghui@google.com name: Zhenghui Wang owners: - email: ajaygopinathan@google.com name: Ajay Gopinathan - email: zhenghui@google.com name: Zhenghui Wang type: metadata version: alpha selector: matchLabels: app.kubernetes.io/component: metadata app.kubernetes.io/instance: metadata-0.2.1 app.kubernetes.io/managed-by: kfctl app.kubernetes.io/name: metadata app.kubernetes.io/part-of: kubeflow app.kubernetes.io/version: 0.2.1 ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/application/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 bases: - ../../base commonLabels: app.kubernetes.io/component: metadata app.kubernetes.io/name: metadata kind: Kustomization resources: - application.yaml ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: kustomize.component: metadata namespace: kubeflow generatorOptions: # name suffix hash is not propagated correctly to base resources disableNameSuffixHash: true configMapGenerator: - name: metadata-db-parameters envs: - params.env secretGenerator: - name: metadata-db-secrets envs: - secrets.env bases: - ../../base resources: - metadata-db-pvc.yaml - metadata-db-deployment.yaml - metadata-db-service.yaml patchesStrategicMerge: - metadata-deployment.yaml images: - name: mysql newName: mysql newTag: 8.0.3 vars: - name: metadata-db-service objref: kind: Service name: metadata-db apiVersion: v1 fieldref: fieldpath: metadata.name ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-db-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: metadata-db labels: component: db spec: selector: matchLabels: component: db replicas: 1 template: metadata: name: db labels: component: db annotations: sidecar.istio.io/inject: "false" spec: containers: - name: db-container image: mysql:8.0.3 args: - --datadir - /var/lib/mysql/datadir envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets ports: - name: dbapi containerPort: 3306 readinessProbe: exec: command: - "/bin/bash" - "-c" - "mysql -D $$MYSQL_DATABASE -p$$MYSQL_ROOT_PASSWORD -e 'SELECT 1'" initialDelaySeconds: 5 periodSeconds: 2 timeoutSeconds: 1 volumeMounts: - name: metadata-mysql mountPath: /var/lib/mysql volumes: - name: metadata-mysql persistentVolumeClaim: claimName: metadata-mysql ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-db-pvc.yaml ================================================ apiVersion: v1 kind: PersistentVolumeClaim metadata: name: metadata-mysql spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-db-service.yaml ================================================ apiVersion: v1 kind: Service metadata: name: metadata-db labels: component: db spec: type: ClusterIP ports: - port: 3306 protocol: TCP name: dbapi selector: component: db ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/metadata-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: deployment labels: component: server spec: replicas: 1 selector: matchLabels: component: server template: metadata: labels: component: server spec: containers: - name: container envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets command: ["./server/server", "--http_port=8080", "--mysql_service_host=$(metadata-db-service)", "--mysql_service_port=$(MYSQL_PORT)", "--mysql_service_user=$(MYSQL_USER_NAME)", "--mysql_service_password=$(MYSQL_ROOT_PASSWORD)", "--mlmd_db_name=$(MYSQL_DATABASE)"] --- apiVersion: apps/v1 kind: Deployment metadata: name: grpc-deployment labels: component: grpc-server spec: replicas: 1 selector: matchLabels: component: grpc-server template: metadata: labels: component: grpc-server spec: containers: - name: container envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets - configMapRef: name: grpc-configmap args: ["--grpc_port=$(METADATA_GRPC_SERVICE_PORT)", "--mysql_config_host=$(metadata-db-service)", "--mysql_config_database=$(MYSQL_DATABASE)", "--mysql_config_port=$(MYSQL_PORT)", "--mysql_config_user=$(MYSQL_USER_NAME)", "--mysql_config_password=$(MYSQL_ROOT_PASSWORD)" ] ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/params.env ================================================ MYSQL_DATABASE=metadb MYSQL_PORT=3306 MYSQL_ALLOW_EMPTY_PASSWORD=true ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/db/secrets.env ================================================ MYSQL_USER_NAME=root MYSQL_ROOT_PASSWORD=test ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: kustomize.component: metadata configMapGenerator: - name: metadata-db-parameters envs: - params.env secretGenerator: - name: metadata-db-secrets envs: - secrets.env bases: - ../../base patchesStrategicMerge: - metadata-deployment.yaml ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/metadata-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: deployment labels: component: server spec: replicas: 1 selector: matchLabels: component: server template: metadata: labels: component: server spec: containers: - name: container envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets command: ["./server/server", "--http_port=8080", "--mysql_service_host=$(MYSQL_HOST)", "--mysql_service_port=$(MYSQL_PORT)", "--mysql_service_user=$(MYSQL_USERNAME)", "--mysql_service_password=$(MYSQL_PASSWORD)", "--mlmd_db_name=$(MYSQL_DATABASE)"] --- apiVersion: apps/v1 kind: Deployment metadata: name: grpc-deployment labels: component: grpc-server spec: replicas: 1 selector: matchLabels: component: grpc-server template: metadata: labels: component: grpc-server spec: containers: - name: container envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets - configMapRef: name: grpc-configmap args: ["--grpc_port=$(METADATA_GRPC_SERVICE_PORT)", "--mysql_config_host=$(MYSQL_HOST)", "--mysql_config_database=$(MYSQL_DATABASE)", "--mysql_config_port=$(MYSQL_PORT)", "--mysql_config_user=$(MYSQL_USERNAME)", "--mysql_config_password=$(MYSQL_PASSWORD)" ] ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/params.env ================================================ MYSQL_HOST=external_host MYSQL_DATABASE=metadb MYSQL_PORT=3306 MYSQL_ALLOW_EMPTY_PASSWORD=true ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/external-mysql/secrets.env ================================================ MYSQL_USERNAME=root MYSQ_PASSWORD=test ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/README.md ================================================ This directory contains configurations and guidelines on setting up metadata services to connect to a [Google CloudSQL](https://cloud.google.com/sql) instance. You will get all the benefits of using CloudSQL comparing to managing your own MySQL server in a Kubernetes cluster. #### Prerequisites - Install [kustomize](https://github.com/kubernetes-sigs/kustomize) for building Kubernetes configurations. - Install [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) for managing workloads on Kubernetes clusters. #### 0. Remove default metadata services. By default, Metadata component starts a MySQL server in `kubeflow` namespace. Since we are going to deploy metadata services with CloudSQL, you should delete the default services by running ``` kustomize build metadata/overlays/db | kubectl delete -n kubeflow -f - ``` #### 1. Create a CloudSQL instance. If you don't have an existing one, you need to [create a CloudSQL instance](https://cloud.google.com/sql/docs/mysql/create-instance) of type MySQL in your GCP project. If you want to connect the instance via private IP, you also need to enable the private IP configuration when creating the instance. #### 2. Create a Kubernetes secret for accessing the CloudSQL instance. You can follow [this guide](https://cloud.google.com/sql/docs/mysql/connect-kubernetes-engine#secrets) to set up a [service account with permissions](https://cloud.google.com/sql/docs/mysql/sql-proxy#create-service-account) to connect to the instance, download the JSON key file, and name it `credentials.json`. You need to create a secret via command: ``` kubectl create secret -n kubeflow generic cloudsql-instance-credentials --from-file /credentials.json ``` Note that you must name the key file `credentials.json`, because we will later refer to this file name in the deployment configuration. #### 3. Create a Kubernetes secret for MySQL account and password. Besides the service account with permissions, the metadata services also need a MySQL account name and password to be authenticated for accessing databases. Secret is the way how Kubernetes manages sensitive information. You need to [create a secret](https://kubernetes.io/docs/concepts/configuration/secret/#creating-your-own-secrets) under `kubeflow` namespace with name `metadata-db-secrets`, containing values of `MYSQL_USERNAME` and `MYSQL_PASSWORD`. You should be able to see the secret after its creation via command: ``` kubectl describe secrets -n kubeflow metadata-db-secrets Name: metadata-db-secrets Namespace: kubeflow Labels: kustomize.component=metadata Annotations: Type: Opaque Data ==== MYSQL_PASSWORD: 9 bytes MYSQL_USERNAME: 4 bytes ``` #### 4. Specify the instance connection name. Change the value of `MYSQL_INSTANCE` in `params.env` to your CloudSQL instance connection name. The connection name is in the form of `::`. #### 5. Start metadata services with CloudSQL proxy. Start metadata services with CloudSQL proxy sidecar containers via command: ``` kustomize build metadata/overlays/google-cloudsql | kubectl apply -n kubeflow -f - ``` You may find the CloudSQL proxy container logs useful to debug connection errors. ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization generatorOptions: # name suffix hash is not propagated correctly to base resources due to # https://github.com/kubernetes-sigs/kustomize/issues/1301 disableNameSuffixHash: true commonLabels: kustomize.component: metadata configMapGenerator: - name: metadata-db-parameters envs: - params.env bases: - ../../base patchesStrategicMerge: - metadata-deployment.yaml ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/metadata-deployment.yaml ================================================ apiVersion: apps/v1 kind: Deployment metadata: name: deployment labels: component: server spec: replicas: 1 selector: matchLabels: component: server template: metadata: labels: component: server spec: volumes: - name: cloudsql-instance-credentials secret: secretName: cloudsql-instance-credentials containers: - name: cloudsql-proxy envFrom: - configMapRef: name: metadata-db-parameters image: gcr.io/cloudsql-docker/gce-proxy:1.16 command: ["/cloud_sql_proxy", "-instances=$(MYSQL_INSTANCE)=tcp:3306", # If running on a VPC, the Cloud SQL proxy can connect via Private IP. See: # https://cloud.google.com/sql/docs/mysql/private-ip for more info. # "-ip_address_types=PRIVATE", "-credential_file=/secrets/cloudsql/credentials.json"] securityContext: runAsUser: 2 # non-root user allowPrivilegeEscalation: false volumeMounts: - name: cloudsql-instance-credentials mountPath: /secrets/cloudsql readOnly: true - name: container envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets command: ["./server/server", "--http_port=8080", "--mysql_service_host=$(MYSQL_HOST)", "--mysql_service_port=$(MYSQL_PORT)", "--mysql_service_user=$(MYSQL_USERNAME)", "--mysql_service_password=$(MYSQL_PASSWORD)", "--mlmd_db_name=$(MYSQL_DATABASE)"] --- apiVersion: apps/v1 kind: Deployment metadata: name: grpc-deployment labels: component: grpc-server spec: replicas: 1 selector: matchLabels: component: grpc-server template: metadata: labels: component: grpc-server spec: volumes: - name: cloudsql-instance-credentials secret: secretName: cloudsql-instance-credentials containers: - name: container envFrom: - configMapRef: name: metadata-db-parameters - secretRef: name: metadata-db-secrets - configMapRef: name: metadata-grpc-configmap args: ["--grpc_port=$(METADATA_GRPC_SERVICE_PORT)", "--mysql_config_host=$(MYSQL_HOST)", "--mysql_config_database=$(MYSQL_DATABASE)", "--mysql_config_port=$(MYSQL_PORT)", "--mysql_config_user=$(MYSQL_USERNAME)", "--mysql_config_password=$(MYSQL_PASSWORD)" ] - name: cloudsql-proxy envFrom: - configMapRef: name: metadata-db-parameters image: gcr.io/cloudsql-docker/gce-proxy:1.16 command: ["/cloud_sql_proxy", "-instances=$(MYSQL_INSTANCE)=tcp:3306", # If running on a VPC, the Cloud SQL proxy can connect via Private IP. See: # https://cloud.google.com/sql/docs/mysql/private-ip for more info. # "-ip_address_types=PRIVATE", "-credential_file=/secrets/cloudsql/credentials.json"] securityContext: runAsUser: 2 # non-root user allowPrivilegeEscalation: false volumeMounts: - name: cloudsql-instance-credentials mountPath: /secrets/cloudsql readOnly: true ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/google-cloudsql/params.env ================================================ MYSQL_HOST=127.0.0.1 MYSQL_DATABASE=metadb MYSQL_PORT=3306 MYSQL_ALLOW_EMPTY_PASSWORD=true MYSQL_INSTANCE=your-project:your-region:your-mysql-instance-id ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/ibm-storage-config/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../../base images: - name: mysql newTag: "5.6" newName: mysql ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../../base resources: - virtual-service.yaml - virtual-service-metadata-grpc.yaml configurations: - params.yaml ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/params.yaml ================================================ varReference: - path: spec/http/route/destination/host kind: VirtualService ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/virtual-service-metadata-grpc.yaml ================================================ apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: metadata-grpc spec: gateways: - kubeflow-gateway hosts: - '*' http: - match: - uri: prefix: /ml_metadata rewrite: uri: /ml_metadata route: - destination: host: $(metadata-envoy-service).$(ui-namespace).svc.$(ui-clusterDomain) port: number: 9090 timeout: 300s ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/metadata/overlays/istio/virtual-service.yaml ================================================ apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: metadata-ui spec: gateways: - kubeflow-gateway hosts: - '*' http: - match: - uri: prefix: /metadata rewrite: uri: /metadata route: - destination: host: $(metadata-service).$(ui-namespace).svc.$(ui-clusterDomain) port: number: 80 timeout: 300s ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/cluster-role-binding.yaml ================================================ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: labels: app: pytorch-operator name: pytorch-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: pytorch-operator subjects: - kind: ServiceAccount name: pytorch-operator ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/cluster-role.yaml ================================================ apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: labels: app: pytorch-operator name: pytorch-operator rules: - apiGroups: - kubeflow.org resources: - pytorchjobs - pytorchjobs/status verbs: - '*' - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - '*' - apiGroups: - storage.k8s.io resources: - storageclasses verbs: - '*' - apiGroups: - batch resources: - jobs verbs: - '*' - apiGroups: - "" resources: - configmaps - pods - services - endpoints - persistentvolumeclaims - events verbs: - '*' - apiGroups: - apps - extensions resources: - deployments verbs: - '*' ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/config-map.yaml ================================================ apiVersion: v1 data: controller_config_file.yaml: |- { } kind: ConfigMap metadata: name: pytorch-operator-config ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/deployment.yaml ================================================ apiVersion: extensions/v1beta1 kind: Deployment metadata: name: pytorch-operator spec: replicas: 1 selector: matchLabels: name: pytorch-operator template: metadata: labels: name: pytorch-operator spec: containers: - command: - /pytorch-operator.v1 - --alsologtostderr - -v=1 - --monitoring-port=8443 env: - name: MY_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name image: gcr.io/kubeflow-images-public/pytorch-operator:v0.5.1-5-ge775742 name: pytorch-operator volumeMounts: - mountPath: /etc/config name: config-volume serviceAccountName: pytorch-operator volumes: - configMap: name: pytorch-operator-config name: config-volume ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: kubeflow resources: - cluster-role-binding.yaml - cluster-role.yaml - config-map.yaml - deployment.yaml - service-account.yaml - service.yaml commonLabels: kustomize.component: pytorch-operator images: - name: gcr.io/kubeflow-images-public/pytorch-operator newName: gcr.io/kubeflow-images-public/pytorch-operator #newTag: v0.5.0-7-g6d7ed35 ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/params.env ================================================ pytorchDefaultImage=null deploymentScope=cluster deploymentNamespace=null ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/service-account.yaml ================================================ apiVersion: v1 kind: ServiceAccount metadata: labels: app: pytorch-operator name: pytorch-operator ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/base/service.yaml ================================================ apiVersion: v1 kind: Service metadata: annotations: prometheus.io/path: /metrics prometheus.io/port: "8443" prometheus.io/scrape: "true" labels: app: pytorch-operator name: pytorch-operator spec: ports: - name: monitoring-port port: 8443 targetPort: 8443 selector: name: pytorch-operator type: ClusterIP ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/expected/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 bases: - base commonLabels: app.kubernetes.io/component: pytorch app.kubernetes.io/instance: pytorch-operator app.kubernetes.io/managed-by: kfctl app.kubernetes.io/name: pytorch-operator-application app.kubernetes.io/part-of: kubeflow app.kubernetes.io/version: v0.6.0 kind: Kustomization namespace: kubeflow resources: - overlays/application/application.yaml secretGenerator: - behavior: unspecified env: overlays/application/secrets.env name: secrets-are-no-fun ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/overlays/application/application.yaml ================================================ apiVersion: app.k8s.io/v1beta1 kind: Application metadata: name: pytorch-operator-application spec: type: pytorch-operator componentKinds: - group: core kind: ConfigMap - group: apps kind: Deployment - group: core kind: ServiceAccount description: pytorch-operator allows users to create a custom resource \"PyTorchJob\". keywords: - pytorch-job - pytorch-operator version: v1alpha1 ================================================ FILE: pkg/kfapp/kustomize/testdata/kustomizeExample/pytorch-operator/overlays/application/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization bases: - ../../base resources: - application.yaml commonLabels: app.kubernetes.io/name: pytorch-operator-application app.kubernetes.io/instance: pytorch-operator app.kubernetes.io/version: v0.6.0 app.kubernetes.io/component: pytorch app.kubernetes.io/part-of: kubeflow app.kubernetes.io/managed-by: kfctl secretGenerator: - name: secrets-are-no-fun env: secrets.env ================================================ FILE: pkg/kfapp/kustomize/testdata/operator/base/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization commonLabels: app: fake resources: - service.yaml ================================================ FILE: pkg/kfapp/kustomize/testdata/operator/base/service.yaml ================================================ apiVersion: v1 kind: Service metadata: name: fake-service spec: ports: - port: 9000 protocol: TCP targetPort: 9000 selector: app: fake ================================================ FILE: pkg/kfapp/kustomize/testdata/operator/expected/service.yaml ================================================ apiVersion: v1 kind: Service metadata: annotations: kfctl.kubeflow.io/kfdef-instance: operator.kubeflow labels: app: fake name: fake-service namespace: kubeflow spec: ports: - port: 9000 protocol: TCP targetPort: 9000 selector: app: fake ================================================ FILE: pkg/kfapp/kustomize/testdata/operator/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 bases: - base kind: Kustomization namespace: kubeflow ================================================ FILE: pkg/kfapp/minikube/minikube.go ================================================ /* 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. */ package minikube import ( "fmt" "github.com/ghodss/yaml" //"github.com/kubeflow/kfctl/v3/config" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" //kfdefs "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" "io/ioutil" "k8s.io/client-go/rest" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" //"os/user" "path/filepath" //"strconv" //"strings" ) // Minikube implements KfApp Interface type Minikube struct { kfconfig.KfConfig } func Getplatform(kfdef *kfconfig.KfConfig) kftypes.Platform { _minikube := &Minikube{ KfConfig: *kfdef, } return _minikube } // GetK8sConfig return nil; minikube will use default kube config file func (minikube *Minikube) GetK8sConfig() (*rest.Config, *clientcmdapi.Config) { return nil, nil } func (minikube *Minikube) Apply(resources kftypes.ResourceEnum) error { //mount_local_fs //setup_tunnels return nil } func (minikube *Minikube) Delete(resources kftypes.ResourceEnum) error { return nil } func (minikube *Minikube) Dump(resources kftypes.ResourceEnum) error { return nil } func (minikube *Minikube) generate() error { // TODO: fix with applications // remove Katib package and component // minikube.Spec.Packages = kftypes.RemoveItem(minikube.Spec.Packages, "katib") // minikube.Spec.Components = kftypes.RemoveItem(minikube.Spec.Components, "katib") // minikube.Spec.ComponentParams["application"] = []config.NameValue{ // { // Name: "components", // Value: "[" + strings.Join(kftypes.QuoteItems(minikube.Spec.Components), ",") + "]", // }, // } // usr, err := user.Current() // if err != nil { // return &kfapis.KfError{ // Code: int(kfapis.INVALID_ARGUMENT), // Message: fmt.Sprintf("Could not get current user; error %v", err), // } // } // uid := usr.Uid // gid := usr.Gid // minikube.Spec.ComponentParams["jupyter"] = []config.NameValue{ // { // Name: string(kftypes.PLATFORM), // Value: minikube.Spec.Platform, // }, // { // Name: "accessLocalFs", // Value: strconv.FormatBool(minikube.Spec.MountLocal), // }, // { // Name: "disks", // Value: "local-notebooks", // }, // { // Name: "notebookUid", // Value: uid, // }, // { // Name: "notebookGid", // Value: gid, // }, // } // minikube.Spec.ComponentParams["ambassador"] = []config.NameValue{ // { // Name: string(kftypes.PLATFORM), // Value: minikube.Spec.Platform, // }, // { // Name: "replicas", // Value: "1", // }, // } return nil } func (minikube *Minikube) Generate(resources kftypes.ResourceEnum) error { switch resources { case kftypes.K8S: case kftypes.ALL: fallthrough case kftypes.PLATFORM: generateErr := minikube.generate() if generateErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("minikube generate failed Error: %v", generateErr), } } } createConfigErr := minikube.writeConfigFile() if createConfigErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("cannot create config file app.yaml in %v", minikube.KfConfig.Spec.AppDir), } } return nil } func (minikube *Minikube) Init(kftypes.ResourceEnum) error { return nil } func (minikube *Minikube) writeConfigFile() error { buf, bufErr := yaml.Marshal(minikube.KfConfig) if bufErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("cannot marshal config file: %v", bufErr), } } cfgFilePath := filepath.Join(minikube.KfConfig.Spec.AppDir, kftypes.KfConfigFile) cfgFilePathErr := ioutil.WriteFile(cfgFilePath, buf, 0644) if cfgFilePathErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("cannot write config file: %v", cfgFilePathErr), } } return nil } ================================================ FILE: pkg/kfconfig/awsplugin/OWNERS ================================================ approvers: - jeffwan - PatrickXYS ================================================ FILE: pkg/kfconfig/awsplugin/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 v1beta1 contains API Schema definitions for the kfdef v1beta1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig/awsplugin // +k8s:defaulter-gen=TypeMeta // +groupName=awsplugin.internal.kubeflow.org package awsplugin ================================================ FILE: pkg/kfconfig/awsplugin/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the KfAwsPlugin v1alpha1. // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig/awsplugin // +k8s:defaulter-gen=TypeMeta // +groupName=awsplugin.internal.kubeflow.org package awsplugin import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "awsplugin.internal.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfAwsPlugin{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/kfconfig/awsplugin/types.go ================================================ package awsplugin import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:openapi-gen=true // Placeholder for the plugin API. type KfAwsPlugin struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec AwsPluginSpec `json:"spec,omitempty"` } // AwsPlugin defines the extra data provided by the GCP Plugin in KfDef type AwsPluginSpec struct { Auth *Auth `json:"auth,omitempty"` Region string `json:"region,omitempty"` Roles []string `json:"roles,omitempty"` EnablePodIamPolicy *bool `json:"enablePodIamPolicy,omitempty"` EnableNodeGroupLog *bool `json:"enableNodeGroupLog,omitempty"` ManagedCluster *bool `json:"managedCluster,omitempty"` ManagedRelationDatabase *RelationDatabaseConfig `json:"managedRelationDatabase,omitempty"` ManagedObjectStorage *ObjectStorageConfig `json:"managedObjectStorage,omitempty"` // TODO: Addon is used to host some optional aws specific components // EFS, FSX CSI Plugin, Device Plugin, etc //AddOns []string `json:"addons,omitempty"` } type RelationDatabaseConfig struct { Host string `json:"host,omitempty"` Port *int `json:"port,omitempty"` Database string `json:"database,omitempty"` Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` } type ObjectStorageConfig struct { Endpoint string `json:"endpoint,omitempty"` Region string `json:"region,omitempty"` Bucket string `json:"bucket,omitempty"` PathPrefix string `json:"pathPrefix,omitempty"` } type Auth struct { BasicAuth *BasicAuth `json:"basicAuth,omitempty"` Oidc *OIDC `json:"oidc,omitempty"` Cognito *Coginito `json:"cognito,omitempty"` } type BasicAuth struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` } type OIDC struct { OidcAuthorizationEndpoint string `json:"oidcAuthorizationEndpoint,omitempty"` OidcIssuer string `json:"oidcIssuer,omitempty"` OidcTokenEndpoint string `json:"oidcTokenEndpoint,omitempty"` OidcUserInfoEndpoint string `json:"oidcUserInfoEndpoint,omitempty"` CertArn string `json:"certArn,omitempty"` OAuthClientId string `json:"oAuthClientId,omitempty"` OAuthClientSecret string `json:"oAuthClientSecret,omitempty"` } type Coginito struct { CognitoAppClientId string `json:"cognitoAppClientId,omitempty"` CognitoUserPoolArn string `json:"cognitoUserPoolArn,omitempty"` CognitoUserPoolDomain string `json:"cognitoUserPoolDomain,omitempty"` CertArn string `json:"certArn,omitempty"` } // IsValid returns true if the spec is a valid and complete spec. // If false it will also return a string providing a message about why its invalid. func (plugin *AwsPluginSpec) IsValid() (bool, string) { if plugin.Auth.BasicAuth != nil { msg := "" isValid := true if plugin.Auth.BasicAuth.Username == "" { isValid = false msg += "BasicAuth requires username. " } if plugin.Auth.BasicAuth.Password == "" { isValid = false msg += "BasicAuth requires password. " } return isValid, msg } if plugin.Auth.Oidc != nil { msg := "" isValid := true if plugin.Auth.Oidc.OidcAuthorizationEndpoint == "" { isValid = false msg += "OidcAuthorizationEndpoint is required" } if plugin.Auth.Oidc.OidcIssuer == "" { isValid = false msg += "OidcIssuer is required" } if plugin.Auth.Oidc.OidcTokenEndpoint == "" { isValid = false msg += "OidcTokenEndpoint is required" } if plugin.Auth.Oidc.OidcUserInfoEndpoint == "" { isValid = false msg += "OidcUserInfoEndpoint is required" } if plugin.Auth.Oidc.CertArn == "" { isValid = false msg += "CertArn is required" } if plugin.Auth.Oidc.OAuthClientId == "" { isValid = false msg += "OAuthClientId is required" } if plugin.Auth.Oidc.OAuthClientSecret == "" { isValid = false msg += "OAuthClientSecret is required" } return isValid, msg } if plugin.Auth.Cognito != nil { msg := "" isValid := true if plugin.Auth.Cognito.CognitoAppClientId == "" { isValid = false msg += "CognitoAppClientId is required" } if plugin.Auth.Cognito.CognitoUserPoolArn == "" { isValid = false msg += "CognitoUserPoolArn is required" } if plugin.Auth.Cognito.CognitoUserPoolDomain == "" { isValid = false msg += "CognitoUserPoolDomain is required" } if plugin.Auth.Cognito.CertArn == "" { isValid = false msg += "CertArn is required" } return isValid, msg } if plugin.ManagedRelationDatabase != nil { msg := "" isValid := true if plugin.ManagedRelationDatabase.Host == "" { isValid = false msg += "ManagedRelationDatabase.Host is required" } if plugin.ManagedRelationDatabase.Username == "" { isValid = false msg += "ManagedRelationDatabase.Username is required" } if plugin.ManagedRelationDatabase.Password == "" { isValid = false msg += "ManagedRelationDatabase.Password is required" } return isValid, msg } if plugin.ManagedObjectStorage != nil { msg := "" isValid := true if plugin.ManagedObjectStorage.Endpoint == "" { isValid = false msg += "ManagedObjectStorage.Endpoint is required" } if plugin.ManagedObjectStorage.Region == "" { isValid = false msg += "ManagedObjectStorage.Region is required" } if plugin.ManagedObjectStorage.Bucket == "" { isValid = false msg += "ManagedObjectStorage.Bucket is required" } return isValid, msg } return true, "" } // GetEnablePodIamPolicy return true if user want to enable pod iam policy func (p *AwsPluginSpec) GetEnablePodIamPolicy() bool { if p.EnablePodIamPolicy == nil { return false } v := p.EnablePodIamPolicy return *v } // GetEnableNodeGroupLog return true if user want to enable fluentd cloud watch logs func (p *AwsPluginSpec) GetEnableNodeGroupLog() bool { if p.EnableNodeGroupLog == nil { return false } v := p.EnableNodeGroupLog return *v } // GetManagedCluster return true if user want to create a new cluster and then deploy kubeflow func (p *AwsPluginSpec) GetManagedCluster() bool { if p.ManagedCluster == nil { return false } v := p.ManagedCluster return *v } ================================================ FILE: pkg/kfconfig/awsplugin/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 awsplugin import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Auth) DeepCopyInto(out *Auth) { *out = *in if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(BasicAuth) (*in).DeepCopyInto(*out) } if in.Oidc != nil { in, out := &in.Oidc, &out.Oidc *out = new(OIDC) **out = **in } if in.Cognito != nil { in, out := &in.Cognito, &out.Cognito *out = new(Coginito) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth. func (in *Auth) DeepCopy() *Auth { if in == nil { return nil } out := new(Auth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AwsPluginSpec) DeepCopyInto(out *AwsPluginSpec) { *out = *in if in.Auth != nil { in, out := &in.Auth, &out.Auth *out = new(Auth) (*in).DeepCopyInto(*out) } if in.Roles != nil { in, out := &in.Roles, &out.Roles *out = make([]string, len(*in)) copy(*out, *in) } if in.EnablePodIamPolicy != nil { in, out := &in.EnablePodIamPolicy, &out.EnablePodIamPolicy *out = new(bool) **out = **in } if in.EnableNodeGroupLog != nil { in, out := &in.EnableNodeGroupLog, &out.EnableNodeGroupLog *out = new(bool) **out = **in } if in.ManagedCluster != nil { in, out := &in.ManagedCluster, &out.ManagedCluster *out = new(bool) **out = **in } if in.ManagedRelationDatabase != nil { in, out := &in.ManagedRelationDatabase, &out.ManagedRelationDatabase *out = new(RelationDatabaseConfig) (*in).DeepCopyInto(*out) } if in.ManagedObjectStorage != nil { in, out := &in.ManagedObjectStorage, &out.ManagedObjectStorage *out = new(ObjectStorageConfig) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AwsPluginSpec. func (in *AwsPluginSpec) DeepCopy() *AwsPluginSpec { if in == nil { return nil } out := new(AwsPluginSpec) in.DeepCopyInto(out) return out } //DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = *in //if in.Password != "" { // in, out := &in.Password, &out.Password // *out = "" // **out = **in //} return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. func (in *BasicAuth) DeepCopy() *BasicAuth { if in == nil { return nil } out := new(BasicAuth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Coginito) DeepCopyInto(out *Coginito) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Coginito. func (in *Coginito) DeepCopy() *Coginito { if in == nil { return nil } out := new(Coginito) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfAwsPlugin) DeepCopyInto(out *KfAwsPlugin) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfAwsPlugin. func (in *KfAwsPlugin) DeepCopy() *KfAwsPlugin { if in == nil { return nil } out := new(KfAwsPlugin) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfAwsPlugin) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OIDC) DeepCopyInto(out *OIDC) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDC. func (in *OIDC) DeepCopy() *OIDC { if in == nil { return nil } out := new(OIDC) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ObjectStorageConfig) DeepCopyInto(out *ObjectStorageConfig) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStorageConfig. func (in *ObjectStorageConfig) DeepCopy() *ObjectStorageConfig { if in == nil { return nil } out := new(ObjectStorageConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RelationDatabaseConfig) DeepCopyInto(out *RelationDatabaseConfig) { *out = *in if in.Port != nil { in, out := &in.Port, &out.Port *out = new(int) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RelationDatabaseConfig. func (in *RelationDatabaseConfig) DeepCopy() *RelationDatabaseConfig { if in == nil { return nil } out := new(RelationDatabaseConfig) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/kfconfig/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 v1alpha1 contains API Schema definitions for the kfconfig v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig // +k8s:defaulter-gen=TypeMeta // +groupName=kfconfig.apps.kubeflow.org package kfconfig ================================================ FILE: pkg/kfconfig/gcpplugin/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 v1beta1 contains API Schema definitions for the kfdef v1beta1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig/gcpplugin // +k8s:defaulter-gen=TypeMeta // +groupName=gcpplugin.internal.kubeflow.org package gcpplugin ================================================ FILE: pkg/kfconfig/gcpplugin/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the KfGcpPlugin v1alpha1. // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig/gcpplugin // +k8s:defaulter-gen=TypeMeta // +groupName=gcpplugin.internal.kubeflow.org package gcpplugin import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "gcpplugin.internal.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfGcpPlugin{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/kfconfig/gcpplugin/types.go ================================================ package gcpplugin import ( "fmt" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "strings" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:openapi-gen=true // Placeholder for the plugin API. type KfGcpPlugin struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec GcpPluginSpec `json:"spec,omitempty"` } // GcpPlugin defines the extra data provided by the GCP Plugin in KfDef type GcpPluginSpec struct { Auth *Auth `json:"auth,omitempty"` // SAClientId if supplied grant this service account cluster admin access // TODO(jlewi): Might want to make it a list SAClientId string `json:"username,omitempty"` // CreatePipelinePersistentStorage indicates whether to create storage. // Use a pointer so we can distinguish unset values. CreatePipelinePersistentStorage *bool `json:"createPipelinePersistentStorage,omitempty"` // EnableWorkloadIdentity indicates whether to enable workload identity. // Use a pointer so we can distinguish unset values. EnableWorkloadIdentity *bool `json:"enableWorkloadIdentity,omitempty"` // DeploymentManagerConfig provides location of the deployment manager configs. DeploymentManagerConfig *DeploymentManagerConfig `json:"deploymentManagerConfig,omitempty"` Project string `json:"project,omitempty"` Email string `json:"email,omitempty"` IpName string `json:"ipName,omitempty"` Hostname string `json:"hostname,omitempty"` Zone string `json:"zone,omitempty"` UseBasicAuth bool `json:"useBasicAuth"` SkipInitProject bool `json:"skipInitProject,omitempty"` DeleteStorage bool `json:"deleteStorage,omitempty"` } type Auth struct { BasicAuth *BasicAuth `json:"basicAuth,omitempty"` IAP *IAP `json:"iap,omitempty"` } type BasicAuth struct { Username string `json:"username,omitempty"` Password *kfconfig.SecretRef `json:"password,omitempty"` } type IAP struct { OAuthClientId string `json:"oAuthClientId,omitempty"` OAuthClientSecret *kfconfig.SecretRef `json:"oAuthClientSecret,omitempty"` } type DeploymentManagerConfig struct { RepoRef *kfconfig.RepoRef `json:"repoRef,omitempty"` } // IsValid returns nil if the spec is a valid and complete spec. // If not nil it will return a `KfError` with an error message. func (s *GcpPluginSpec) IsValid() error { if len(s.Hostname) > 63 { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Invaid host name: host name %s is longer than 63 characters. Please shorten the metadata.name.", s.Hostname), } } basicAuthSet := s.Auth.BasicAuth != nil iapAuthSet := s.Auth.IAP != nil if basicAuthSet == iapAuthSet { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Exactly one of BasicAuth and IAP must be set; the other should be nil", } } if basicAuthSet { msgs := []string{} if s.Auth.BasicAuth.Username == "" { msgs = append(msgs, "BasicAuth requires username.") } if s.Auth.BasicAuth.Password == nil { msgs = append(msgs, "BasicAuth requires password.") } if len(msgs) > 0 { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: strings.Join(msgs, ";"), } } else { return nil } } if iapAuthSet { msgs := []string{} if s.Auth.IAP.OAuthClientId == "" { msgs = append(msgs, "IAP requires OAuthClientId.") } if s.Auth.IAP.OAuthClientSecret == nil { msgs = append(msgs, "IAP requires OAuthClientSecret.") } if len(msgs) > 0 { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: strings.Join(msgs, ";"), } } else { return nil } } return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "Either BasicAuth or IAP must be set", } } func (p *GcpPluginSpec) GetCreatePipelinePersistentStorage() bool { if p.CreatePipelinePersistentStorage == nil { return true } v := p.CreatePipelinePersistentStorage return *v } func (p *GcpPluginSpec) GetEnableWorkloadIdentity() bool { if p.EnableWorkloadIdentity == nil { return true } v := p.EnableWorkloadIdentity return *v } ================================================ FILE: pkg/kfconfig/gcpplugin/types_test.go ================================================ package gcpplugin import ( kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfutils "github.com/kubeflow/kfctl/v3/pkg/utils" "testing" ) func TestGcpPluginSpec_IsValid(t *testing.T) { type testCase struct { input *GcpPluginSpec expected error } cases := []testCase{ { // Neither IAP or BasicAuth is set input: &GcpPluginSpec{ Auth: &Auth{}, }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, { // Both IAP and BasicAuth set input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Username: "jlewi", Password: &kfconfig.SecretRef{ Name: "somesecret", }, }, IAP: &IAP{ OAuthClientId: "jlewi", OAuthClientSecret: &kfconfig.SecretRef{ Name: "somesecret", }, }, }, }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, // Validate basic auth. { input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Username: "jlewi", Password: &kfconfig.SecretRef{ Name: "somesecret", }, }, }, }, expected: nil, }, { input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Username: "jlewi", }, }, }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, { input: &GcpPluginSpec{ Auth: &Auth{ BasicAuth: &BasicAuth{ Password: &kfconfig.SecretRef{ Name: "somesecret", }, }, }, }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, // End Validate basic auth. // End Validate IAP. { input: &GcpPluginSpec{ Auth: &Auth{ IAP: &IAP{ OAuthClientId: "jlewi", OAuthClientSecret: &kfconfig.SecretRef{ Name: "somesecret", }, }, }, }, expected: nil, }, { input: &GcpPluginSpec{ Auth: &Auth{ IAP: &IAP{ OAuthClientId: "jlewi", }, }, }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, { input: &GcpPluginSpec{ Auth: &Auth{ IAP: &IAP{ OAuthClientSecret: &kfconfig.SecretRef{ Name: "somesecret", }, }, }, }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, { input: &GcpPluginSpec{ Hostname: "this-kfApp-name-is-very-long.endpoints.my-gcp-project-for-kubeflow.cloud.goog", }, expected: &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), }, }, } for _, c := range cases { err := c.input.IsValid() pSpec := kfutils.PrettyPrint(c.input) if err != nil { if c.expected != nil { if err.(*kfapis.KfError).Code != c.expected.(*kfapis.KfError).Code { t.Errorf("Spec %v;\n IsValid Got:%v %v", pSpec, err, c.expected) } } else { t.Errorf("Spec %v;\n IsValid Got:%v %v", pSpec, err, c.expected) } } else if c.expected != nil { t.Errorf("Spec %v;\n IsValid Got:%v %v", pSpec, err, c.expected) } } } ================================================ FILE: pkg/kfconfig/gcpplugin/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 gcpplugin import ( kfconfig "github.com/kubeflow/kfctl/v3/pkg/kfconfig" runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Auth) DeepCopyInto(out *Auth) { *out = *in if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(BasicAuth) (*in).DeepCopyInto(*out) } if in.IAP != nil { in, out := &in.IAP, &out.IAP *out = new(IAP) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Auth. func (in *Auth) DeepCopy() *Auth { if in == nil { return nil } out := new(Auth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = *in if in.Password != nil { in, out := &in.Password, &out.Password *out = new(kfconfig.SecretRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. func (in *BasicAuth) DeepCopy() *BasicAuth { if in == nil { return nil } out := new(BasicAuth) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentManagerConfig) DeepCopyInto(out *DeploymentManagerConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(kfconfig.RepoRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentManagerConfig. func (in *DeploymentManagerConfig) DeepCopy() *DeploymentManagerConfig { if in == nil { return nil } out := new(DeploymentManagerConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GcpPluginSpec) DeepCopyInto(out *GcpPluginSpec) { *out = *in if in.Auth != nil { in, out := &in.Auth, &out.Auth *out = new(Auth) (*in).DeepCopyInto(*out) } if in.CreatePipelinePersistentStorage != nil { in, out := &in.CreatePipelinePersistentStorage, &out.CreatePipelinePersistentStorage *out = new(bool) **out = **in } if in.EnableWorkloadIdentity != nil { in, out := &in.EnableWorkloadIdentity, &out.EnableWorkloadIdentity *out = new(bool) **out = **in } if in.DeploymentManagerConfig != nil { in, out := &in.DeploymentManagerConfig, &out.DeploymentManagerConfig *out = new(DeploymentManagerConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GcpPluginSpec. func (in *GcpPluginSpec) DeepCopy() *GcpPluginSpec { if in == nil { return nil } out := new(GcpPluginSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IAP) DeepCopyInto(out *IAP) { *out = *in if in.OAuthClientSecret != nil { in, out := &in.OAuthClientSecret, &out.OAuthClientSecret *out = new(kfconfig.SecretRef) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IAP. func (in *IAP) DeepCopy() *IAP { if in == nil { return nil } out := new(IAP) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfGcpPlugin) DeepCopyInto(out *KfGcpPlugin) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfGcpPlugin. func (in *KfGcpPlugin) DeepCopy() *KfGcpPlugin { if in == nil { return nil } out := new(KfGcpPlugin) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfGcpPlugin) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } ================================================ FILE: pkg/kfconfig/loaders/loaders.go ================================================ package loaders import ( "fmt" "os" "path/filepath" "io/ioutil" netUrl "net/url" "path" "strings" "github.com/ghodss/yaml" gogetter "github.com/hashicorp/go-getter" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/utils" log "github.com/sirupsen/logrus" ) type Loader interface { LoadKfConfig(kfdef interface{}) (*kfconfig.KfConfig, error) LoadKfDef(config kfconfig.KfConfig, out interface{}) error } const ( Api = "kfdef.apps.kubeflow.org" ) func isValidUrl(toTest string) bool { _, err := netUrl.ParseRequestURI(toTest) if err != nil { return false } else { return true } } // LoadConfigFromURI reads the kfdef from a remote URI or local file, // and returns the kfconfig. // It will set the AppDir and ConfigFilename in kfconfig: // AppDir = cwd if configFile is remote, or it will be the dir of configFile. // ConfigFilename = the file name of configFile. func LoadConfigFromURI(configFile string) (*kfconfig.KfConfig, error) { if configFile == "" { return nil, fmt.Errorf("config file must be the URI of a KfDef spec") } isRemoteFile, err := utils.IsRemoteFile(configFile) if err != nil { return nil, err } // appFile is configFile if configFile is local. // Otherwise (configFile is remote), appFile points to a downloaded copy of configFile in tmp. appFile := configFile // If config is remote, download it to a temp dir. if isRemoteFile { // TODO(jlewi): We should check if configFile doesn't specify a protocol or the protocol // is file:// then we can just read it rather than fetching with go-getter. appDir, err := ioutil.TempDir("", "") if err != nil { return nil, fmt.Errorf("Create a temporary directory to copy the file to.") } // Open config file // // TODO(jlewi): Should we use hashicorp go-getter.GetAny here? We use that to download // the tarballs for the repos. Maybe we should use that here as well to be consistent. appFile = path.Join(appDir, "tmp_app.yaml") log.Infof("Downloading %v to %v", configFile, appFile) configFileUri, err := netUrl.Parse(configFile) if err != nil { log.Errorf("Could not parse configFile url") } if isValidUrl(configFile) { errGet := gogetter.GetFile(appFile, configFile) if errGet != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, errGet), } } } else { g := new(gogetter.FileGetter) g.Copy = true errGet := g.GetFile(appFile, configFileUri) if errGet != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err), } } } } // Read contents configFileBytes, err := ioutil.ReadFile(appFile) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not read from config file %s: %v", configFile, err), } } // Check API version. var obj map[string]interface{} if err = yaml.Unmarshal(configFileBytes, &obj); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("invalid config file format: %v", err), } } apiVersion, ok := obj["apiVersion"] if !ok { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "invalid config: apiVersion is not found.", } } apiVersionSeparated := strings.Split(apiVersion.(string), "/") if len(apiVersionSeparated) < 2 || apiVersionSeparated[0] != Api { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("invalid config: apiVersion must be in the format of %v/, got %v", Api, apiVersion), } } // Add this check because kfctl binary can not properly install Kubeflow using v1alpha1 configuration. // See https://github.com/kubeflow/kubeflow/issues/4371. if apiVersionSeparated[1] == "v1alpha1" { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf( "KfDef version v1alpha1 is not supported by this binary. Please use configs at %s for to deploy Kubeflow 0.7 or use old kfctl at %s to deploy Kubeflow 0.6", "https://github.com/kubeflow/manifests/tree/v0.7-branch/kfdef", "https://github.com/kubeflow/kubeflow/releases/tag/v0.6.2", )} } converters := map[string]Loader{ "v1alpha1": V1alpha1{}, "v1beta1": V1beta1{}, "v1": V1{}, } converter, ok := converters[apiVersionSeparated[1]] if !ok { versions := []string{} for key := range converters { versions = append(versions, key) } return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("invalid config: version not supported; supported versions: %v, got %v", strings.Join(versions, ", "), apiVersionSeparated[1]), } } kfconfig, err := converter.LoadKfConfig(obj) if err != nil { log.Errorf("Failed to convert kfdef to kfconfig: %v", err) return nil, err } // Set the AppDir and ConfigFileName for kfconfig if isRemoteFile { cwd, err := os.Getwd() if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not get current directory for KfDef %v", err), } } kfconfig.Spec.AppDir = cwd } else { kfconfig.Spec.AppDir = filepath.Dir(configFile) } kfconfig.Spec.ConfigFileName = filepath.Base(configFile) return kfconfig, nil } func isCwdEmpty() string { cwd, _ := os.Getwd() files, _ := ioutil.ReadDir(cwd) if len(files) > 1 { return "" } return cwd } func WriteConfigToFile(config kfconfig.KfConfig) error { if config.Spec.AppDir == "" { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "No AppDir, cannot write to file.", } } if config.Spec.ConfigFileName == "" { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: "No ConfigFileName, cannot write to file.", } } filename := filepath.Join(config.Spec.AppDir, config.Spec.ConfigFileName) converters := map[string]Loader{ "v1alpha1": V1alpha1{}, "v1beta1": V1beta1{}, "v1": V1{}, } apiVersionSeparated := strings.Split(config.APIVersion, "/") if len(apiVersionSeparated) < 2 || apiVersionSeparated[0] != Api { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("invalid config: apiVersion must be in the format of %v/, got %v", Api, config.APIVersion), } } converter, ok := converters[apiVersionSeparated[1]] if !ok { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("invalid config: unable to find converter for version %v", config.APIVersion), } } var kfdef interface{} if err := converter.LoadKfDef(config, &kfdef); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("error when loading KfDef: %v", err), } } kfdefBytes, err := yaml.Marshal(kfdef) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("error when marshaling KfDef: %v", err), } } err = ioutil.WriteFile(filename, kfdefBytes, 0644) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when writing KfDef: %v", err), } } return nil } ================================================ FILE: pkg/kfconfig/loaders/loaders_test.go ================================================ package loaders import ( "os" "path" "testing" ) // Make sure literal secrets are keeped during load kfdef -> kfconfig func Test_loadKfdefLiteralSecrets(t *testing.T) { wd, _ := os.Getwd() kfconfig, err := LoadConfigFromURI(path.Join(wd, "testdata", "kfctl_gcp_basic_auth.0.7.0.yaml")) if err != nil || kfconfig == nil { t.Error(err) } if kfconfig.Spec.Secrets[0].SecretSource.LiteralSource.Value != "passwordVal" { t.Error("Secrets dropped during kfdef -> kfconfig!") } } ================================================ FILE: pkg/kfconfig/loaders/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/kfconfig/loaders/testdata/kfconfig_v1.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1 kind: KfConfig metadata: creationTimestamp: null name: myapp2 namespace: kubeflow annotations: testAnnotation: "dummy" labels: key1: "value1" spec: project: foo-project email: foo@gmail.com platform: gcp 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: "ON" 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: argo name: argo - kustomizeConfig: overlays: - istio parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: common/centraldashboard name: centraldashboard - kustomizeConfig: repoRef: name: manifests path: admission-webhook/webhook name: webhook - kustomizeConfig: parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-db name: katib-db - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-manager name: katib-manager - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-controller name: katib-controller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: katib-v1alpha2/katib-ui name: katib-ui - kustomizeConfig: overlays: - istio repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/metrics-collector name: metrics-collector - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/suggestion name: suggestion - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" repoRef: name: manifests path: jupyter/notebook-controller name: notebook-controller - kustomizeConfig: 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: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-crds name: knative-crds - kustomizeConfig: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-install name: knative-install - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-crds name: kfserving-crds - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-install name: kfserving-install - kustomizeConfig: parameters: - name: usageId value: "123456" - name: reportUsage value: "true" repoRef: name: manifests path: common/spartakus name: spartakus - kustomizeConfig: overlays: - istio repoRef: name: manifests path: tensorboard name: tensorboard - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: tf-training/tf-job-operator name: tf-job-operator - kustomizeConfig: repoRef: name: manifests path: pipeline/api-service name: api-service - kustomizeConfig: overlays: - minioPd parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - name: mysqlPvcName value: mysql-pv-claim repoRef: name: manifests path: pipeline/mysql name: mysql - kustomizeConfig: repoRef: name: manifests path: pipeline/persistent-agent name: persistent-agent - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-runner name: pipelines-runner - kustomizeConfig: overlays: - istio repoRef: name: manifests path: pipeline/pipelines-ui name: pipelines-ui - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-viewer name: pipelines-viewer - kustomizeConfig: repoRef: name: manifests path: pipeline/scheduledworkflow name: scheduledworkflow - kustomizeConfig: repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - istio parameters: - name: admin value: SET_EMAIL - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - managed-cert parameters: - name: namespace value: istio-system - name: ipName value: myapp2-ip - name: hostname value: myapp2.endpoints.foo-project.cloud.goog repoRef: name: manifests path: gcp/iap-ingress name: iap-ingress - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator plugins: - kind: KfGcpPlugin name: gcp namespace: kubeflow spec: createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs email: foo@gmail.com enableWorkloadIdentity: true project: foo-project skipInitProject: true useBasicAuth: false repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/master.tar.gz secrets: - name: env_password secretSource: envSource: name: ENV_PASSWORD_NAME - name: plain_text_password secretSource: literalSource: value: 12345 SkipInitProject: true useIstio: true status: {} ================================================ FILE: pkg/kfconfig/loaders/testdata/kfconfig_v1alpha1.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1alpha1 kind: KfConfig metadata: creationTimestamp: null name: myapp2 namespace: kubeflow annotations: testAnnotation: "dummy" labels: key1: "value1" spec: appDir: /tmp/myapp2 platform: gcp project: foo-project email: foo@gmail.com 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: "ON" 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: argo name: argo - kustomizeConfig: overlays: - istio parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: common/centraldashboard name: centraldashboard - kustomizeConfig: repoRef: name: manifests path: admission-webhook/webhook name: webhook - kustomizeConfig: parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-db name: katib-db - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-manager name: katib-manager - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-controller name: katib-controller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: katib-v1alpha2/katib-ui name: katib-ui - kustomizeConfig: overlays: - istio repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/metrics-collector name: metrics-collector - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/suggestion name: suggestion - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" repoRef: name: manifests path: jupyter/notebook-controller name: notebook-controller - kustomizeConfig: 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: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-crds name: knative-crds - kustomizeConfig: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-install name: knative-install - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-crds name: kfserving-crds - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-install name: kfserving-install - kustomizeConfig: parameters: - name: usageId value: "123456" - name: reportUsage value: "true" repoRef: name: manifests path: common/spartakus name: spartakus - kustomizeConfig: overlays: - istio repoRef: name: manifests path: tensorboard name: tensorboard - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: tf-training/tf-job-operator name: tf-job-operator - kustomizeConfig: repoRef: name: manifests path: pipeline/api-service name: api-service - kustomizeConfig: overlays: - minioPd parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - name: mysqlPvcName value: mysql-pv-claim repoRef: name: manifests path: pipeline/mysql name: mysql - kustomizeConfig: repoRef: name: manifests path: pipeline/persistent-agent name: persistent-agent - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-runner name: pipelines-runner - kustomizeConfig: overlays: - istio repoRef: name: manifests path: pipeline/pipelines-ui name: pipelines-ui - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-viewer name: pipelines-viewer - kustomizeConfig: repoRef: name: manifests path: pipeline/scheduledworkflow name: scheduledworkflow - kustomizeConfig: repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - istio parameters: - name: admin value: SET_EMAIL - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - managed-cert parameters: - name: namespace value: istio-system - name: ipName value: myapp2-ip - name: hostname value: myapp2.endpoints.foo-project.cloud.goog repoRef: name: manifests path: gcp/iap-ingress name: iap-ingress - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator plugins: - kind: KfGcpPlugin name: gcp namespace: kubeflow spec: createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs email: foo@gmail.com enableWorkloadIdentity: true project: foo-project skipInitProject: true useBasicAuth: false repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/master.tar.gz skipInitProject: true useIstio: true status: {} ================================================ FILE: pkg/kfconfig/loaders/testdata/kfconfig_v1beta1.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1beta1 kind: KfConfig metadata: creationTimestamp: null name: myapp2 namespace: kubeflow annotations: testAnnotation: "dummy" labels: key1: "value1" spec: project: foo-project email: foo@gmail.com platform: gcp 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: "ON" 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: argo name: argo - kustomizeConfig: overlays: - istio parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: common/centraldashboard name: centraldashboard - kustomizeConfig: repoRef: name: manifests path: admission-webhook/webhook name: webhook - kustomizeConfig: parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-db name: katib-db - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-manager name: katib-manager - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-controller name: katib-controller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: katib-v1alpha2/katib-ui name: katib-ui - kustomizeConfig: overlays: - istio repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/metrics-collector name: metrics-collector - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/suggestion name: suggestion - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" repoRef: name: manifests path: jupyter/notebook-controller name: notebook-controller - kustomizeConfig: 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: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-crds name: knative-crds - kustomizeConfig: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-install name: knative-install - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-crds name: kfserving-crds - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-install name: kfserving-install - kustomizeConfig: parameters: - name: usageId value: "123456" - name: reportUsage value: "true" repoRef: name: manifests path: common/spartakus name: spartakus - kustomizeConfig: overlays: - istio repoRef: name: manifests path: tensorboard name: tensorboard - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: tf-training/tf-job-operator name: tf-job-operator - kustomizeConfig: repoRef: name: manifests path: pipeline/api-service name: api-service - kustomizeConfig: overlays: - minioPd parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - name: mysqlPvcName value: mysql-pv-claim repoRef: name: manifests path: pipeline/mysql name: mysql - kustomizeConfig: repoRef: name: manifests path: pipeline/persistent-agent name: persistent-agent - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-runner name: pipelines-runner - kustomizeConfig: overlays: - istio repoRef: name: manifests path: pipeline/pipelines-ui name: pipelines-ui - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-viewer name: pipelines-viewer - kustomizeConfig: repoRef: name: manifests path: pipeline/scheduledworkflow name: scheduledworkflow - kustomizeConfig: repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - istio parameters: - name: admin value: SET_EMAIL - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - managed-cert parameters: - name: namespace value: istio-system - name: ipName value: myapp2-ip - name: hostname value: myapp2.endpoints.foo-project.cloud.goog repoRef: name: manifests path: gcp/iap-ingress name: iap-ingress - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator plugins: - kind: KfGcpPlugin name: gcp namespace: kubeflow spec: createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs email: foo@gmail.com enableWorkloadIdentity: true project: foo-project skipInitProject: true useBasicAuth: false repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/master.tar.gz secrets: - name: env_password secretSource: envSource: name: ENV_PASSWORD_NAME - name: plain_text_password secretSource: literalSource: value: 12345 SkipInitProject: true useIstio: true status: {} ================================================ FILE: pkg/kfconfig/loaders/testdata/kfctl_gcp_basic_auth.0.7.0.yaml ================================================ # Please set project and email! apiVersion: kfdef.apps.kubeflow.org/v1beta1 kind: KfDef metadata: # If name is not set, kfctl will infer app name from the directory. # name: myapp2 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio - application 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/webhook name: webhook - kustomizeConfig: overlays: - application parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" 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: "2700513155662330975" - 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 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: - minioPd - application parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd - application parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - 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: - gcp - 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 parameters: - name: ipName value: ipName - name: hostname repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - application - istio parameters: - name: admin # email will be auto-filled. # value: SET_EMAIL repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: overlays: - application repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator - kustomizeConfig: parameters: - name: ambassadorServiceType value: NodePort - name: namespace value: istio-system repoRef: name: manifests path: common/ambassador name: ambassador - kustomizeConfig: repoRef: name: manifests path: common/basic-auth name: basic-auth - kustomizeConfig: overlays: - managed-cert - application parameters: - name: namespace value: istio-system - name: ipName # ipName will be auto-filled based on app name if not set. # value: test1-ip - name: hostname # hostname will be auto-filled if not set. # value: .endpoints..cloud.goog - name: project # Project will be auto-filled. # value: SET_PROJECT - name: ingressName value: envoy-ingress - name: issuer value: letsencrypt-prod repoRef: name: manifests path: gcp/basic-auth-ingress name: basic-auth-ingress - kustomizeConfig: repoRef: name: manifests path: default-install name: default-install plugins: - kind: KfGcpPlugin metadata: creationTimestamp: null name: gcp spec: auth: basicAuth: username: usernameVal password: name: password createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs enableWorkloadIdentity: true skipInitProject: true useBasicAuth: true # email should be set the google account of the person setting up Kubeflow. # If its not set kfctl generate will try to set it automatically based on the default # gcloud config # email: # # Project should be set to the GCP project you want to use. # If you run kfctl init --config=/kfctl_gcp_iap.yaml # kfctl will try to automatically set it. # project: # # User can specify which zone to deploy to. If not set, will try to auto-fill # this field based on default config in gcloud. # zone: us-east1-d secrets: - name: password secretSource: literalSource: value: passwordVal repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/c0e81bedec9a4df8acf568cc5ccacc4bc05a3b38.tar.gz version: v0.7.0 ================================================ FILE: pkg/kfconfig/loaders/testdata/v1.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1 kind: KfDef metadata: creationTimestamp: null name: myapp2 namespace: kubeflow annotations: testAnnotation: "dummy" labels: key1: "value1" 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: "ON" 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: argo name: argo - kustomizeConfig: overlays: - istio parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: common/centraldashboard name: centraldashboard - kustomizeConfig: repoRef: name: manifests path: admission-webhook/webhook name: webhook - kustomizeConfig: parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-db name: katib-db - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-manager name: katib-manager - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-controller name: katib-controller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: katib-v1alpha2/katib-ui name: katib-ui - kustomizeConfig: overlays: - istio repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/metrics-collector name: metrics-collector - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/suggestion name: suggestion - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" repoRef: name: manifests path: jupyter/notebook-controller name: notebook-controller - kustomizeConfig: 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: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-crds name: knative-crds - kustomizeConfig: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-install name: knative-install - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-crds name: kfserving-crds - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-install name: kfserving-install - kustomizeConfig: parameters: - name: usageId value: "123456" - name: reportUsage value: "true" repoRef: name: manifests path: common/spartakus name: spartakus - kustomizeConfig: overlays: - istio repoRef: name: manifests path: tensorboard name: tensorboard - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: tf-training/tf-job-operator name: tf-job-operator - kustomizeConfig: repoRef: name: manifests path: pipeline/api-service name: api-service - kustomizeConfig: overlays: - minioPd parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - name: mysqlPvcName value: mysql-pv-claim repoRef: name: manifests path: pipeline/mysql name: mysql - kustomizeConfig: repoRef: name: manifests path: pipeline/persistent-agent name: persistent-agent - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-runner name: pipelines-runner - kustomizeConfig: overlays: - istio repoRef: name: manifests path: pipeline/pipelines-ui name: pipelines-ui - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-viewer name: pipelines-viewer - kustomizeConfig: repoRef: name: manifests path: pipeline/scheduledworkflow name: scheduledworkflow - kustomizeConfig: repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - istio parameters: - name: admin value: SET_EMAIL - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - managed-cert parameters: - name: namespace value: istio-system - name: ipName value: myapp2-ip - name: hostname value: myapp2.endpoints.foo-project.cloud.goog repoRef: name: manifests path: gcp/iap-ingress name: iap-ingress - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator plugins: - kind: KfGcpPlugin metadata: creationTimestamp: null name: gcp spec: createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs email: foo@gmail.com enableWorkloadIdentity: true project: foo-project skipInitProject: true useBasicAuth: false repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/master.tar.gz secrets: - name: env_password secretSource: envSource: name: ENV_PASSWORD_NAME - name: plain_text_password secretSource: literalSource: value: 12345 status: {} ================================================ FILE: pkg/kfconfig/loaders/testdata/v1alpha1.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1alpha1 kind: KfDef metadata: creationTimestamp: null name: myapp2 namespace: kubeflow annotations: testAnnotation: "dummy" labels: key1: "value1" spec: repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/master.tar.gz appdir: /tmp/myapp2 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: "ON" 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: argo name: argo - kustomizeConfig: overlays: - istio parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: "accounts.google.com:" repoRef: name: manifests path: common/centraldashboard name: centraldashboard - kustomizeConfig: repoRef: name: manifests path: admission-webhook/webhook name: webhook - kustomizeConfig: parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: "accounts.google.com:" repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-db name: katib-db - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-manager name: katib-manager - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-controller name: katib-controller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: katib-v1alpha2/katib-ui name: katib-ui - kustomizeConfig: overlays: - istio repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/metrics-collector name: metrics-collector - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/suggestion name: suggestion - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" repoRef: name: manifests path: jupyter/notebook-controller name: notebook-controller - kustomizeConfig: 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: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-crds name: knative-crds - kustomizeConfig: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-install name: knative-install - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-crds name: kfserving-crds - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-install name: kfserving-install - kustomizeConfig: parameters: - name: usageId value: "123456" - name: reportUsage value: "true" repoRef: name: manifests path: common/spartakus name: spartakus - kustomizeConfig: overlays: - istio repoRef: name: manifests path: tensorboard name: tensorboard - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: tf-training/tf-job-operator name: tf-job-operator - kustomizeConfig: repoRef: name: manifests path: pipeline/api-service name: api-service - kustomizeConfig: overlays: - minioPd parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - name: mysqlPvcName value: mysql-pv-claim repoRef: name: manifests path: pipeline/mysql name: mysql - kustomizeConfig: repoRef: name: manifests path: pipeline/persistent-agent name: persistent-agent - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-runner name: pipelines-runner - kustomizeConfig: overlays: - istio repoRef: name: manifests path: pipeline/pipelines-ui name: pipelines-ui - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-viewer name: pipelines-viewer - kustomizeConfig: repoRef: name: manifests path: pipeline/scheduledworkflow name: scheduledworkflow - kustomizeConfig: repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - istio parameters: - name: admin value: SET_EMAIL - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: "accounts.google.com:" repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - managed-cert parameters: - name: namespace value: istio-system - name: ipName value: myapp2-ip - name: hostname value: myapp2.endpoints.foo-project.cloud.goog repoRef: name: manifests path: gcp/iap-ingress name: iap-ingress - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator email: foo@gmail.com enableApplications: true packageManager: kustomize platform: gcp plugins: - name: gcp spec: createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs enableWorkloadIdentity: true useBasicAuth: false skipInitProject: true useBasicAuth: false useIstio: true project: foo-project ================================================ FILE: pkg/kfconfig/loaders/testdata/v1beta1.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1beta1 kind: KfDef metadata: creationTimestamp: null name: myapp2 namespace: kubeflow annotations: testAnnotation: "dummy" labels: key1: "value1" 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: "ON" 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: repoRef: name: manifests path: metacontroller name: metacontroller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: argo name: argo - kustomizeConfig: overlays: - istio parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: common/centraldashboard name: centraldashboard - kustomizeConfig: repoRef: name: manifests path: admission-webhook/webhook name: webhook - kustomizeConfig: parameters: - name: webhookNamePrefix value: admission-webhook- repoRef: name: manifests path: admission-webhook/bootstrap name: bootstrap - kustomizeConfig: overlays: - istio - application parameters: - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: jupyter/jupyter-web-app name: jupyter-web-app - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-db name: katib-db - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-manager name: katib-manager - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/katib-controller name: katib-controller - kustomizeConfig: overlays: - istio repoRef: name: manifests path: katib-v1alpha2/katib-ui name: katib-ui - kustomizeConfig: overlays: - istio repoRef: name: manifests path: metadata name: metadata - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/metrics-collector name: metrics-collector - kustomizeConfig: repoRef: name: manifests path: katib-v1alpha2/suggestion name: suggestion - kustomizeConfig: overlays: - istio - application parameters: - name: injectGcpCredentials value: "true" repoRef: name: manifests path: jupyter/notebook-controller name: notebook-controller - kustomizeConfig: 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: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-crds name: knative-crds - kustomizeConfig: parameters: - name: namespace value: knative-serving repoRef: name: manifests path: knative/knative-serving-install name: knative-install - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-crds name: kfserving-crds - kustomizeConfig: repoRef: name: manifests path: kfserving/kfserving-install name: kfserving-install - kustomizeConfig: parameters: - name: usageId value: "123456" - name: reportUsage value: "true" repoRef: name: manifests path: common/spartakus name: spartakus - kustomizeConfig: overlays: - istio repoRef: name: manifests path: tensorboard name: tensorboard - kustomizeConfig: overlays: - istio - application repoRef: name: manifests path: tf-training/tf-job-operator name: tf-job-operator - kustomizeConfig: repoRef: name: manifests path: pipeline/api-service name: api-service - kustomizeConfig: overlays: - minioPd parameters: - name: minioPd value: test1-storage-artifact-store - name: minioPvName value: minio-pv - name: minioPvcName value: minio-pv-claim repoRef: name: manifests path: pipeline/minio name: minio - kustomizeConfig: overlays: - mysqlPd parameters: - name: mysqlPd value: test1-storage-metadata-store - name: mysqlPvName value: mysql-pv - name: mysqlPvcName value: mysql-pv-claim repoRef: name: manifests path: pipeline/mysql name: mysql - kustomizeConfig: repoRef: name: manifests path: pipeline/persistent-agent name: persistent-agent - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-runner name: pipelines-runner - kustomizeConfig: overlays: - istio repoRef: name: manifests path: pipeline/pipelines-ui name: pipelines-ui - kustomizeConfig: repoRef: name: manifests path: pipeline/pipelines-viewer name: pipelines-viewer - kustomizeConfig: repoRef: name: manifests path: pipeline/scheduledworkflow name: scheduledworkflow - kustomizeConfig: repoRef: name: manifests path: gcp/cloud-endpoints name: cloud-endpoints - kustomizeConfig: overlays: - istio parameters: - name: admin value: SET_EMAIL - name: userid-header value: X-Goog-Authenticated-User-Email - name: userid-prefix value: 'accounts.google.com:' repoRef: name: manifests path: profiles name: profiles - kustomizeConfig: repoRef: name: manifests path: gcp/gpu-driver name: gpu-driver - kustomizeConfig: overlays: - managed-cert parameters: - name: namespace value: istio-system - name: ipName value: myapp2-ip - name: hostname value: myapp2.endpoints.foo-project.cloud.goog repoRef: name: manifests path: gcp/iap-ingress name: iap-ingress - kustomizeConfig: overlays: - application repoRef: name: manifests path: seldon/seldon-core-operator name: seldon-core-operator plugins: - kind: KfGcpPlugin metadata: creationTimestamp: null name: gcp spec: createPipelinePersistentStorage: true deploymentManagerConfig: repoRef: name: manifests path: gcp/deployment_manager_configs email: foo@gmail.com enableWorkloadIdentity: true project: foo-project skipInitProject: true useBasicAuth: false repos: - name: manifests uri: https://github.com/kubeflow/manifests/archive/master.tar.gz secrets: - name: env_password secretSource: envSource: name: ENV_PASSWORD_NAME - name: plain_text_password secretSource: literalSource: value: 12345 status: {} ================================================ FILE: pkg/kfconfig/loaders/utils.go ================================================ package loaders import ( kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" ) func maybeGetPlatform(pluginKind string) string { platforms := map[string]string{ string(kfconfig.AWS_PLUGIN_KIND): kftypesv3.AWS, string(kfconfig.GCP_PLUGIN_KIND): kftypesv3.GCP, string(kfconfig.EXISTING_ARRIKTO_PLUGIN_KIND): kftypesv3.EXISTING_ARRIKTO, } p, ok := platforms[pluginKind] if ok { return p } else { return "" } } ================================================ FILE: pkg/kfconfig/loaders/v1.go ================================================ package loaders import ( "fmt" "github.com/ghodss/yaml" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1" kfdefgcpplugin "github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" ) // Empty struct - used to implement Converter interface. type V1 struct { } func (v V1) LoadKfConfig(def interface{}) (*kfconfig.KfConfig, error) { kfdef := &kfdeftypes.KfDef{} if bytes, err := yaml.Marshal(def); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not marshal kfdef into bytes: %v", err), } } else { err = yaml.Unmarshal(bytes, kfdef) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not unpack kfdef: %v", err), } } } // Set UseBasicAuth later. config := &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, } config.Name = kfdef.Name config.Namespace = kfdef.Namespace config.APIVersion = kfdef.APIVersion config.Kind = "KfConfig" config.Labels = kfdef.Labels config.Annotations = kfdef.Annotations config.ClusterName = kfdef.ClusterName config.Spec.Version = kfdef.Spec.Version for i, app := range kfdef.Spec.Applications { if app.Name == "" { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("must have name for application. missing application name on application[%d] in kfdef", i), } } application := kfconfig.Application{ Name: app.Name, } if app.KustomizeConfig != nil { kconfig := &kfconfig.KustomizeConfig{ Overlays: app.KustomizeConfig.Overlays, } if app.KustomizeConfig.RepoRef != nil { kref := &kfconfig.RepoRef{ Name: app.KustomizeConfig.RepoRef.Name, Path: app.KustomizeConfig.RepoRef.Path, } kconfig.RepoRef = kref // Use application to infer whether UseBasicAuth is true. if kref.Path == "common/basic-auth" { config.Spec.UseBasicAuth = true } } for _, param := range app.KustomizeConfig.Parameters { p := kfconfig.NameValue{ Name: param.Name, Value: param.Value, } kconfig.Parameters = append(kconfig.Parameters, p) } application.KustomizeConfig = kconfig } config.Spec.Applications = append(config.Spec.Applications, application) } for _, plugin := range kfdef.Spec.Plugins { p := kfconfig.Plugin{ Name: plugin.Name, Namespace: kfdef.Namespace, Kind: kfconfig.PluginKindType(plugin.Kind), Spec: plugin.Spec, } config.Spec.Plugins = append(config.Spec.Plugins, p) if plugin.Kind == string(kfconfig.GCP_PLUGIN_KIND) { spec := kfdefgcpplugin.GcpPluginSpec{} if err := kfdef.GetPluginSpec(plugin.Kind, &spec); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not retrieve GCP plugin spec: %v", err), } } config.Spec.Project = spec.Project config.Spec.Email = spec.Email config.Spec.IpName = spec.IpName config.Spec.Hostname = spec.Hostname config.Spec.SkipInitProject = spec.SkipInitProject config.Spec.Zone = spec.Zone config.Spec.DeleteStorage = spec.DeleteStorage } if p := maybeGetPlatform(plugin.Kind); p != "" { config.Spec.Platform = p } } for _, secret := range kfdef.Spec.Secrets { s := kfconfig.Secret{ Name: secret.Name, } src := &kfconfig.SecretSource{} // kfdef -> kfconfig should keep literalSource , becasue only kfdef should be checked into source control, // We only filter secrets during kfconfig -> kfdef. if secret.SecretSource.LiteralSource != nil { src.LiteralSource = &kfconfig.LiteralSource{ Value: secret.SecretSource.LiteralSource.Value, } } if secret.SecretSource.EnvSource != nil { src.EnvSource = &kfconfig.EnvSource{ Name: secret.SecretSource.EnvSource.Name, } } s.SecretSource = src config.Spec.Secrets = append(config.Spec.Secrets, s) } for _, repo := range kfdef.Spec.Repos { r := kfconfig.Repo{ Name: repo.Name, URI: repo.URI, } config.Spec.Repos = append(config.Spec.Repos, r) } for _, cond := range kfdef.Status.Conditions { c := kfconfig.Condition{ Type: kfconfig.ConditionType(cond.Type), Status: cond.Status, LastUpdateTime: cond.LastUpdateTime, LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, Message: cond.Message, } config.Status.Conditions = append(config.Status.Conditions, c) } for _, cache := range kfdef.Status.ReposCache { c := kfconfig.Cache{ Name: cache.Name, LocalPath: cache.LocalPath, } config.Status.Caches = append(config.Status.Caches, c) } return config, nil } func (v V1) LoadKfDef(config kfconfig.KfConfig, out interface{}) error { kfdef := &kfdeftypes.KfDef{} kfdef.Name = config.Name kfdef.Namespace = config.Namespace kfdef.APIVersion = config.APIVersion kfdef.Kind = "KfDef" kfdef.Labels = config.Labels kfdef.Annotations = config.Annotations kfdef.ClusterName = config.ClusterName kfdef.Spec.Version = config.Spec.Version for _, app := range config.Spec.Applications { application := kfdeftypes.Application{ Name: app.Name, } if app.KustomizeConfig != nil { kconfig := &kfdeftypes.KustomizeConfig{ Overlays: app.KustomizeConfig.Overlays, } if app.KustomizeConfig.RepoRef != nil { kref := &kfdeftypes.RepoRef{ Name: app.KustomizeConfig.RepoRef.Name, Path: app.KustomizeConfig.RepoRef.Path, } kconfig.RepoRef = kref } for _, param := range app.KustomizeConfig.Parameters { p := kfdeftypes.NameValue{ Name: param.Name, Value: param.Value, } kconfig.Parameters = append(kconfig.Parameters, p) } application.KustomizeConfig = kconfig } kfdef.Spec.Applications = append(kfdef.Spec.Applications, application) } for _, plugin := range config.Spec.Plugins { p := kfdeftypes.Plugin{ Spec: plugin.Spec, } p.Name = plugin.Name p.Kind = string(plugin.Kind) kfdef.Spec.Plugins = append(kfdef.Spec.Plugins, p) } for _, secret := range config.Spec.Secrets { s := kfdeftypes.Secret{ Name: secret.Name, } if secret.SecretSource != nil { s.SecretSource = &kfdeftypes.SecretSource{} // We don't want to store literalSource explictly, becasue we want the config to be checked into source control and don't want secrets in source control. if secret.SecretSource.EnvSource != nil { s.SecretSource.EnvSource = &kfdeftypes.EnvSource{ Name: secret.SecretSource.EnvSource.Name, } } } kfdef.Spec.Secrets = append(kfdef.Spec.Secrets, s) } for _, repo := range config.Spec.Repos { r := kfdeftypes.Repo{ Name: repo.Name, URI: repo.URI, } kfdef.Spec.Repos = append(kfdef.Spec.Repos, r) } for _, cond := range config.Status.Conditions { c := kfdeftypes.KfDefCondition{ Type: kfdeftypes.KfDefConditionType(cond.Type), Status: cond.Status, LastUpdateTime: cond.LastUpdateTime, LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, Message: cond.Message, } kfdef.Status.Conditions = append(kfdef.Status.Conditions, c) } for _, cache := range config.Status.Caches { c := kfdeftypes.RepoCache{ Name: cache.Name, LocalPath: cache.LocalPath, } kfdef.Status.ReposCache = append(kfdef.Status.ReposCache, c) } kfdefBytes, err := yaml.Marshal(kfdef) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when marshaling to KfDef: %v", err), } } err = yaml.Unmarshal(kfdefBytes, out) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when unmarshaling to KfDef: %v", err), } } } ================================================ FILE: pkg/kfconfig/loaders/v1_test.go ================================================ package loaders import ( "io/ioutil" "os" "path" "reflect" "testing" "github.com/ghodss/yaml" "github.com/google/go-cmp/cmp" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfutils "github.com/kubeflow/kfctl/v3/pkg/utils" ) func TestV1_expectedConfig(t *testing.T) { type testCase struct { Input string Expected string } cases := []testCase{ testCase{ Input: "v1.yaml", Expected: "kfconfig_v1.yaml", }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Input) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } var obj interface{} if err := yaml.Unmarshal(buf, &obj); err != nil { t.Fatalf("Error when unmarshaling file %v; error %v", fPath, err) } v1beta1 := V1beta1{} config, err := v1beta1.LoadKfConfig(obj) if err != nil { t.Fatalf("Error converting to KfConfig: %v", err) } ePath := path.Join(wd, "testdata", c.Expected) eBuf, err := ioutil.ReadFile(ePath) if err != nil { t.Fatalf("Error when reading KfConfig: %v", err) } expectedConfig := &kfconfig.KfConfig{} err = yaml.Unmarshal(eBuf, expectedConfig) if err != nil { t.Fatalf("Error when unmarshaling KfConfig: %v", err) } if !reflect.DeepEqual(config, expectedConfig) { pGot := kfutils.PrettyPrint(config) pWant := kfutils.PrettyPrint(expectedConfig) t.Errorf("Loaded KfConfig doesn't match %v", cmp.Diff(pGot, pWant)) } } } ================================================ FILE: pkg/kfconfig/loaders/v1alpha1.go ================================================ package loaders import ( "fmt" "github.com/ghodss/yaml" configsv3 "github.com/kubeflow/kfctl/v3/config" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" kfgcpplugin "github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" ) // Empty struct - used to implement Converter interface. type V1alpha1 struct { } func pluginNameToKind(pluginName string) kfconfig.PluginKindType { mapper := map[string]kfconfig.PluginKindType{ kftypesv3.AWS: kfconfig.AWS_PLUGIN_KIND, kftypesv3.GCP: kfconfig.GCP_PLUGIN_KIND, kftypesv3.MINIKUBE: kfconfig.MINIKUBE_PLUGIN_KIND, kftypesv3.EXISTING_ARRIKTO: kfconfig.EXISTING_ARRIKTO_PLUGIN_KIND, } kind, ok := mapper[pluginName] if ok { return kind } else { return kfconfig.PluginKindType("KfUnknownPlugin") } } // Copy GCP plugin spec. Will skip if platform is not GCP. func copyGcpPluginSpec(from *kfdeftypes.KfDef, to *kfconfig.KfConfig) error { if from.Spec.Platform != kftypesv3.GCP { return nil } spec := kfgcpplugin.GcpPluginSpec{} if err := to.GetPluginSpec(kfconfig.GCP_PLUGIN_KIND, &spec); err != nil && !kfconfig.IsPluginNotFound(err) { return err } spec.Project = from.Spec.Project spec.Email = from.Spec.Email spec.IpName = from.Spec.IpName spec.Hostname = from.Spec.Hostname spec.Zone = from.Spec.Zone spec.UseBasicAuth = from.Spec.UseBasicAuth spec.SkipInitProject = from.Spec.SkipInitProject spec.DeleteStorage = from.Spec.DeleteStorage return to.SetPluginSpec(kfconfig.GCP_PLUGIN_KIND, spec) } func (v V1alpha1) LoadKfConfig(def interface{}) (*kfconfig.KfConfig, error) { kfdef := &kfdeftypes.KfDef{} if bytes, err := yaml.Marshal(def); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not marshal kfdef into bytes: %v", err), } } else { err = yaml.Unmarshal(bytes, kfdef) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not unpack kfdef: %v", err), } } } config := &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ AppDir: kfdef.Spec.AppDir, Version: kfdef.Spec.Version, UseBasicAuth: kfdef.Spec.UseBasicAuth, Project: kfdef.Spec.Project, Email: kfdef.Spec.Email, IpName: kfdef.Spec.IpName, Hostname: kfdef.Spec.Hostname, SkipInitProject: kfdef.Spec.SkipInitProject, Zone: kfdef.Spec.Zone, Platform: kfdef.Spec.Platform, }, } config.Name = kfdef.Name config.Namespace = kfdef.Namespace config.APIVersion = kfdef.APIVersion config.Kind = "KfConfig" config.Labels = kfdef.Labels config.Annotations = kfdef.Annotations config.ClusterName = kfdef.ClusterName for _, app := range kfdef.Spec.Applications { application := kfconfig.Application{ Name: app.Name, } if app.KustomizeConfig != nil { kconfig := &kfconfig.KustomizeConfig{ Overlays: app.KustomizeConfig.Overlays, } if app.KustomizeConfig.RepoRef != nil { kref := &kfconfig.RepoRef{ Name: app.KustomizeConfig.RepoRef.Name, Path: app.KustomizeConfig.RepoRef.Path, } kconfig.RepoRef = kref } for _, param := range app.KustomizeConfig.Parameters { p := kfconfig.NameValue{ Name: param.Name, Value: param.Value, } kconfig.Parameters = append(kconfig.Parameters, p) } application.KustomizeConfig = kconfig } config.Spec.Applications = append(config.Spec.Applications, application) } for _, plugin := range kfdef.Spec.Plugins { p := kfconfig.Plugin{ Name: plugin.Name, Namespace: kfdef.Namespace, Kind: pluginNameToKind(plugin.Name), Spec: plugin.Spec, } config.Spec.Plugins = append(config.Spec.Plugins, p) } specCopiers := []func(*kfdeftypes.KfDef, *kfconfig.KfConfig) error{ copyGcpPluginSpec, } for _, copier := range specCopiers { if err := copier(kfdef, config); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("error copying plugin specs: %v", err), } } } for _, secret := range kfdef.Spec.Secrets { s := kfconfig.Secret{ Name: secret.Name, } if secret.SecretSource == nil { config.Spec.Secrets = append(config.Spec.Secrets, s) continue } src := &kfconfig.SecretSource{} if secret.SecretSource.LiteralSource != nil { src.LiteralSource = &kfconfig.LiteralSource{ Value: secret.SecretSource.LiteralSource.Value, } } else if secret.SecretSource.EnvSource != nil { src.EnvSource = &kfconfig.EnvSource{ Name: secret.SecretSource.EnvSource.Name, } } else if secret.SecretSource.HashedSource != nil { src.HashedSource = &kfconfig.HashedSource{ HashedValue: secret.SecretSource.HashedSource.HashedValue, } } s.SecretSource = src config.Spec.Secrets = append(config.Spec.Secrets, s) } for _, repo := range kfdef.Spec.Repos { r := kfconfig.Repo{ Name: repo.Name, URI: repo.Uri, } config.Spec.Repos = append(config.Spec.Repos, r) } for _, cond := range kfdef.Status.Conditions { c := kfconfig.Condition{ Type: kfconfig.ConditionType(cond.Type), Status: cond.Status, LastUpdateTime: cond.LastUpdateTime, LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, Message: cond.Message, } config.Status.Conditions = append(config.Status.Conditions, c) } for name, cache := range kfdef.Status.ReposCache { c := kfconfig.Cache{ Name: name, LocalPath: cache.LocalPath, } config.Status.Caches = append(config.Status.Caches, c) } return config, nil } func (v V1alpha1) LoadKfDef(config kfconfig.KfConfig, out interface{}) error { kfdef := &kfdeftypes.KfDef{} kfdef.Name = config.Name kfdef.Namespace = config.Namespace kfdef.APIVersion = config.APIVersion kfdef.Kind = "KfDef" kfdef.Labels = config.Labels kfdef.Annotations = config.Annotations kfdef.ClusterName = config.ClusterName kfdef.Spec.AppDir = config.Spec.AppDir kfdef.Spec.Version = config.Spec.Version kfdef.Spec.UseBasicAuth = config.Spec.UseBasicAuth // Should be deprecated, hardcode it just to be safe. kfdef.Spec.EnableApplications = true kfdef.Spec.UseIstio = true kfdef.Spec.PackageManager = "kustomize" gcpSpec := &kfgcpplugin.GcpPluginSpec{} if err := config.GetPluginSpec(kfconfig.GCP_PLUGIN_KIND, gcpSpec); err == nil { kfdef.Spec.Project = gcpSpec.Project kfdef.Spec.Email = gcpSpec.Email kfdef.Spec.IpName = gcpSpec.IpName kfdef.Spec.Hostname = gcpSpec.Hostname kfdef.Spec.Zone = gcpSpec.Zone kfdef.Spec.SkipInitProject = gcpSpec.SkipInitProject kfdef.Spec.DeleteStorage = gcpSpec.DeleteStorage } for _, app := range config.Spec.Applications { application := kfdeftypes.Application{ Name: app.Name, } if app.KustomizeConfig != nil { kconfig := &kfdeftypes.KustomizeConfig{ Overlays: app.KustomizeConfig.Overlays, } if app.KustomizeConfig.RepoRef != nil { kref := &kfdeftypes.RepoRef{ Name: app.KustomizeConfig.RepoRef.Name, Path: app.KustomizeConfig.RepoRef.Path, } kconfig.RepoRef = kref } for _, param := range app.KustomizeConfig.Parameters { p := configsv3.NameValue{ Name: param.Name, Value: param.Value, } kconfig.Parameters = append(kconfig.Parameters, p) } application.KustomizeConfig = kconfig } kfdef.Spec.Applications = append(kfdef.Spec.Applications, application) } platform := "" for _, plugin := range config.Spec.Plugins { p := kfdeftypes.Plugin{ Name: plugin.Name, Spec: plugin.Spec, } kfdef.Spec.Plugins = append(kfdef.Spec.Plugins, p) if plugin.Name == kftypesv3.AWS { platform = kftypesv3.AWS } else if plugin.Name == kftypesv3.GCP { platform = kftypesv3.GCP } } kfdef.Spec.Platform = platform for _, secret := range config.Spec.Secrets { s := kfdeftypes.Secret{ Name: secret.Name, } if secret.SecretSource != nil { s.SecretSource = &kfdeftypes.SecretSource{} if secret.SecretSource.LiteralSource != nil { s.SecretSource.LiteralSource = &kfdeftypes.LiteralSource{ Value: secret.SecretSource.LiteralSource.Value, } } if secret.SecretSource.EnvSource != nil { s.SecretSource.EnvSource = &kfdeftypes.EnvSource{ Name: secret.SecretSource.EnvSource.Name, } } if secret.SecretSource.HashedSource != nil { s.SecretSource.HashedSource = &kfdeftypes.HashedSource{ HashedValue: secret.SecretSource.HashedSource.HashedValue, } } } kfdef.Spec.Secrets = append(kfdef.Spec.Secrets, s) } for _, repo := range config.Spec.Repos { r := kfdeftypes.Repo{ Name: repo.Name, Uri: repo.URI, } kfdef.Spec.Repos = append(kfdef.Spec.Repos, r) } kfdef.Status = kfdeftypes.KfDefStatus{} for _, cond := range config.Status.Conditions { c := kfdeftypes.KfDefCondition{ Type: kfdeftypes.KfDefConditionType(cond.Type), Status: cond.Status, LastUpdateTime: cond.LastUpdateTime, LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, Message: cond.Message, } kfdef.Status.Conditions = append(kfdef.Status.Conditions, c) } kfdef.Status.ReposCache = make(map[string]kfdeftypes.RepoCache) for _, cache := range config.Status.Caches { kfdef.Status.ReposCache[cache.Name] = kfdeftypes.RepoCache{ LocalPath: cache.LocalPath, } } kfdefBytes, err := yaml.Marshal(kfdef) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when marshaling to KfDef: %v", err), } } err = yaml.Unmarshal(kfdefBytes, out) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when unmarshaling to KfDef: %v", err), } } } ================================================ FILE: pkg/kfconfig/loaders/v1alpha1_test.go ================================================ package loaders import ( "github.com/ghodss/yaml" "github.com/google/go-cmp/cmp" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1alpha1" kfgcpplugin "github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfutils "github.com/kubeflow/kfctl/v3/pkg/utils" "io/ioutil" "os" "path" "reflect" "testing" ) func TestV1alpha1_ConvertToKfConfigs(t *testing.T) { type testCase struct { Input string Expected string } cases := []testCase{ testCase{ Input: "v1alpha1.yaml", Expected: "kfconfig_v1alpha1.yaml", }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Input) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } var obj interface{} if err := yaml.Unmarshal(buf, &obj); err != nil { t.Fatalf("Error when unmarshaling file %v; error %v", fPath, err) } v1alpha1 := V1alpha1{} config, err := v1alpha1.LoadKfConfig(obj) if err != nil { t.Fatalf("Error converting to KfConfig: %v", err) } ePath := path.Join(wd, "testdata", c.Expected) eBuf, err := ioutil.ReadFile(ePath) if err != nil { t.Fatalf("Error when reading KfConfig: %v", err) } expectedConfig := &kfconfig.KfConfig{} err = yaml.Unmarshal(eBuf, expectedConfig) if err != nil { t.Fatalf("Error when unmarshaling KfConfig: %v", err) } if !reflect.DeepEqual(config, expectedConfig) { pGot := kfutils.PrettyPrint(config) pWant := kfutils.PrettyPrint(expectedConfig) t.Errorf("Loaded KfConfig doesn't match: %v", cmp.Diff(pGot, pWant)) } } } func TestV1alpha1_ConvertToKfDef(t *testing.T) { type testCase struct { Input string Expected string } cases := []testCase{ testCase{ Input: "kfconfig_v1alpha1.yaml", Expected: "v1alpha1.yaml", }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Input) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } config := &kfconfig.KfConfig{} err := yaml.Unmarshal(buf, config) if err != nil { t.Fatalf("Error when unmarshaling KfConfig: %v", err) } v1alpha1 := V1alpha1{} got := &kfdeftypes.KfDef{} if err = v1alpha1.LoadKfDef(*config, got); err != nil { t.Fatalf("Error converting to KfDef: %v", err) } gcpSpec := &kfgcpplugin.GcpPluginSpec{} err = got.GetPluginSpec(kftypes.GCP, gcpSpec) if err != nil { t.Fatalf("Error when getting spec: %v", err) } newSpec := &kfgcpplugin.GcpPluginSpec{} newSpec.CreatePipelinePersistentStorage = gcpSpec.CreatePipelinePersistentStorage newSpec.EnableWorkloadIdentity = gcpSpec.EnableWorkloadIdentity newSpec.DeploymentManagerConfig = gcpSpec.DeploymentManagerConfig err = got.SetPluginSpec(kftypes.GCP, newSpec) if err != nil { t.Fatalf("Error when writing back GcpPluginSpec: %v", err) } ePath := path.Join(wd, "testdata", c.Expected) eBuf, err := ioutil.ReadFile(ePath) if err != nil { t.Fatalf("Error when reading KfDef: %v", err) } want := &kfdeftypes.KfDef{} err = yaml.Unmarshal(eBuf, want) if err != nil { t.Fatalf("Error when unmarshaling to KfDef: %v", err) } if !reflect.DeepEqual(got, want) { pGot := kfutils.PrettyPrint(got) pWant := kfutils.PrettyPrint(want) t.Errorf("Loaded KfConfig doesn't match: %v", cmp.Diff(pGot, pWant)) } } } ================================================ FILE: pkg/kfconfig/loaders/v1beta1.go ================================================ package loaders import ( "fmt" "github.com/ghodss/yaml" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kfdeftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfdef/v1beta1" kfdefgcpplugin "github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" ) // Empty struct - used to implement Converter interface. type V1beta1 struct { } func (v V1beta1) LoadKfConfig(def interface{}) (*kfconfig.KfConfig, error) { kfdef := &kfdeftypes.KfDef{} if bytes, err := yaml.Marshal(def); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not marshal kfdef into bytes: %v", err), } } else { err = yaml.Unmarshal(bytes, kfdef) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not unpack kfdef: %v", err), } } } // Set UseBasicAuth later. config := &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ UseBasicAuth: false, }, } config.Name = kfdef.Name config.Namespace = kfdef.Namespace config.APIVersion = kfdef.APIVersion config.Kind = "KfConfig" config.Labels = kfdef.Labels config.Annotations = kfdef.Annotations config.ClusterName = kfdef.ClusterName config.Spec.Version = kfdef.Spec.Version for _, app := range kfdef.Spec.Applications { application := kfconfig.Application{ Name: app.Name, } if app.KustomizeConfig != nil { kconfig := &kfconfig.KustomizeConfig{ Overlays: app.KustomizeConfig.Overlays, } if app.KustomizeConfig.RepoRef != nil { kref := &kfconfig.RepoRef{ Name: app.KustomizeConfig.RepoRef.Name, Path: app.KustomizeConfig.RepoRef.Path, } kconfig.RepoRef = kref // Use application to infer whether UseBasicAuth is true. if kref.Path == "common/basic-auth" { config.Spec.UseBasicAuth = true } } for _, param := range app.KustomizeConfig.Parameters { p := kfconfig.NameValue{ Name: param.Name, Value: param.Value, } kconfig.Parameters = append(kconfig.Parameters, p) } application.KustomizeConfig = kconfig } config.Spec.Applications = append(config.Spec.Applications, application) } for _, plugin := range kfdef.Spec.Plugins { p := kfconfig.Plugin{ Name: plugin.Name, Namespace: kfdef.Namespace, Kind: kfconfig.PluginKindType(plugin.Kind), Spec: plugin.Spec, } config.Spec.Plugins = append(config.Spec.Plugins, p) if plugin.Kind == string(kfconfig.GCP_PLUGIN_KIND) { spec := kfdefgcpplugin.GcpPluginSpec{} if err := kfdef.GetPluginSpec(plugin.Kind, &spec); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not retrieve GCP plugin spec: %v", err), } } config.Spec.Project = spec.Project config.Spec.Email = spec.Email config.Spec.IpName = spec.IpName config.Spec.Hostname = spec.Hostname config.Spec.SkipInitProject = spec.SkipInitProject config.Spec.Zone = spec.Zone config.Spec.DeleteStorage = spec.DeleteStorage } if p := maybeGetPlatform(plugin.Kind); p != "" { config.Spec.Platform = p } } for _, secret := range kfdef.Spec.Secrets { s := kfconfig.Secret{ Name: secret.Name, } src := &kfconfig.SecretSource{} // kfdef -> kfconfig should keep literalSource , becasue only kfdef should be checked into source control, // We only filter secrets during kfconfig -> kfdef. if secret.SecretSource.LiteralSource != nil { src.LiteralSource = &kfconfig.LiteralSource{ Value: secret.SecretSource.LiteralSource.Value, } } if secret.SecretSource.EnvSource != nil { src.EnvSource = &kfconfig.EnvSource{ Name: secret.SecretSource.EnvSource.Name, } } s.SecretSource = src config.Spec.Secrets = append(config.Spec.Secrets, s) } for _, repo := range kfdef.Spec.Repos { r := kfconfig.Repo{ Name: repo.Name, URI: repo.URI, } config.Spec.Repos = append(config.Spec.Repos, r) } for _, cond := range kfdef.Status.Conditions { c := kfconfig.Condition{ Type: kfconfig.ConditionType(cond.Type), Status: cond.Status, LastUpdateTime: cond.LastUpdateTime, LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, Message: cond.Message, } config.Status.Conditions = append(config.Status.Conditions, c) } for _, cache := range kfdef.Status.ReposCache { c := kfconfig.Cache{ Name: cache.Name, LocalPath: cache.LocalPath, } config.Status.Caches = append(config.Status.Caches, c) } return config, nil } func (v V1beta1) LoadKfDef(config kfconfig.KfConfig, out interface{}) error { kfdef := &kfdeftypes.KfDef{} kfdef.Name = config.Name kfdef.Namespace = config.Namespace kfdef.APIVersion = config.APIVersion kfdef.Kind = "KfDef" kfdef.Labels = config.Labels kfdef.Annotations = config.Annotations kfdef.ClusterName = config.ClusterName kfdef.Spec.Version = config.Spec.Version for _, app := range config.Spec.Applications { application := kfdeftypes.Application{ Name: app.Name, } if app.KustomizeConfig != nil { kconfig := &kfdeftypes.KustomizeConfig{ Overlays: app.KustomizeConfig.Overlays, } if app.KustomizeConfig.RepoRef != nil { kref := &kfdeftypes.RepoRef{ Name: app.KustomizeConfig.RepoRef.Name, Path: app.KustomizeConfig.RepoRef.Path, } kconfig.RepoRef = kref } for _, param := range app.KustomizeConfig.Parameters { p := kfdeftypes.NameValue{ Name: param.Name, Value: param.Value, } kconfig.Parameters = append(kconfig.Parameters, p) } application.KustomizeConfig = kconfig } kfdef.Spec.Applications = append(kfdef.Spec.Applications, application) } for _, plugin := range config.Spec.Plugins { p := kfdeftypes.Plugin{ Spec: plugin.Spec, } p.Name = plugin.Name p.Kind = string(plugin.Kind) kfdef.Spec.Plugins = append(kfdef.Spec.Plugins, p) } for _, secret := range config.Spec.Secrets { s := kfdeftypes.Secret{ Name: secret.Name, } if secret.SecretSource != nil { s.SecretSource = &kfdeftypes.SecretSource{} // We don't want to store literalSource explictly, becasue we want the config to be checked into source control and don't want secrets in source control. if secret.SecretSource.EnvSource != nil { s.SecretSource.EnvSource = &kfdeftypes.EnvSource{ Name: secret.SecretSource.EnvSource.Name, } } } kfdef.Spec.Secrets = append(kfdef.Spec.Secrets, s) } for _, repo := range config.Spec.Repos { r := kfdeftypes.Repo{ Name: repo.Name, URI: repo.URI, } kfdef.Spec.Repos = append(kfdef.Spec.Repos, r) } for _, cond := range config.Status.Conditions { c := kfdeftypes.KfDefCondition{ Type: kfdeftypes.KfDefConditionType(cond.Type), Status: cond.Status, LastUpdateTime: cond.LastUpdateTime, LastTransitionTime: cond.LastTransitionTime, Reason: cond.Reason, Message: cond.Message, } kfdef.Status.Conditions = append(kfdef.Status.Conditions, c) } for _, cache := range config.Status.Caches { c := kfdeftypes.RepoCache{ Name: cache.Name, LocalPath: cache.LocalPath, } kfdef.Status.ReposCache = append(kfdef.Status.ReposCache, c) } kfdefBytes, err := yaml.Marshal(kfdef) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when marshaling to KfDef: %v", err), } } err = yaml.Unmarshal(kfdefBytes, out) if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("error when unmarshaling to KfDef: %v", err), } } } ================================================ FILE: pkg/kfconfig/loaders/v1beta1_test.go ================================================ package loaders import ( "io/ioutil" "os" "path" "reflect" "testing" "github.com/ghodss/yaml" "github.com/google/go-cmp/cmp" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfutils "github.com/kubeflow/kfctl/v3/pkg/utils" ) func TestV1beta1_expectedConfig(t *testing.T) { type testCase struct { Input string Expected string } cases := []testCase{ testCase{ Input: "v1beta1.yaml", Expected: "kfconfig_v1beta1.yaml", }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Input) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } var obj interface{} if err := yaml.Unmarshal(buf, &obj); err != nil { t.Fatalf("Error when unmarshaling file %v; error %v", fPath, err) } v1beta1 := V1beta1{} config, err := v1beta1.LoadKfConfig(obj) if err != nil { t.Fatalf("Error converting to KfConfig: %v", err) } ePath := path.Join(wd, "testdata", c.Expected) eBuf, err := ioutil.ReadFile(ePath) if err != nil { t.Fatalf("Error when reading KfConfig: %v", err) } expectedConfig := &kfconfig.KfConfig{} err = yaml.Unmarshal(eBuf, expectedConfig) if err != nil { t.Fatalf("Error when unmarshaling KfConfig: %v", err) } if !reflect.DeepEqual(config, expectedConfig) { pGot := kfutils.PrettyPrint(config) pWant := kfutils.PrettyPrint(expectedConfig) t.Errorf("Loaded KfConfig doesn't match %v", cmp.Diff(pGot, pWant)) } } } ================================================ FILE: pkg/kfconfig/register.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. // NOTE: Boilerplate only. Ignore this file. // Package v1alpha1 contains API Schema definitions for the kfdef v1alpha1 API group // +k8s:openapi-gen=true // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=github.com/kubeflow/kfctl/v3/pkg/kfconfig // +k8s:defaulter-gen=TypeMeta // +groupName=kfconfig.apps.kubeflow.org package kfconfig import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes/scheme" ) var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: "kfconfig.apps.kubeflow.org", Version: "v1alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) localSchemeBuilder = &SchemeBuilder // AddToScheme is required by pkg/kfdef/... AddToScheme = localSchemeBuilder.AddToScheme ) // Resource is required by pkg/kfdef/listers/... func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &KfConfig{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil } func init() { metav1.AddToGroupVersion(scheme.Scheme, SchemeGroupVersion) utilruntime.Must(AddToScheme(scheme.Scheme)) } ================================================ FILE: pkg/kfconfig/testdata/doc.go ================================================ package testdata ================================================ FILE: pkg/kfconfig/testdata/kfctl_plugin_test.yaml ================================================ apiVersion: kfdef.apps.kubeflow.org/v1beta1 kind: KfConfig spec: applications: - name: delete - name: keep plugins: - kind: fakeplugin spec: param: someparam boolParam: true ================================================ FILE: pkg/kfconfig/types.go ================================================ package kfconfig import ( "archive/tar" "bytes" "compress/gzip" "fmt" "github.com/ghodss/yaml" gogetter "github.com/hashicorp/go-getter" "github.com/hashicorp/go-getter/helper/url" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/otiai10/copy" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "io" "io/ioutil" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "net/http" "os" "path" "path/filepath" "regexp" "sigs.k8s.io/kustomize/v3/pkg/types" "strings" ) const ( DefaultCacheDir = ".cache" // KfAppsStackName is the name that should be assigned to the application corresponding to the kubeflow // application stack. KfAppsStackName = "kubeflow-apps" KustomizeDir = "kustomize" ) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Internal data structure to hold app related info. // +k8s:openapi-gen=true type KfConfig struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec KfConfigSpec `json:"spec,omitempty"` Status Status `json:"status,omitempty"` } // The spec of kKfConfig type KfConfigSpec struct { // Shared fields among all components. should limit this list. // TODO(gabrielwen): Deprecate AppDir and move it to cache in Status. AppDir string `json:"appDir,omitempty"` // The filename of the config, e.g. app.yaml. // Base name only, as the directory is AppDir above. ConfigFileName string `json:"configFileName,omitempty"` Version string `json:"version,omitempty"` // TODO(gabrielwen): Can we infer this from Applications? UseBasicAuth bool `json:"useBasicAuth,omitempty"` Platform string `json:"platform,omitempty"` // TODO(gabrielwen): Deprecate these fields as they only makes sense to GCP. Project string `json:"project,omitempty"` Email string `json:"email,omitempty"` IpName string `json:"ipName,omitempty"` Hostname string `json:"hostname,omitempty"` SkipInitProject bool `json:"skipInitProject,omitempty"` Zone string `json:"zone,omitempty"` DeleteStorage bool `json:"deleteStorage,omitempty"` Applications []Application `json:"applications,omitempty"` Plugins []Plugin `json:"plugins,omitempty"` Secrets []Secret `json:"secrets,omitempty"` Repos []Repo `json:"repos,omitempty"` } // Application defines an application to install type Application struct { Name string `json:"name,omitempty"` KustomizeConfig *KustomizeConfig `json:"kustomizeConfig,omitempty"` } type KustomizeConfig struct { RepoRef *RepoRef `json:"repoRef,omitempty"` Overlays []string `json:"overlays,omitempty"` Parameters []NameValue `json:"parameters,omitempty"` } type RepoRef struct { Name string `json:"name,omitempty"` Path string `json:"path,omitempty"` } type NameValue struct { Name string `json:"name,omitempty"` Value string `json:"value,omitempty"` } type Plugin struct { Name string `json:"name,omitempty"` Namespace string `json:"namespace,omitempty"` Kind PluginKindType `json:"kind,omitempty"` Spec *runtime.RawExtension `json:"spec,omitempty"` } // Secret provides information about secrets needed to configure Kubeflow. // Secrets can be provided via references. type Secret struct { Name string `json:"name,omitempty"` SecretSource *SecretSource `json:"secretSource,omitempty"` } type SecretSource struct { LiteralSource *LiteralSource `json:"literalSource,omitempty"` HashedSource *HashedSource `json:"hashedSource,omitempty"` EnvSource *EnvSource `json:"envSource,omitempty"` } type LiteralSource struct { Value string `json:"value,omitempty"` } type HashedSource struct { HashedValue string `json:"value,omitempty"` } type EnvSource struct { Name string `json:"name,omitempty"` } // SecretRef is a reference to a secret type SecretRef struct { // Name of the secret Name string `json:"name,omitempty"` } // Repo provides information about a repository providing config (e.g. kustomize packages, // Deployment manager configs, etc...) type Repo struct { // Name is a name to identify the repository. Name string `json:"name,omitempty"` // URI where repository can be obtained. // Can use any URI understood by go-getter: // https://github.com/hashicorp/go-getter/blob/master/README.md#installation-and-usage URI string `json:"uri,omitempty"` } type Status struct { Conditions []Condition `json:"conditions,omitempty"` Caches []Cache `json:"caches,omitempty"` } type Condition struct { // Type of deployment condition. Type ConditionType `json:"type,omitempty"` // Status of the condition, one of True, False, Unknown. Status v1.ConditionStatus `json:"status,omitempty"` // The last time this condition was updated. LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` // Last time the condition transitioned from one status to another. LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` // The reason for the condition's last transition. Reason string `json:"reason,omitempty"` // A human readable message indicating details about the transition. Message string `json:"message,omitempty"` } type Cache struct { Name string `json:"name,omitempty"` LocalPath string `json:"localPath,omitempty"` } type PluginKindType string const ( // Used for populating plugin missing errors and identifying those // errors. pluginNotFoundErrPrefix = "Missing plugin" // Used for populating plugin missing errors and identifying those // errors. conditionNotFoundErrPrefix = "Missing condition" ) // Plugin kind used starting from v1beta1 const ( AWS_PLUGIN_KIND PluginKindType = "KfAwsPlugin" GCP_PLUGIN_KIND PluginKindType = "KfGcpPlugin" MINIKUBE_PLUGIN_KIND PluginKindType = "KfMinikubePlugin" EXISTING_ARRIKTO_PLUGIN_KIND PluginKindType = "KfExistingArriktoPlugin" ) type ConditionType string const ( // Available means Kubeflow is serving. Available ConditionType = "Available" // Degraded means one or more Kubeflow services are not healthy. Degraded ConditionType = "Degraded" // Pending means Kubeflow services is being updated. Pending ConditionType = "Pending" ) // Define plugin related conditions to be the format: // - conditions for successful plugins: ${PluginKind}Succeeded // - conditions for failed plugins: ${PluginKind}Failed func GetPluginSucceededCondition(pluginKind PluginKindType) ConditionType { return ConditionType(fmt.Sprintf("%vSucceeded", pluginKind)) } func GetPluginFailedCondition(pluginKind PluginKindType) ConditionType { return ConditionType(fmt.Sprintf("%vFailed", pluginKind)) } // Returns the repo with the name and true if repo exists. // nil and false otherwise. func (c *KfConfig) GetRepoCache(repoName string) (Cache, bool) { for _, r := range c.Status.Caches { if r.Name == repoName { return r, true } } return Cache{}, false } func (c *KfConfig) GetPluginSpec(pluginKind PluginKindType, s interface{}) error { for _, p := range c.Spec.Plugins { if p.Kind != pluginKind { continue } // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(p.Spec) if err != nil { msg := fmt.Sprintf("Could not marshal plugin %v args; error %v", pluginKind, err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: msg, } } err = yaml.Unmarshal(specBytes, s) if err != nil { msg := fmt.Sprintf("Could not unmarshal plugin %v to the provided type; error %v", pluginKind, err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: msg, } } return nil } return &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("%v %v", pluginNotFoundErrPrefix, pluginKind), } } // SetPluginSpec sets the requested parameter: add the plugin if it doesn't already exist, or replace existing plugin. func (c *KfConfig) SetPluginSpec(pluginKind PluginKindType, spec interface{}) error { // Convert spec to RawExtension r := &runtime.RawExtension{} // To deserialize it to a specific type we need to first serialize it to bytes // and then unserialize it. specBytes, err := yaml.Marshal(spec) if err != nil { msg := fmt.Sprintf("Could not marshal spec; error %v", err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: msg, } } err = yaml.Unmarshal(specBytes, r) if err != nil { msg := fmt.Sprintf("Could not unmarshal plugin to RawExtension; error %v", err) log.Errorf(msg) return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: msg, } } index := -1 for i, p := range c.Spec.Plugins { if p.Kind == pluginKind { index = i break } } if index == -1 { // Plugin in doesn't exist so add it log.Infof("Adding plugin %v", pluginKind) p := Plugin{} p.Name = string(pluginKind) p.Kind = pluginKind c.Spec.Plugins = append(c.Spec.Plugins, p) index = len(c.Spec.Plugins) - 1 } c.Spec.Plugins[index].Spec = r return nil } // Sets condition and status to KfConfig. func (c *KfConfig) SetCondition(condType ConditionType, status v1.ConditionStatus, reason string, message string) { now := metav1.Now() cond := Condition{ Type: condType, Status: status, LastUpdateTime: now, LastTransitionTime: now, Reason: reason, Message: message, } for i := range c.Status.Conditions { if c.Status.Conditions[i].Type != condType { continue } if c.Status.Conditions[i].Status == status { cond.LastTransitionTime = c.Status.Conditions[i].LastTransitionTime } c.Status.Conditions[i] = cond return } c.Status.Conditions = append(c.Status.Conditions, cond) } // Gets condition from KfConfig. func (c *KfConfig) GetCondition(condType ConditionType) (*Condition, error) { for i := range c.Status.Conditions { if c.Status.Conditions[i].Type == condType { return &c.Status.Conditions[i], nil } } return nil, &kfapis.KfError{ Code: int(kfapis.NOT_FOUND), Message: fmt.Sprintf("%v %v", conditionNotFoundErrPrefix, condType), } } func (c *KfConfig) IsPluginFinished(pluginKind PluginKindType) bool { condType := GetPluginSucceededCondition(pluginKind) cond, err := c.GetCondition(condType) if err != nil { if IsConditionNotFound(err) { return false } log.Warnf("Error when getting condition info: %v", err) return false } return cond.Status == v1.ConditionTrue } func (c *KfConfig) SetPluginFinished(pluginKind PluginKindType, msg string) { succeededCond := GetPluginSucceededCondition(pluginKind) failedCond := GetPluginFailedCondition(pluginKind) if _, err := c.GetCondition(failedCond); err == nil { c.SetCondition(failedCond, v1.ConditionFalse, "", "Reset to false as the plugin is set to be finished.") } c.SetCondition(succeededCond, v1.ConditionTrue, "", msg) } func (c *KfConfig) IsPluginFailed(pluginKind PluginKindType) bool { condType := GetPluginFailedCondition(pluginKind) cond, err := c.GetCondition(condType) if err != nil { if IsConditionNotFound(err) { return false } log.Warnf("Error when getting condition info: %v", err) return false } return cond.Status == v1.ConditionTrue } func (c *KfConfig) SetPluginFailed(pluginKind PluginKindType, msg string) { succeededCond := GetPluginSucceededCondition(pluginKind) failedCond := GetPluginFailedCondition(pluginKind) if _, err := c.GetCondition(succeededCond); err == nil { c.SetCondition(succeededCond, v1.ConditionFalse, "", "Reset to false as the plugin is set to be failed.") } c.SetCondition(failedCond, v1.ConditionTrue, "", msg) } // SyncCache will synchronize the local cache of any repositories. // On success the status is updated with pointers to the cache. // // TODO(jlewi): I'm not sure this handles head references correctly. // e.g. suppose we have a URI like // https://github.com/kubeflow/manifests/tarball/pull/189/head?archive=tar.gz // This gets unpacked to: kubeflow-manifests-e2c1bcb where e2c1bcb is the commit. // I don't think the code is currently setting the local directory for the cache correctly in // that case. // // // Using tarball vs. archive in github links affects the download path // e.g. // https://github.com/kubeflow/manifests/tarball/master?archive=tar.gz // unpacks to kubeflow-manifests-${COMMIT} // https://github.com/kubeflow/manifests/archive/master.tar.gz // unpacks to manifests-master // Always use archive format so that the path is predetermined. // // Instructions: https://github.com/hashicorp/go-getter#protocol-specific-options // // What is the correct syntax for downloading pull requests? // The following doesn't seem to work // https://github.com/kubeflow/manifests/archive/master.tar.gz?ref=pull/188 // * Appears to download master // // This appears to work // https://github.com/kubeflow/manifests/tarball/pull/188/head?archive=tar.gz // But unpacks it into // kubeflow-manifests-${COMMIT} // func (c *KfConfig) SyncCache() error { if c.Spec.AppDir == "" { return fmt.Errorf("AppDir must be specified") } appDir := c.Spec.AppDir // Loop over all the repos and download them. // TODO(https://github.com/kubeflow/kubeflow/issues/3545): We should check if we already have a local copy and // not redownload it. baseCacheDir := path.Join(appDir, DefaultCacheDir) if _, err := os.Stat(baseCacheDir); os.IsNotExist(err) { log.Infof("Creating directory %v", baseCacheDir) appdirErr := os.MkdirAll(baseCacheDir, os.ModePerm) if appdirErr != nil { log.Errorf("Couldn't create directory %v: %v", baseCacheDir, appdirErr) return appdirErr } } for _, r := range c.Spec.Repos { cacheDir := path.Join(baseCacheDir, r.Name) // Can we use a checksum or other mechanism to verify if the existing location is good? // If there was a problem the first time around then removing it might provide a way to recover. if _, err := os.Stat(cacheDir); err == nil { // Check if the cache is up to date. shouldSkip := false for _, cache := range c.Status.Caches { if cache.Name == r.Name && cache.LocalPath != "" { shouldSkip = true break } } if shouldSkip { log.Infof("%v exists; not resyncing ", cacheDir) continue } log.Infof("Deleting cachedir %v because Status.ReposCache is out of date", cacheDir) // TODO(jlewi): The reason the cachedir might exist but not be stored in KfDef.status // is because of a backwards compatibility path in which we download the cache to construct // the KfDef. Specifically coordinator.CreateKfDefFromOptions is calling kftypes.DownloadFromCache // We don't want to rely on that method to set the cache because we have logic // below to set LocalPath that we don't want to duplicate. // Unfortunately this means we end up fetching the repo twice which is very inefficient. if err := os.RemoveAll(cacheDir); err != nil { log.Errorf("There was a problem deleting directory %v; error %v", cacheDir, err) return errors.WithStack(err) } } u, err := url.Parse(r.URI) if err != nil { log.Errorf("Could not parse URI %v; error %v", r.URI, err) return errors.WithStack(err) } log.Infof("Fetching %v to %v", r.URI, cacheDir) fu, err := gogetter.Detect(r.URI, "", gogetter.Detectors) // from gogetter.getForcedGetter var forcedRegexp = regexp.MustCompile(`^([A-Za-z0-9]+)::(.+)$`) // uri is in go-getter format (i.e. not http, may also handle local) if ms := forcedRegexp.FindStringSubmatch(fu); ms != nil { tarballUrlErr := gogetter.GetAny(cacheDir, fu) if tarballUrlErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't download URI %v Error %v", fu, tarballUrlErr), } } } else { if err := os.MkdirAll(cacheDir, os.ModePerm); err != nil { log.Errorf("Could not create dir %v; error %v", cacheDir, err) return errors.WithStack(err) } // Manifests are local dir if fi, err := os.Stat(r.URI); err == nil && fi.Mode().IsDir() { // check whether the cache directory is a sub directory of manifests absCacheDir, err := filepath.Abs(cacheDir) if err != nil { return errors.WithStack(err) } absURI, err := filepath.Abs(r.URI) if err != nil { return errors.WithStack(err) } relDir, err := filepath.Rel(absURI, absCacheDir) if err != nil { return errors.WithStack(err) } if !strings.HasPrefix(relDir, ".."+string(filepath.Separator)) { return errors.WithStack(errors.New("SyncCache: could not sync cache when the cache path " + cacheDir + " is sub directory of manifests " + r.URI)) } if err := copy.Copy(r.URI, cacheDir); err != nil { return errors.WithStack(err) } } else { t := &http.Transport{ Proxy: http.ProxyFromEnvironment, } t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) t.RegisterProtocol("", http.NewFileTransport(http.Dir("/"))) hclient := &http.Client{Transport: t} req, _ := http.NewRequest("GET", r.URI, nil) req.Header.Set("User-Agent", "kfctl") resp, err := hclient.Do(req) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't download URI %v : %v", r.URI, err), } } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Errorf("Could not read response body; error %v", err) return errors.WithStack(err) } if err := untar(body, cacheDir); err != nil { log.Errorf("Could not untar file %v; error %v", r.URI, err) return errors.WithStack(err) } } } // This is a bit of a hack to deal with the fact that GitHub tarballs // can unpack to a directory containing the commit. localPath := cacheDir files, filesErr := ioutil.ReadDir(cacheDir) if filesErr != nil { log.Errorf("Error reading cachedir; error %v", filesErr) return errors.WithStack(filesErr) } if u.Scheme == "http" || u.Scheme == "https" { subdir := files[0].Name() localPath = path.Join(cacheDir, subdir) log.Infof("Updating localPath to %v", localPath) } else if u.Scheme == "file" { filePath := strings.TrimPrefix(r.URI, "file:") log.Infof("Probing file path: %v", filePath) if fileInfo, err := os.Stat(filePath); err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't stat the path %v: %v", filePath, err), } } else if !fileInfo.IsDir() { subdir := files[0].Name() localPath = path.Join(cacheDir, subdir) log.Infof("Updating localPath to %v", localPath) } } c.Status.Caches = append(c.Status.Caches, Cache{ Name: r.Name, LocalPath: localPath, }) log.Infof("Fetch succeeded; LocalPath %v", localPath) } return nil } func untar(body []byte, cacheDir string) error { gzf, err := gzip.NewReader(bytes.NewReader(body)) if err != nil { return err } tarReader := tar.NewReader(gzf) for { header, err := tarReader.Next() if err == io.EOF { break } if err != nil { return err } if header == nil { continue } target := filepath.Join(cacheDir, header.Name) switch header.Typeflag { case tar.TypeDir: if _, err := os.Stat(target); err != nil { if err := os.MkdirAll(target, 0755); err != nil { return err } } case tar.TypeReg: f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) if err != nil { return err } if _, err := io.Copy(f, tarReader); err != nil { return err } if err := f.Close(); err != nil { return err } } } return nil } // GetSecret returns the specified secret or an error if the secret isn't specified. func (c *KfConfig) GetSecret(name string) (string, error) { for _, s := range c.Spec.Secrets { if s.Name != name { continue } if s.SecretSource.LiteralSource != nil { return s.SecretSource.LiteralSource.Value, nil } if s.SecretSource.HashedSource != nil { return s.SecretSource.HashedSource.HashedValue, nil } if s.SecretSource.EnvSource != nil { return os.Getenv(s.SecretSource.EnvSource.Name), nil } return "", fmt.Errorf("No secret source provided for secret %v", name) } return "", NewSecretNotFound(name) } // GetSecretSource returns the SecretSource of the specified name or an error if the secret isn't specified. func (c *KfConfig) GetSecretSource(name string) (*SecretSource, error) { for _, s := range c.Spec.Secrets { if s.Name == name { return s.SecretSource, nil } } return nil, NewSecretNotFound(name) } // GetApplicationParameter gets the desired application parameter. func (c *KfConfig) GetApplicationParameter(appName string, paramName string) (string, bool) { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { for _, a := range c.Spec.Applications { if a.Name == appName { return getParameter(a.KustomizeConfig.Parameters, paramName) } } } return "", false } // addPatchStratgicMerge adds the patchFile to the strategic merge if it isn't already present. // Returns true if it is added func addPatchStratgicMerge(k *types.Kustomization, patchFile string) bool { for _, p := range k.PatchesStrategicMerge { if string(p) == patchFile { log.Infof("kustomization already defines a patch for %v", patchFile) return false } } k.PatchesStrategicMerge = append(k.PatchesStrategicMerge, types.PatchStrategicMerge(patchFile)) return true } // setApplicationParameterInConfigMap sets an application parameter by creatign or modifying a configMap // generator. // kustomizeDir: Directory of the kustomize application // appName: Name of the application // paramName: Name of the parameter // value: Value of the parameter // // N.B. In the YAML for the generated config map patch the creationTimeStamp is set to null. This appears to // be the result of how the struct is serialized. Hopefully having this field in the output doesn't cause problems // with kustomize and kubectl. func setApplicationParameterInConfigMap(kustomizeDir string, appName string, paramName string, value string) error { if _, err := os.Stat(kustomizeDir); err == nil { // Noop if the directory already exists. } else if os.IsNotExist(err) { log.Infof("Creating kustomize directory %v", kustomizeDir) if err := os.MkdirAll(kustomizeDir, os.ModePerm); err != nil { return errors.WithStack(errors.Wrapf(err, "Could not create directory: %v", kustomizeDir)) } } else { log.Errorf("Error checking directory %v; error %v", kustomizeDir, err) return errors.WithStack(err) } kustomizationFile := filepath.Join(kustomizeDir, kftypesv3.KustomizationFile) contents, err := ioutil.ReadFile(kustomizationFile) k := &types.Kustomization{} // The kustomization file may not exist yet in which case we keep going because we will just create it. if err == nil { if err := yaml.Unmarshal(contents, k); err != nil { return errors.WithStack(errors.Wrapf(err, "Failed to unmashal kustomization.yaml: %v", kustomizationFile)) } } else if err != nil && !os.IsNotExist(err) { return errors.WithStack(errors.Wrapf(err, "Failed to read: %v", kustomizationFile)) } configMapFileName := appName + "-config.yaml" if addPatchStratgicMerge(k, configMapFileName) { yaml, err := yaml.Marshal(k) if err != nil { return errors.WithStack(errors.Wrapf(err, "Error trying to marshal kustomization for kubeflow application: %v", appName)) } kustomizationFileErr := ioutil.WriteFile(kustomizationFile, yaml, 0644) if kustomizationFileErr != nil { return errors.WithStack(errors.Wrapf(kustomizationFileErr, "Error writing file: %v", kustomizationFile)) } } // Patch the parameter into the configmap. c := &v1.ConfigMap{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "ConfigMap", }, ObjectMeta: metav1.ObjectMeta{ Name: appName + "-config", CreationTimestamp: metav1.Time{}, }, } configMapPath := filepath.Join(kustomizeDir, configMapFileName) if contents, err := ioutil.ReadFile(configMapPath); err == nil { if err := yaml.Unmarshal(contents, c); err != nil { return errors.WithStack(errors.Wrapf(err, "Error reading configmap from file: %v", configMapPath)) } } else if !os.IsNotExist(err) { return errors.WithStack(errors.Wrapf(err, "Error trying to read file: %v", configMapPath)) } if c.Data == nil { c.Data = map[string]string{} } c.Data[paramName] = value newContents, err := yaml.Marshal(c) if err != nil { return errors.WithStack(errors.Wrapf(err, "Error while marshaling patch for configMap %v", configMapPath)) } if err := ioutil.WriteFile(configMapPath, newContents, os.ModePerm); err != nil { return errors.WithStack(errors.Wrapf(err, "Error while writing patch file: %v", configMapPath)) } return nil } // legacySetApplicationParameter sets the desired application parameter. // // This is the legacy version of KFDef that predates the use of kustomize stacks. In this case // application parameters are set by modifying the Applications in the KFDef spec. func (c *KfConfig) legacySetApplicationParameter(appName string, paramName string, value string) error { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { appIndex := -1 for i, a := range c.Spec.Applications { if a.Name == appName { appIndex = i } } if appIndex >= 0 { if c.Spec.Applications[appIndex].KustomizeConfig == nil { return errors.WithStack(fmt.Errorf("Application %v doesn't have KustomizeConfig", appName)) } c.Spec.Applications[appIndex].KustomizeConfig.Parameters = setParameter( c.Spec.Applications[appIndex].KustomizeConfig.Parameters, paramName, value) return nil } } log.Warnf("Application %v not found", appName) return nil } // SetApplicationParameter sets the desired application parameter. func (c *KfConfig) SetApplicationParameter(appName string, paramName string, value string) error { if c.UsingStacks() { // We need to map the application names to the stack they belong to. // Prior to the v3 version which introduced the stack there was a 1:1 mapping between the appName // and the kustomize directory for that application. // With the introduction of stacks some of the applications e.g. "jupyter-web-app" are now in the // the kubeflow-apps stack. So when we call SetApplicationParameter("jupyter-web-app",...) // we actually want to modify the config map inside ${KFAPP}/kustomize/kubeflow-apps // // TODO(jlewi): Is there a better way handle this other than hardcoding the path. appToStack := map[string]string{ "centraldashboard": KfAppsStackName, "cloud-endpoints": "cloud-endpoints", "default-install": KfAppsStackName, "istio-stack": "istio-stack", "iap-ingress": "iap-ingress", "jupyter-web-app": KfAppsStackName, "metacontroller": "metacontroller", "profiles": KfAppsStackName, "dex": "dex", // Spartakus is its own application because we want kfctl to be able to remove it. "spartakus": "spartakus", // AWS Specific "aws-alb-ingress-controller": KfAppsStackName, "istio-ingress": "istio-ingress", } appNameDir, ok := appToStack[appName] if !ok { // Default to assuming appNameDir is the same as appName if not explicitly // specified? appNameDir = appName log.Warnf("No stack directory specified for app %v; defaulting to %v", appName, appNameDir) } kustomizeDir := filepath.Join(c.Spec.AppDir, KustomizeDir, appNameDir) return setApplicationParameterInConfigMap(kustomizeDir, appName, paramName, value) } return c.legacySetApplicationParameter(appName, paramName, value) } // UsingStacks returns true if the KfDef is using kustomize to collect all of the Kubeflow applications func (c *KfConfig) UsingStacks() bool { if c.Spec.Applications == nil { return false } for _, a := range c.Spec.Applications { if a.Name == KfAppsStackName { return true } } return false } func (c *KfConfig) DeleteApplication(appName string) error { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { appIndex := -1 for i, a := range c.Spec.Applications { if a.Name == appName { appIndex = i } } if appIndex >= 0 { c.Spec.Applications = append(c.Spec.Applications[:appIndex], c.Spec.Applications[appIndex+1:]...) return nil } } log.Warnf("Application %v not found", appName) return nil } func (c *KfConfig) AddApplicationOverlay(appName, overlayName string) error { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { appIndex := -1 for i, a := range c.Spec.Applications { if a.Name == appName { appIndex = i } } if appIndex >= 0 { overlayIndex := -1 for i, o := range c.Spec.Applications[appIndex].KustomizeConfig.Overlays { if o == overlayName { overlayIndex = i } } if overlayIndex >= 0 { log.Warnf("Found existing overlay %v in Application %v, skip adding", appName, overlayName) } else { c.Spec.Applications[appIndex].KustomizeConfig.Overlays = append(c.Spec.Applications[appIndex].KustomizeConfig.Overlays, overlayName) } } else { log.Warnf("Application %v not found, overlay %v cannot be added", appName, overlayName) } } return nil } func (c *KfConfig) RemoveApplicationOverlay(appName, overlayName string) error { // First we check applications for an application with the specified name. if c.Spec.Applications != nil { appIndex := -1 for i, a := range c.Spec.Applications { if a.Name == appName { appIndex = i } } if appIndex >= 0 { overlayIndex := -1 for i, o := range c.Spec.Applications[appIndex].KustomizeConfig.Overlays { if o == overlayName { overlayIndex = i } } if overlayIndex >= 0 { c.Spec.Applications[appIndex].KustomizeConfig.Overlays = append(c.Spec.Applications[appIndex].KustomizeConfig.Overlays[:overlayIndex], c.Spec.Applications[appIndex].KustomizeConfig.Overlays[overlayIndex+1:]...) } else { log.Warnf("Cannot find overlay %v in Application %v, skip removing", appName, overlayName) } } else { log.Warnf("Application %v not found, overlay %v cannot be deleted", appName, overlayName) } } return nil } // SetSecret sets the specified secret; if a secret with the given name already exists it is overwritten. func (c *KfConfig) SetSecret(newSecret Secret) { for i, s := range c.Spec.Secrets { if s.Name == newSecret.Name { c.Spec.Secrets[i] = newSecret return } } c.Spec.Secrets = append(c.Spec.Secrets, newSecret) } func IsPluginNotFound(e error) bool { if e == nil { return false } err, ok := e.(*kfapis.KfError) return ok && err.Code == int(kfapis.NOT_FOUND) && strings.HasPrefix(err.Message, pluginNotFoundErrPrefix) } func IsConditionNotFound(e error) bool { if e == nil { return false } err, ok := e.(*kfapis.KfError) return ok && err.Code == int(kfapis.NOT_FOUND) && strings.HasPrefix(err.Message, conditionNotFoundErrPrefix) } type SecretNotFound struct { Name string } func (e *SecretNotFound) Error() string { return fmt.Sprintf("Missing secret %v", e.Name) } func NewSecretNotFound(n string) *SecretNotFound { return &SecretNotFound{ Name: n, } } func IsSecretNotFound(e error) bool { if e == nil { return false } _, ok := e.(*SecretNotFound) return ok } type AppNotFound struct { Name string } func (e *AppNotFound) Error() string { return fmt.Sprintf("Application %v is missing", e.Name) } func IsAppNotFound(e error) bool { if e == nil { return false } _, ok := e.(*AppNotFound) return ok } func getParameter(parameters []NameValue, paramName string) (string, bool) { for _, p := range parameters { if p.Name == paramName { return p.Value, true } } return "", false } func setParameter(parameters []NameValue, paramName string, value string) []NameValue { pIndex := -1 for i, p := range parameters { if p.Name == paramName { pIndex = i } } if pIndex < 0 { parameters = append(parameters, NameValue{}) pIndex = len(parameters) - 1 } parameters[pIndex].Name = paramName parameters[pIndex].Value = value return parameters } ================================================ FILE: pkg/kfconfig/types_test.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 kfconfig import ( "encoding/json" "github.com/ghodss/yaml" "github.com/google/go-cmp/cmp" "github.com/pkg/errors" "github.com/prometheus/common/log" "io" "io/ioutil" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "os" "path" "path/filepath" "reflect" "sigs.k8s.io/kustomize/v3/pkg/types" "testing" ) func TestSyncCache(t *testing.T) { type testCase struct { input *KfConfig expected []Cache expectedErr error } // Verify that we can sync some files. testDir, _ := ioutil.TempDir("", "") srcDir := path.Join(testDir, "src") err := os.Mkdir(srcDir, os.ModePerm) if err != nil { t.Fatalf("Failed to create directoy; %v", err) } ioutil.WriteFile(path.Join(srcDir, "file1"), []byte("hello world"), os.ModePerm) // Verify that we can unpack a local tarball and use it. tarballName := "c0e81bedec9a4df8acf568cc5ccacc4bc05a3b38.tar.gz" from, err := os.Open(path.Join("./testdata", tarballName)) if err != nil { t.Fatalf("failed to open tarball file: %v", err) } tarballPath := path.Join(srcDir, tarballName) to, err := os.OpenFile(tarballPath, os.O_RDWR|os.O_CREATE, 0666) if err != nil { t.Fatalf("failed to open new file location fortarball file: %v", err) } if _, err = io.Copy(to, from); err != nil { t.Fatalf("tarball copy is failed: %v", err) } repoName := "testRepo" testCases := []testCase{ { input: &KfConfig{ Spec: KfConfigSpec{ AppDir: path.Join(testDir, "app1"), Repos: []Repo{{ Name: repoName, URI: srcDir, }, }, }, }, expected: []Cache{ { Name: repoName, LocalPath: path.Join(testDir, "app1", ".cache", repoName), }, }, expectedErr: nil, }, { input: &KfConfig{ Spec: KfConfigSpec{ AppDir: path.Join(srcDir, "app1"), Repos: []Repo{{ Name: repoName, URI: srcDir, }, }, }, }, expected: nil, expectedErr: errors.New("SyncCache: could not sync cache when the cache path " + path.Join(srcDir, "app1", ".cache", repoName) + " is sub directory of manifests " + srcDir), }, { input: &KfConfig{ Spec: KfConfigSpec{ AppDir: ".", Repos: []Repo{{ Name: repoName, URI: srcDir, }, }, }, }, expected: []Cache{ { Name: repoName, LocalPath: path.Join(".cache", repoName), }, }, expectedErr: nil, }, { input: &KfConfig{ Spec: KfConfigSpec{ AppDir: path.Join(testDir, "app2"), Repos: []Repo{{ Name: repoName, URI: "file:" + tarballPath, }, }, }, }, expected: []Cache{ { Name: repoName, LocalPath: path.Join(testDir, "app2", ".cache", repoName, "kubeflow-manifests-c0e81be"), }, }, expectedErr: nil, }, // The following test cases pull from GitHub. The may be worth commenting // out in the unittests and only running manually //{ // input: &KfConfig{ // Spec: KfConfigSpec{ // AppDir: path.Join(testDir, "app2"), // Repos: []Repo{{ // Name: repoName, // URI: "https://github.com/kubeflow/manifests/archive/master.tar.gz", // }, // }, // }, // }, // expected: []Cache { // { // LocalPath: path.Join(testDir, "app2", ".cache", repoName, "manifests-master"), // }, // }, //}, //{ // input: &KfConfig{ // Spec: KfConfigSpec{ // AppDir: path.Join(testDir, "app3"), // Repos: []Repo{{ // Name: repoName, // URI: "https://github.com/kubeflow/manifests/tarball/pull/187/head?archive=tar.gz", // }, // }, // }, // }, // expected: []Cache { // { // LocalPath: path.Join(testDir, "app3", ".cache", repoName, "kubeflow-manifests-c04764b"), // }, // }, //}, } for _, c := range testCases { err = c.input.SyncCache() // remove the local path for the test case whose AppDir is "." if c.input.Spec.AppDir == "." { os.RemoveAll(path.Join(".cache", repoName)) } if err != nil { if c.expectedErr == nil || err.Error() != c.expectedErr.Error() { t.Fatalf("Could not sync cache; %v", err) } } if c.expected != nil { actual := c.input.Status.Caches[0].LocalPath expected := c.expected[0].LocalPath if actual != expected { t.Fatalf("LocalPath; got %v; want %v", actual, expected) } } } } type FakePluginSpec struct { Param string `json:"param,omitempty"` BoolParam bool `json:"boolParam,omitempty"` } func TestKfConfig_GetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { Filename string PluginName string PluginKind PluginKindType Expected *FakePluginSpec } cases := []testCase{ { Filename: "kfctl_plugin_test.yaml", PluginName: "fake", PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "someparam", BoolParam: true, }, }, } for _, c := range cases { wd, _ := os.Getwd() fPath := path.Join(wd, "testdata", c.Filename) buf, bufErr := ioutil.ReadFile(fPath) if bufErr != nil { t.Fatalf("Error reading file %v; error %v", fPath, bufErr) } log.Infof("Want ") d := &KfConfig{} err := yaml.Unmarshal(buf, d) if err != nil { t.Fatalf("Could not parse as KfConfig error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginKind, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin spec got;\n%v\nwant;\n%v", pGot, pWant) } } } func TestKfConfig_SetPluginSpec(t *testing.T) { // Test that we can properly parse the gcp structs. type testCase struct { PluginName string PluginKind PluginKindType Expected *FakePluginSpec } cases := []testCase{ { PluginName: "fake", PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "oldparam", BoolParam: true, }, }, // Override the existing plugin { PluginName: "fake", PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, // Add a new plugin { PluginName: "fake", PluginKind: "fakeplugin", Expected: &FakePluginSpec{ Param: "newparam", BoolParam: true, }, }, } d := &KfConfig{} for _, c := range cases { err := d.SetPluginSpec(c.PluginKind, c.Expected) if err != nil { t.Fatalf("Could not set plugin spec; error %v", err) } actual := &FakePluginSpec{} err = d.GetPluginSpec(c.PluginKind, actual) if err != nil { t.Fatalf("Could not get plugin spec; error %v", err) } if !reflect.DeepEqual(actual, c.Expected) { pGot, _ := Pformat(actual) pWant, _ := Pformat(c.Expected) t.Errorf("Error parsing plugin, plugin spec doesn't match %v", cmp.Diff(pGot, pWant)) } } } func TestKfConfig_GetSecret(t *testing.T) { d := &KfConfig{ Spec: KfConfigSpec{ AppDir: "someapp", Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "somedata", }, }, }, { Name: "s2", SecretSource: &SecretSource{ EnvSource: &EnvSource{ Name: "s2", }, }, }, }, }, } type testCase struct { SecretName string ExpectedValue string } cases := []testCase{ { SecretName: "s1", ExpectedValue: "somedata", }, { SecretName: "s2", ExpectedValue: "somesecret", }, } os.Setenv("s2", "somesecret") for _, c := range cases { actual, err := d.GetSecret(c.SecretName) if err != nil { t.Errorf("Error getting secret %v; error %v", c.SecretName, err) } if actual != c.ExpectedValue { t.Errorf("Secret %v value doesn't match %v", c.SecretName, cmp.Diff(actual, c.ExpectedValue)) } } } func TestKfConfig_SetSecret(t *testing.T) { type testCase struct { Input KfConfig Secret Secret Expected KfConfig } cases := []testCase{ // No Secrets exist { Input: KfConfig{}, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, Expected: KfConfig{ Spec: KfConfigSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "v1", }, }, }, }, }, }, }, // Override a secret { Input: KfConfig{ Spec: KfConfigSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "oldvalue", }, }, }, }, }, }, Secret: Secret{ Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, Expected: KfConfig{ Spec: KfConfigSpec{ Secrets: []Secret{ { Name: "s1", SecretSource: &SecretSource{ LiteralSource: &LiteralSource{ Value: "newvalue", }, }, }, }, }, }, }, } for _, c := range cases { i := &KfConfig{} *i = c.Input i.SetSecret(c.Secret) if !reflect.DeepEqual(*i, c.Expected) { pGot, _ := Pformat(i) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting secret %v; got;\n%v\nwant;\n%v", c.Secret.Name, pGot, pWant) } } } func TestKfConfig_addPatchStratgicMerge(t *testing.T) { type testCase struct { Input *types.Kustomization PatchName string Expected *types.Kustomization } cases := []testCase{ // New parameter { Input: &types.Kustomization{}, PatchName: "new-config.yaml", Expected: &types.Kustomization{ PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("new-config.yaml"), }, }, }, // Existing parameter { Input: &types.Kustomization{ PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("config1.yaml"), types.PatchStrategicMerge("exists-config.yaml"), types.PatchStrategicMerge("config2.yaml"), }, }, PatchName: "exists-config.yaml", Expected: &types.Kustomization{ PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("config1.yaml"), types.PatchStrategicMerge("exists-config.yaml"), types.PatchStrategicMerge("config2.yaml"), }, }, }, } for _, c := range cases { addPatchStratgicMerge(c.Input, c.PatchName) if !reflect.DeepEqual(c.Input, c.Expected) { pGot, _ := Pformat(c.Input) pWant, _ := Pformat(c.Expected) t.Errorf("Error adding patch %v; got;\n%v\nwant;\n%v", c.PatchName, pGot, pWant) } } } func Test_setApplicationParameterInConfigMap(t *testing.T) { type testCase struct { Name string InputKustomization *types.Kustomization InputPatch *v1.ConfigMap AppName string ParameterName string Value string ExpectedKustomization *types.Kustomization ExpectedPatch *v1.ConfigMap } cases := []testCase{ // New parameter { Name: "No-patch", InputKustomization: &types.Kustomization{}, InputPatch: nil, AppName: "app", ParameterName: "param", Value: "value", ExpectedKustomization: &types.Kustomization{ PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("app-config.yaml"), }, }, ExpectedPatch: &v1.ConfigMap{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "ConfigMap", }, ObjectMeta: metav1.ObjectMeta{ Name: "app-config", }, Data: map[string]string{ "param": "value", }, }, }, // Modify existing parameter { Name: "existing-parameter", InputKustomization: &types.Kustomization{}, InputPatch: &v1.ConfigMap{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "ConfigMap", }, ObjectMeta: metav1.ObjectMeta{ Name: "app-config", }, Data: map[string]string{ "a": "b", "param": "oldvalue", "d": "e", }, }, AppName: "app", ParameterName: "param", Value: "newvalue", ExpectedKustomization: &types.Kustomization{ PatchesStrategicMerge: []types.PatchStrategicMerge{ types.PatchStrategicMerge("app-config.yaml"), }, }, ExpectedPatch: &v1.ConfigMap{ TypeMeta: metav1.TypeMeta{ APIVersion: "v1", Kind: "ConfigMap", }, ObjectMeta: metav1.ObjectMeta{ Name: "app-config", }, Data: map[string]string{ "a": "b", "param": "newvalue", "d": "e", }, }, }, } for _, c := range cases { // Create a kustomization app based on the inputs. testDir, err := ioutil.TempDir("", "testSetApplicationParameter-"+c.Name) log.Infof("Test case: %v; directory: %v", c.Name, testDir) if err != nil { t.Fatalf("Could not creat temporary directory: %v", err) } type pair struct { o interface{} path string } pairs := []pair{ { o: c.InputKustomization, path: filepath.Join(testDir, "kustomization.yaml"), }, } if c.InputPatch != nil { pairs = append(pairs, pair{ o: c.InputPatch, path: filepath.Join(testDir, c.AppName+"-config.yaml"), }) } for _, p := range pairs { kBytes, err := yaml.Marshal(p.o) if err != nil { t.Fatalf("Could not marshal yaml error: %v", err) } if err := ioutil.WriteFile(p.path, kBytes, os.ModePerm); err != nil { t.Fatalf("Could not write file: %v; error %v", p.path, err) } } setApplicationParameterInConfigMap(testDir, c.AppName, c.ParameterName, c.Value) parse := func(path string, o interface{}) { b, err := ioutil.ReadFile(path) if err != nil { t.Fatalf("Could not read file: %v; error %v", path, err) } if err := yaml.Unmarshal(b, o); err != nil { t.Fatalf("Could not read unmarshal yaml; error: %v", err) } } actualKustomization := &types.Kustomization{} actualPatch := &v1.ConfigMap{} parse(filepath.Join(testDir, "kustomization.yaml"), actualKustomization) parse(filepath.Join(testDir, c.AppName+"-config.yaml"), actualPatch) if !reflect.DeepEqual(actualKustomization, c.ExpectedKustomization) { pGot, _ := Pformat(actualKustomization) pWant, _ := Pformat(c.ExpectedKustomization) t.Errorf("Case %v: kustomization.yaml: got;\n%v\nwant;\n%v", c.Name, pGot, pWant) } if !reflect.DeepEqual(actualPatch, c.ExpectedPatch) { pGot, _ := Pformat(actualPatch) pWant, _ := Pformat(c.ExpectedPatch) t.Errorf("Case %v: kustomization.yaml: got;\n%v\nwant;\n%v", c.Name, pGot, pWant) } } } func TestKfConfig_SetApplicationParameter(t *testing.T) { type testCase struct { Input *KfConfig AppName string ParamName string Value string Expected *KfConfig } cases := []testCase{ // New parameter { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{}, }, }, }, }, AppName: "app1", ParamName: "p1", Value: "v1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []NameValue{ { Name: "p1", Value: "v1", }, }, }, }, }, }, }, }, // Override parameter { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, AppName: "app1", ParamName: "p1", Value: "v1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []NameValue{ { Name: "p1", Value: "v1", }, }, }, }, }, }, }, }, } for _, c := range cases { c.Input.SetApplicationParameter(c.AppName, c.ParamName, c.Value) if !reflect.DeepEqual(c.Input, c.Expected) { pGot, _ := Pformat(c.Input) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting App %v; Param %v; value %v; got;\n%v\nwant;\n%v", c.AppName, c.ParamName, c.Value, pGot, pWant) } } } func TestKfConfig_GetApplicationParameter(t *testing.T) { type testCase struct { Input *KfConfig AppName string ParamName string Expected string HasParam bool } cases := []testCase{ // No parameter { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{}, }, }, }, }, AppName: "app1", ParamName: "p1", Expected: "", HasParam: false, }, // Has Parameter { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app2", KustomizeConfig: &KustomizeConfig{ Parameters: []NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, AppName: "app2", ParamName: "p1", Expected: "old1", HasParam: true, }, } for _, c := range cases { v, hasParam := c.Input.GetApplicationParameter(c.AppName, c.ParamName) if c.HasParam != hasParam { t.Errorf("Error getting App %v; Param %v; hasParam; got; %v; want %v", c.AppName, c.ParamName, hasParam, c.HasParam) } if c.Expected != v { t.Errorf("Error getting App %v; Param %v; got; %v; want %v", c.AppName, c.ParamName, c, c.Expected) } } } func TestKfConfig_DeleteApplication(t *testing.T) { type testCase struct { Input *KfConfig AppNameToDelete string Expected *KfConfig } cases := []testCase{ { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{}, }, { Name: "app2", KustomizeConfig: &KustomizeConfig{}, }, }, }, }, AppNameToDelete: "app1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app2", KustomizeConfig: &KustomizeConfig{}, }, }, }, }, }, { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Parameters: []NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, AppNameToDelete: "app1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{}, }, }, }, } for _, c := range cases { c.Input.DeleteApplication(c.AppNameToDelete) if !reflect.DeepEqual(c.Input, c.Expected) { pGot, _ := Pformat(c.Input) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting App %v; got;\n%v\nwant;\n%v", c.AppNameToDelete, pGot, pWant) } } } func TestKfConfig_AddApplicationOverlay(t *testing.T) { type testCase struct { Input *KfConfig AppName string OverlayToAdd string Expected *KfConfig } cases := []testCase{ // overlay already exist { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, AppName: "app1", OverlayToAdd: "overlay1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, }, // app not found { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", }, }, }, }, }, }, AppName: "app2", OverlayToAdd: "overlay1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", }, }, }, }, }, }, }, // normal { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", }, }, }, }, }, }, AppName: "app1", OverlayToAdd: "overlay2", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", }, }, }, }, }, }, }, } for _, c := range cases { c.Input.AddApplicationOverlay(c.AppName, c.OverlayToAdd) if !reflect.DeepEqual(c.Input, c.Expected) { pGot, _ := Pformat(c.Input) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting App %v; got;\n%v\nwant;\n%v", c.OverlayToAdd, pGot, pWant) } } } func TestKfConfig_RemoveApplicationOverlay(t *testing.T) { type testCase struct { Input *KfConfig AppName string OverlayToRemove string Expected *KfConfig } cases := []testCase{ // Normal case - remove overlay on boarder { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, AppName: "app1", OverlayToRemove: "overlay1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay2", "overlay3", }, }, }, }, }, }, }, // Normal case - remove overlay in the middle { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, AppName: "app1", OverlayToRemove: "overlay2", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay3", }, }, }, }, }, }, }, // Can not find app -> remain same { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, AppName: "app2", OverlayToRemove: "overlay2", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, }, // Can not find overlay -> remain same { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, AppName: "app1", OverlayToRemove: "overlay4", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{ "overlay1", "overlay2", "overlay3", }, }, }, }, }, }, }, // no overlay -> remain same { Input: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{}, }, }, }, }, }, AppName: "app1", OverlayToRemove: "overlay1", Expected: &KfConfig{ Spec: KfConfigSpec{ Applications: []Application{ { Name: "app1", KustomizeConfig: &KustomizeConfig{ Overlays: []string{}, }, }, }, }, }, }, } for _, c := range cases { c.Input.RemoveApplicationOverlay(c.AppName, c.OverlayToRemove) if !reflect.DeepEqual(c.Input, c.Expected) { pGot, _ := Pformat(c.Input) pWant, _ := Pformat(c.Expected) t.Errorf("Error setting App %v; overlay %v; got;\n%v\nwant;\n%v", c.AppName, c.OverlayToRemove, pGot, pWant) } } } // Pformat returns a pretty format output of any value. func Pformat(value interface{}) (string, error) { if s, ok := value.(string); ok { return s, nil } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { return "", err } return string(valueJson), nil } ================================================ FILE: pkg/kfconfig/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 kfconfig import ( runtime "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AppNotFound) DeepCopyInto(out *AppNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppNotFound. func (in *AppNotFound) DeepCopy() *AppNotFound { if in == nil { return nil } out := new(AppNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Application) DeepCopyInto(out *Application) { *out = *in if in.KustomizeConfig != nil { in, out := &in.KustomizeConfig, &out.KustomizeConfig *out = new(KustomizeConfig) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. func (in *Application) DeepCopy() *Application { if in == nil { return nil } out := new(Application) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Cache) DeepCopyInto(out *Cache) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cache. func (in *Cache) DeepCopy() *Cache { if in == nil { return nil } out := new(Cache) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Condition) DeepCopyInto(out *Condition) { *out = *in in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. func (in *Condition) DeepCopy() *Condition { if in == nil { return nil } out := new(Condition) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EnvSource) DeepCopyInto(out *EnvSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvSource. func (in *EnvSource) DeepCopy() *EnvSource { if in == nil { return nil } out := new(EnvSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HashedSource) DeepCopyInto(out *HashedSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashedSource. func (in *HashedSource) DeepCopy() *HashedSource { if in == nil { return nil } out := new(HashedSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfConfig) DeepCopyInto(out *KfConfig) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfConfig. func (in *KfConfig) DeepCopy() *KfConfig { if in == nil { return nil } out := new(KfConfig) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. func (in *KfConfig) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } return nil } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KfConfigSpec) DeepCopyInto(out *KfConfigSpec) { *out = *in if in.Applications != nil { in, out := &in.Applications, &out.Applications *out = make([]Application, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]Plugin, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Secrets != nil { in, out := &in.Secrets, &out.Secrets *out = make([]Secret, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Repos != nil { in, out := &in.Repos, &out.Repos *out = make([]Repo, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KfConfigSpec. func (in *KfConfigSpec) DeepCopy() *KfConfigSpec { if in == nil { return nil } out := new(KfConfigSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KustomizeConfig) DeepCopyInto(out *KustomizeConfig) { *out = *in if in.RepoRef != nil { in, out := &in.RepoRef, &out.RepoRef *out = new(RepoRef) **out = **in } if in.Overlays != nil { in, out := &in.Overlays, &out.Overlays *out = make([]string, len(*in)) copy(*out, *in) } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters *out = make([]NameValue, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizeConfig. func (in *KustomizeConfig) DeepCopy() *KustomizeConfig { if in == nil { return nil } out := new(KustomizeConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LiteralSource) DeepCopyInto(out *LiteralSource) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LiteralSource. func (in *LiteralSource) DeepCopy() *LiteralSource { if in == nil { return nil } out := new(LiteralSource) 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 *Plugin) DeepCopyInto(out *Plugin) { *out = *in if in.Spec != nil { in, out := &in.Spec, &out.Spec *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin. func (in *Plugin) DeepCopy() *Plugin { if in == nil { return nil } out := new(Plugin) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Repo) DeepCopyInto(out *Repo) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Repo. func (in *Repo) DeepCopy() *Repo { if in == nil { return nil } out := new(Repo) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RepoRef) DeepCopyInto(out *RepoRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoRef. func (in *RepoRef) DeepCopy() *RepoRef { if in == nil { return nil } out := new(RepoRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Secret) DeepCopyInto(out *Secret) { *out = *in if in.SecretSource != nil { in, out := &in.SecretSource, &out.SecretSource *out = new(SecretSource) (*in).DeepCopyInto(*out) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Secret. func (in *Secret) DeepCopy() *Secret { if in == nil { return nil } out := new(Secret) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretNotFound) DeepCopyInto(out *SecretNotFound) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretNotFound. func (in *SecretNotFound) DeepCopy() *SecretNotFound { if in == nil { return nil } out := new(SecretNotFound) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretRef. func (in *SecretRef) DeepCopy() *SecretRef { if in == nil { return nil } out := new(SecretRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretSource) DeepCopyInto(out *SecretSource) { *out = *in if in.LiteralSource != nil { in, out := &in.LiteralSource, &out.LiteralSource *out = new(LiteralSource) **out = **in } if in.HashedSource != nil { in, out := &in.HashedSource, &out.HashedSource *out = new(HashedSource) **out = **in } if in.EnvSource != nil { in, out := &in.EnvSource, &out.EnvSource *out = new(EnvSource) **out = **in } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretSource. func (in *SecretSource) DeepCopy() *SecretSource { if in == nil { return nil } out := new(SecretSource) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Status) DeepCopyInto(out *Status) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Caches != nil { in, out := &in.Caches, &out.Caches *out = make([]Cache, len(*in)) copy(*out, *in) } return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. func (in *Status) DeepCopy() *Status { if in == nil { return nil } out := new(Status) in.DeepCopyInto(out) return out } ================================================ FILE: pkg/kfupgrade/kfupgrade.go ================================================ // 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 kfupgrade package kfupgrade import ( "bytes" "context" "crypto/sha256" "encoding/base32" "encoding/json" "fmt" "os" "path/filepath" "reflect" "strings" "k8s.io/client-go/kubernetes/scheme" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypesv3 "github.com/kubeflow/kfctl/v3/pkg/apis/apps" kfupgrade "github.com/kubeflow/kfctl/v3/pkg/apis/apps/kfupgrade/v1alpha1" kfdefgcpplugin "github.com/kubeflow/kfctl/v3/pkg/apis/apps/plugins/gcp/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfapp/coordinator" "github.com/kubeflow/kfctl/v3/pkg/kfconfig" kfconfigloaders "github.com/kubeflow/kfctl/v3/pkg/kfconfig/loaders" applicationsv1beta1 "github.com/kubernetes-sigs/application/pkg/apis/app/v1beta1" log "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" ) type KfUpgrader struct { OldKfCfg *kfconfig.KfConfig NewKfCfg *kfconfig.KfConfig TargetPath string } // Given a path to a base config and the existing KfCfg, create and return a new KfCfg // while keeping the existing KfApp's customizations. Also create a new KfApp in the // current working directory. func createNewKfApp(baseConfig string, version string, oldKfCfg *kfconfig.KfConfig) (*kfconfig.KfConfig, string, error) { appDir, err := os.Getwd() if err != nil { return nil, "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not get current directory %v", err), } } // Load the new KfCfg from the base config newKfCfg, err := kfconfigloaders.LoadConfigFromURI(baseConfig) if err != nil { return nil, "", &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Could not load %v. Error: %v", baseConfig, err), } } // Merge the previous KfCfg's customized values into the new KfCfg MergeKfCfg(oldKfCfg, newKfCfg) // Compute hash from the new KfCfg and use it to create the new app directory h, err := computeHash(newKfCfg) if err != nil { return nil, "", &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Could not compute sha256 hash. Error: %v", err), } } newAppDir := filepath.Join(appDir, h) newKfCfg.Spec.AppDir = newAppDir newKfCfg.Spec.Version = version outputFilePath := filepath.Join(newAppDir, newKfCfg.Spec.ConfigFileName) // Make sure the directory is created. if _, err := os.Stat(newAppDir); os.IsNotExist(err) { log.Infof("Creating directory %v", newAppDir) err = os.MkdirAll(newAppDir, os.ModePerm) if err != nil { log.Errorf("Couldn't create directory %v: %v", newAppDir, err) return nil, "", err } } else { log.Infof("App directory %v already exists", newAppDir) } err = kfconfigloaders.WriteConfigToFile(*newKfCfg) if err != nil { return nil, "", err } return newKfCfg, outputFilePath, nil } // Given a KfUpgrade config, either find the KfApp that matches the NewKfCfg reference or // create a new one. func NewKfUpgrade(upgradeConfig string) (*KfUpgrader, error) { // Parse the KfUpgrade spec. upgrade, err := kfupgrade.LoadKfUpgradeFromUri(upgradeConfig) if err != nil { log.Errorf("Could not load %v; error %v", upgradeConfig, err) return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: err.Error(), } } // Try to find the old KfCfg. oldKfCfg, _, err := findKfCfg(upgrade.Spec.CurrentKfDef) if err != nil || oldKfCfg == nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Could not find existing KfCfg %v. Error: %v", upgrade.Spec.CurrentKfDef.Name, err), } } // Try to find the new KfCfg. newKfCfg, targetPath, err := findKfCfg(upgrade.Spec.NewKfDef) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Encountered error while trying to find %v: %v", upgrade.Spec.NewKfDef.Name, err), } } // If the new KfCfg is not found, create it if newKfCfg == nil { newKfCfg, targetPath, err = createNewKfApp(upgrade.Spec.BaseConfigPath, upgrade.Spec.NewKfDef.Version, oldKfCfg) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Encountered error while creating new KfApp %v: %v", upgrade.Spec.NewKfDef.Name, err), } } } return &KfUpgrader{ OldKfCfg: oldKfCfg, NewKfCfg: newKfCfg, TargetPath: targetPath, }, nil } func computeHash(d *kfconfig.KfConfig) (string, error) { h := sha256.New() buf := new(bytes.Buffer) json.NewEncoder(buf).Encode(d) h.Write([]byte(buf.Bytes())) id := base32.HexEncoding.WithPadding(base32.NoPadding).EncodeToString(h.Sum(nil)) id = strings.ToLower(id)[0:7] return id, nil } func findKfCfg(kfDefRef *kfupgrade.KfDefRef) (*kfconfig.KfConfig, string, error) { var target *kfconfig.KfConfig var targetPath string err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error { if target != nil { // If we already found the target directory, skip return nil } if strings.Contains(path, ".cache") { // Skip cache directories return nil } if !strings.HasSuffix(path, "yaml") { // Skip everything that's not a yaml file return nil } kfCfg, err := kfconfigloaders.LoadConfigFromURI(path) if err != nil { return nil } if kfCfg.Name == kfDefRef.Name && kfCfg.Spec.Version == kfDefRef.Version { log.Infof("Found KfCfg with matching name: %v version: %v at %v", kfCfg.Name, kfCfg.Spec.Version, path) target = kfCfg targetPath = path } return err }) if err != nil { log.Println(err) return nil, "", err } wd, err := os.Getwd() if err != nil { return nil, "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not get current directory %v", err), } } return target, filepath.Join(wd, targetPath), err } func MergeKfCfg(oldKfCfg *kfconfig.KfConfig, newKfCfg *kfconfig.KfConfig) { newKfCfg.Name = oldKfCfg.Name // Merge plugins. pluginKinds := []kfconfig.PluginKindType{ kfconfig.AWS_PLUGIN_KIND, kfconfig.GCP_PLUGIN_KIND, kfconfig.MINIKUBE_PLUGIN_KIND, kfconfig.EXISTING_ARRIKTO_PLUGIN_KIND, } for _, kind := range pluginKinds { oldPlugin := kfdefgcpplugin.GcpPluginSpec{} err := oldKfCfg.GetPluginSpec(kind, &oldPlugin) // If no error, then this plugin is found and we need to copy it to the new KfCfg. if err == nil { log.Infof("Merging plugin spec: %v\n", kind) newKfCfg.SetPluginSpec(kind, &oldPlugin) } } for appIndex, newApp := range newKfCfg.Spec.Applications { for _, oldApp := range oldKfCfg.Spec.Applications { if newApp.Name == oldApp.Name { for paramIndex, newParam := range newApp.KustomizeConfig.Parameters { for _, oldParam := range oldApp.KustomizeConfig.Parameters { if newParam.Name == oldParam.Name && newParam.Value != oldParam.Value { log.Infof("Merging application %v param %v from %v to %v\n", newApp.Name, newParam.Name, newParam.Value, oldParam.Value) newKfCfg.Spec.Applications[appIndex].KustomizeConfig.Parameters[paramIndex].Value = oldParam.Value break } } } break } } } } func (upgrader *KfUpgrader) Generate() error { kfApp, err := coordinator.NewLoadKfAppFromURI(upgrader.TargetPath) if err != nil { log.Errorf("Failed to build KfApp from URI: %v", err) return err } return kfApp.Generate(kftypesv3.K8S) } func (upgrader *KfUpgrader) Apply() error { kfApp, err := coordinator.NewLoadKfAppFromURI(upgrader.TargetPath) if err != nil { log.Errorf("Failed to build KfApp from URI: %v", err) return err } err = kfApp.Generate(kftypesv3.K8S) if err != nil { log.Errorf("Failed to generate KfApp: %v", err) return err } err = upgrader.DeleteObsoleteResources(upgrader.OldKfCfg.ObjectMeta.Namespace) if err != nil { log.Errorf("Failed to delete obsolete resources: %v", err) return err } err = upgrader.DeleteObsoleteResources("istio-system") if err != nil { log.Errorf("Failed to delete obsolete resources: %v", err) return err } return kfApp.Apply(kftypesv3.K8S) } func (upgrader *KfUpgrader) Dump() error { kfApp, err := coordinator.NewLoadKfAppFromURI(upgrader.TargetPath) if err != nil { log.Errorf("Failed to build KfApp from URI: %v", err) return err } return kfApp.Dump(kftypesv3.K8S) } func (upgrader *KfUpgrader) DeleteObsoleteResources(ns string) error { applicationsv1beta1.AddToScheme(scheme.Scheme) log.Infof("Deleting resources in in namespace %v", ns) objs := []runtime.Object{ &applicationsv1beta1.Application{}, &appsv1.Deployment{}, &appsv1.StatefulSet{}, &appsv1.ReplicaSet{}, &appsv1.DaemonSet{}, } for _, obj := range objs { err := upgrader.DeleteResources(ns, obj) if err != nil { return err } } return nil } func (upgrader *KfUpgrader) DeleteResources(ns string, obj runtime.Object) error { config := kftypesv3.GetConfig() kubeClient, err := client.New(config, client.Options{}) objKind := reflect.TypeOf(obj) log.Infof("Deleting resources type %v in in namespace %v", objKind, ns) err = kubeClient.DeleteAllOf(context.Background(), obj, client.InNamespace(ns), client.MatchingLabels{ "app.kubernetes.io/part-of": "kubeflow", }, client.PropagationPolicy(metav1.DeletePropagationBackground)) if err != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't delete %v Error: %v", objKind, err), } } return nil } ================================================ FILE: pkg/kfupgrade/kfupgrade_test.go ================================================ package kfupgrade import ( "github.com/kubeflow/kfctl/v3/pkg/kfconfig" "github.com/kubeflow/kfctl/v3/pkg/utils" "reflect" "testing" ) func Test_MergeKfCfg(t *testing.T) { type testCase struct { oldKf *kfconfig.KfConfig newKf *kfconfig.KfConfig expected *kfconfig.KfConfig } testCases := []testCase{ // Param names are different; no merging. { oldKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, newKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p2", Value: "old2", }, }, }, }, }, }, }, expected: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p2", Value: "old2", }, }, }, }, }, }, }, }, // App names are different, no merging { oldKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app2", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "old1", }, }, }, }, }, }, }, newKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app3", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "new1", }, }, }, }, }, }, }, expected: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app3", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "new1", }, }, }, }, }, }, }, }, // Merging old param values to new { oldKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "old1", }, { Name: "p2", Value: "old2", }, }, }, }, }, }, }, newKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "new1", }, { Name: "p2", Value: "new2", }, }, }, }, }, }, }, expected: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "old1", }, { Name: "p2", Value: "old2", }, }, }, }, }, }, }, }, // Merging two apps { oldKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "old1", }, }, }, }, { Name: "app2", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p2", Value: "old2", }, }, }, }, }, }, }, newKf: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "new1", }, }, }, }, { Name: "app2", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p2", Value: "new2", }, }, }, }, }, }, }, expected: &kfconfig.KfConfig{ Spec: kfconfig.KfConfigSpec{ Applications: []kfconfig.Application{ { Name: "app1", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p1", Value: "old1", }, }, }, }, { Name: "app2", KustomizeConfig: &kfconfig.KustomizeConfig{ Parameters: []kfconfig.NameValue{ { Name: "p2", Value: "old2", }, }, }, }, }, }, }, }, } for _, c := range testCases { MergeKfCfg(c.oldKf, c.newKf) if !reflect.DeepEqual(c.newKf, c.expected) { t.Errorf("MergeKfCfg produced incorrect results; got\n%v\nwant:\n%v", utils.PrettyPrint(c.newKf), utils.PrettyPrint(c.expected)) } } } ================================================ FILE: pkg/mirror/mirror_image.go ================================================ package mirror import ( "fmt" "github.com/ghodss/yaml" mirrorv1alpha1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/imagemirror/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/kfapp/kustomize" "github.com/kubeflow/kfctl/v3/pkg/utils" "github.com/pkg/errors" log "github.com/sirupsen/logrus" pipeline "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" cloudbuild "google.golang.org/api/cloudbuild/v1" "io/ioutil" "k8s.io/apimachinery/pkg/apis/meta/v1" "os" "path" "path/filepath" "regexp" "sort" "strings" ) const INPUT_IMAGE = "inputImage" const OUTPUT_IMAGE = "outputImage" const CONTEXT = "context" const TASK_NAME = "mirror-image" const KUSTOMIZE_FOLDER = "kustomize" const CLOUD_BUILD_IMAGE = "gcr.io/cloud-builders/docker" const CLOUD_BUILD_FILE = "cloudbuild.yaml" type ReplicateTasks map[string]string // buildContext: gs:/// func GenerateMirroringPipeline(directory string, spec mirrorv1alpha1.ReplicationSpec, outputFileName string, gcb bool) error { replicateTasks := make(ReplicateTasks) for _, pattern := range spec.Patterns { if err := replicateTasks.fillTasks(directory, pattern.Dest, spec.Context, pattern.Src.Include, pattern.Src.Exclude); err != nil { return err } } pipelineTasks := []pipeline.PipelineTask{} idx := 0 re := regexp.MustCompile("[^a-z0-9]+") for _, newImg := range replicateTasks.orderedKeys() { oldImg := replicateTasks[newImg] pipelineTasks = append(pipelineTasks, pipeline.PipelineTask{ Name: fmt.Sprintf("%v-%v", idx, re.ReplaceAllString(oldImg, "-")), TaskRef: &pipeline.TaskRef{ Name: TASK_NAME, }, Params: []pipeline.Param{ { Name: INPUT_IMAGE, Value: pipeline.ArrayOrString{ Type: pipeline.ParamTypeString, StringVal: oldImg, }, }, { Name: OUTPUT_IMAGE, Value: pipeline.ArrayOrString{ Type: pipeline.ParamTypeString, StringVal: newImg, }, }, { Name: CONTEXT, Value: pipeline.ArrayOrString{ Type: pipeline.ParamTypeString, StringVal: "$(params.context)", }, }, }, }) idx++ } pipelineIns := pipeline.PipelineRun{ TypeMeta: v1.TypeMeta{ APIVersion: "tekton.dev/v1alpha1", Kind: "PipelineRun", }, ObjectMeta: v1.ObjectMeta{ Name: "replication-pipeline", }, Spec: pipeline.PipelineRunSpec{ PipelineSpec: &pipeline.PipelineSpec{ Tasks: pipelineTasks, Params: []pipeline.ParamSpec{ { Name: CONTEXT, Type: pipeline.ParamTypeString, }, }, }, Params: []pipeline.Param{ { Name: CONTEXT, Value: pipeline.ArrayOrString{ Type: pipeline.ParamTypeString, StringVal: spec.Context, }, }, }, }, } buf, err := yaml.Marshal(pipelineIns) if err != nil { return err } writeErr := ioutil.WriteFile(outputFileName, buf, 0644) if writeErr != nil { return errors.WithStack(writeErr) } if gcb { return generateCloudBuild(replicateTasks) } return nil } func generateCloudBuild(rt ReplicateTasks) error { steps := []*cloudbuild.BuildStep{} images := []string{} for _, newImg := range rt.orderedKeys() { oldImg := rt[newImg] log.Infof("Add gcb step" + oldImg) steps = append(steps, &cloudbuild.BuildStep{ Name: CLOUD_BUILD_IMAGE, Args: []string{"build", "-t", newImg, "--build-arg=INPUT_IMAGE=" + oldImg, "."}, WaitFor: []string{"-"}, }, ) images = append(images, newImg) } cb := cloudbuild.Build{ Steps: steps, Images: images, } buf, err := yaml.Marshal(cb) if err != nil { return err } return ioutil.WriteFile(CLOUD_BUILD_FILE, buf, 0644) } func (rt *ReplicateTasks) orderedKeys() []string { var keys []string for k := range *rt { keys = append(keys, k) } sort.Strings(keys) return keys } // processKustomizeDir processes the specified kustomize directory func (rt *ReplicateTasks) processKustomizeDir(absPath string, registry string, include string, exclude string) error { log.Infof("Processing %v", absPath) kustomizationFilePath := filepath.Join(absPath, "kustomization.yaml") if _, err := os.Stat(kustomizationFilePath); err != nil { log.Infof("Skipping %v; no kustomization.yaml found", absPath) return nil } kustomization := kustomize.GetKustomization(absPath) for _, image := range kustomization.Images { curName := image.Name if image.NewName != "" { curName = image.NewName } if strings.Contains(curName, "$") { log.Infof("Image name %v contains kutomize parameter, skipping\n", curName) continue } // check exclude first if exclude != "" && strings.HasPrefix(curName, exclude) { log.Infof("Image %v matches exclude prefix %v, skipping\n", curName, exclude) continue } // then check include if include != "" && (!strings.HasPrefix(curName, include)) { log.Infof("Image %v doesn't match include prefix %v, skipping\n", curName, include) continue } newName := strings.Join([]string{registry, image.Name}, "/") if (image.NewTag == "") == (image.Digest == "") { log.Warnf("One and only one of NewTag or Digest can exist for image %s, skipping\n", image.Name) continue } if image.NewTag != "" { (*rt)[strings.Join([]string{newName, image.NewTag}, ":")] = strings.Join([]string{curName, image.NewTag}, ":") } if image.Digest != "" { (*rt)[strings.Join([]string{newName, image.Digest}, "@")] = strings.Join([]string{curName, image.Digest}, "@") } log.Infof("Replacing image name from %s to %s", image.Name, newName) //kustomization.Images[i].NewName = newName } // Process any kustomize packages we depend on. for _, r := range kustomization.Resources { if ext := strings.ToLower(filepath.Ext(r)); ext == ".yaml" || ext == ".yml" { continue } p := path.Join(absPath, r) if b, err := utils.IsRemoteFile(p); b || err != nil { if err != nil { log.Infof("Skipping path %v; there was an error determining if it was a local file; error: %v", p, err) continue } log.Infof("Skipping remote file %v", p) continue } if err := rt.processKustomizeDir(p, registry, include, exclude); err != nil { log.Errorf("Error occurred while processing %v; error %v", p, err) } } // Bases is deprecated but our manifests still use it. for _, r := range kustomization.Bases { p := path.Join(absPath, r) if b, err := utils.IsRemoteFile(p); b || err != nil { if err != nil { log.Infof("Skipping path %v; there was an error determining if it was a local file; error: %v", p, err) continue } log.Infof("Skipping remote file %v", p) continue } if err := rt.processKustomizeDir(p, registry, include, exclude); err != nil { log.Errorf("Error occurred while processing %v; error %v", p, err) } } return nil } func (rt *ReplicateTasks) fillTasks(directory string, registry string, buildContext string, include string, exclude string) error { return filepath.Walk(directory, func(path string, info os.FileInfo, err error) error { if info.IsDir() { absPath, err := filepath.Abs(path) if err != nil { return err } return rt.processKustomizeDir(absPath, registry, include, exclude) } return nil }) } func verifyCurrDir() error { infos, err := ioutil.ReadDir(".") if err != nil { return errors.WithStack(err) } foundKus := false for _, info := range infos { if info.IsDir() && info.Name() == KUSTOMIZE_FOLDER { foundKus = true break } } if !foundKus { return fmt.Errorf("kustomize folder not found, have you executed kfctl build yet?") } return nil } func UpdateKustomize(inputFile string) error { if err := verifyCurrDir(); err != nil { return err } buf, err := ioutil.ReadFile(inputFile) if err != nil { return errors.WithStack(err) } pipelineRun := pipeline.PipelineRun{} if err := yaml.Unmarshal(buf, &pipelineRun); err != nil { return err } imageMapping := make(map[string]string) for _, task := range pipelineRun.Spec.PipelineSpec.Tasks { oldImg := "" newImg := "" for _, param := range task.Params { if param.Name == INPUT_IMAGE { oldImg = param.Value.StringVal } if param.Name == OUTPUT_IMAGE { newImg = param.Value.StringVal } } imageMapping[oldImg] = newImg log.Infof("Updating image %v to %v", oldImg, newImg) } return filepath.Walk(KUSTOMIZE_FOLDER, func(path string, info os.FileInfo, err error) error { if info.IsDir() { 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) rewrite := false for i, image := range kustomization.Images { curName := image.Name if image.NewName != "" { curName = image.NewName } if (image.NewTag == "") == (image.Digest == "") { log.Warnf("One and only one of NewTag or Digest can exist for image %s, skipping\n", image.Name) continue } if image.NewTag != "" { curName = strings.Join([]string{curName, image.NewTag}, ":") } if image.Digest != "" { curName = strings.Join([]string{curName, image.Digest}, "@") } if newImg, ok := imageMapping[curName]; ok { // drop image tag before write back to kustomize idx := strings.Index(newImg, ":") if idx == -1 { idx = strings.Index(newImg, "@") } kustomization.Images[i].NewName = newImg[:idx] rewrite = true } } if rewrite { data, err := yaml.Marshal(kustomization) if err != nil { return err } writeErr := ioutil.WriteFile(kustomizationFilePath, data, 0644) if writeErr != nil { return errors.WithStack(writeErr) } } } return nil } return nil }) } ================================================ FILE: pkg/mirror/mirror_image_test.go ================================================ package mirror import ( "bytes" mirrorv1alpha1 "github.com/kubeflow/kfctl/v3/pkg/apis/apps/imagemirror/v1alpha1" "github.com/kubeflow/kfctl/v3/pkg/utils" log "github.com/sirupsen/logrus" "io/ioutil" "os" "path" "testing" ) const KUSTOMIZATION = "kustomize/kustomization.yaml" type testCase struct { Expected string Actual string } func init() { if err := os.Chdir("testdata"); err != nil { log.Errorf("Failed to change dir %v", err) } } func TestGenerateMirroringPipeline(t *testing.T) { spec := mirrorv1alpha1.ReplicationSpec{ Patterns: []mirrorv1alpha1.Pattern{ { Src: mirrorv1alpha1.SrcImages{ Exclude: "gcr.io", }, Dest: "gcr.io/kubeflow-dev", }, }, Context: "gs://kubeflow-examples/image-replicate/replicate-context.tar.gz", } wd, err := os.Getwd() if err != nil { t.Fatalf("Could not get working directory; error %v", err) } directory := path.Join(wd, "kustomize") if err := GenerateMirroringPipeline(directory, spec, "pipeline.yaml", true); err != nil { t.Error(err) } defer func(t *testing.T) { if err := os.Remove("pipeline.yaml"); err != nil { t.Error(err) } if err := os.Remove("cloudbuild.yaml"); err != nil { t.Error(err) } }(t) cases := []testCase{ { Expected: "expected-pipeline.yaml", Actual: "pipeline.yaml", }, { Expected: "expected-cloudbuild.yaml", Actual: "cloudbuild.yaml", }, } compFile(cases, t) } func TestUpdateKustomize(t *testing.T) { original, err := ioutil.ReadFile(KUSTOMIZATION) if err != nil { t.Error(err) } // Undo change after test run defer func(t *testing.T) { if err := ioutil.WriteFile(KUSTOMIZATION, original, 0644); err != nil { t.Error(err) } }(t) if err := UpdateKustomize("expected-pipeline.yaml"); err != nil { t.Error(err) } cases := []testCase{ { Expected: "expected-kustomization.yaml", Actual: KUSTOMIZATION, }, } compFile(cases, t) } func compFile(cases []testCase, t *testing.T) { for _, ca := range cases { expectedBytes, err := ioutil.ReadFile(ca.Expected) if err != nil { t.Error(err) } actualBytes, err := ioutil.ReadFile(ca.Actual) if err != nil { t.Error(err) } if !bytes.Equal(expectedBytes, actualBytes) { utils.PrintDiff(string(actualBytes), string(expectedBytes)) t.Errorf("Result not matching; got\n%v\nwant\n%v", string(actualBytes), string(expectedBytes)) } } } ================================================ FILE: pkg/mirror/testdata/base-pkg/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: docker.io/somerepo/image1 newName: docker.io/somerepo/image1 newTag: v0.16 ================================================ FILE: pkg/mirror/testdata/expected-cloudbuild.yaml ================================================ images: - gcr.io/kubeflow-dev/docker.io/istio/citadel:1.1.6 - gcr.io/kubeflow-dev/docker.io/istio/galley:1.1.6 - gcr.io/kubeflow-dev/docker.io/istio/kubectl:1.1.6 - gcr.io/kubeflow-dev/docker.io/istio/mixer:1.1.6 - gcr.io/kubeflow-dev/docker.io/istio/pilot:1.1.6 - gcr.io/kubeflow-dev/docker.io/istio/proxyv2:1.1.6 - gcr.io/kubeflow-dev/docker.io/istio/sidecar_injector:1.1.6 - gcr.io/kubeflow-dev/docker.io/jaegertracing/all-in-one:1.9 - gcr.io/kubeflow-dev/docker.io/kiali/kiali:v0.16 - gcr.io/kubeflow-dev/docker.io/prom/prometheus:v2.3.1 - gcr.io/kubeflow-dev/docker.io/somerepo/image1:v0.16 - gcr.io/kubeflow-dev/grafana/grafana:6.0.2 steps: - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/citadel:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/citadel:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/galley:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/galley:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/kubectl:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/kubectl:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/mixer:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/mixer:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/pilot:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/pilot:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/proxyv2:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/proxyv2:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/istio/sidecar_injector:1.1.6 - --build-arg=INPUT_IMAGE=docker.io/istio/sidecar_injector:1.1.6 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/jaegertracing/all-in-one:1.9 - --build-arg=INPUT_IMAGE=docker.io/jaegertracing/all-in-one:1.9 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/kiali/kiali:v0.16 - --build-arg=INPUT_IMAGE=docker.io/kiali/kiali:v0.16 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/prom/prometheus:v2.3.1 - --build-arg=INPUT_IMAGE=docker.io/prom/prometheus:v2.3.1 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/docker.io/somerepo/image1:v0.16 - --build-arg=INPUT_IMAGE=docker.io/somerepo/image1:v0.16 - . name: gcr.io/cloud-builders/docker waitFor: - '-' - args: - build - -t - gcr.io/kubeflow-dev/grafana/grafana:6.0.2 - --build-arg=INPUT_IMAGE=grafana/grafana:6.0.2 - . name: gcr.io/cloud-builders/docker waitFor: - '-' ================================================ FILE: pkg/mirror/testdata/expected-kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 images: - name: docker.io/istio/kubectl newName: gcr.io/kubeflow-dev/docker.io/istio/kubectl newTag: 1.1.6 - name: docker.io/istio/galley newName: gcr.io/kubeflow-dev/docker.io/istio/galley newTag: 1.1.6 - name: docker.io/istio/proxyv2 newName: gcr.io/kubeflow-dev/docker.io/istio/proxyv2 newTag: 1.1.6 - name: grafana/grafana newName: gcr.io/kubeflow-dev/grafana/grafana newTag: 6.0.2 - name: docker.io/kiali/kiali newName: gcr.io/kubeflow-dev/docker.io/kiali/kiali newTag: v0.16 - name: docker.io/istio/mixer newName: gcr.io/kubeflow-dev/docker.io/istio/mixer newTag: 1.1.6 - name: docker.io/istio/pilot newName: gcr.io/kubeflow-dev/docker.io/istio/pilot newTag: 1.1.6 - name: docker.io/prom/prometheus newName: gcr.io/kubeflow-dev/docker.io/prom/prometheus newTag: v2.3.1 - name: docker.io/istio/citadel newName: gcr.io/kubeflow-dev/docker.io/istio/citadel newTag: 1.1.6 - name: docker.io/istio/sidecar_injector newName: gcr.io/kubeflow-dev/docker.io/istio/sidecar_injector newTag: 1.1.6 - name: docker.io/jaegertracing/all-in-one newName: gcr.io/kubeflow-dev/docker.io/jaegertracing/all-in-one newTag: "1.9" kind: Kustomization namespace: kubeflow resources: - istio-noauth.yaml - ../base-pkg ================================================ FILE: pkg/mirror/testdata/expected-pipeline.yaml ================================================ apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: creationTimestamp: null name: replication-pipeline spec: params: - name: context value: gs://kubeflow-examples/image-replicate/replicate-context.tar.gz pipelineSpec: params: - name: context type: string tasks: - name: 0-docker-io-istio-citadel-1-1-6 params: - name: inputImage value: docker.io/istio/citadel:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/citadel:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 1-docker-io-istio-galley-1-1-6 params: - name: inputImage value: docker.io/istio/galley:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/galley:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 2-docker-io-istio-kubectl-1-1-6 params: - name: inputImage value: docker.io/istio/kubectl:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/kubectl:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 3-docker-io-istio-mixer-1-1-6 params: - name: inputImage value: docker.io/istio/mixer:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/mixer:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 4-docker-io-istio-pilot-1-1-6 params: - name: inputImage value: docker.io/istio/pilot:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/pilot:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 5-docker-io-istio-proxyv2-1-1-6 params: - name: inputImage value: docker.io/istio/proxyv2:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/proxyv2:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 6-docker-io-istio-sidecar-injector-1-1-6 params: - name: inputImage value: docker.io/istio/sidecar_injector:1.1.6 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/istio/sidecar_injector:1.1.6 - name: context value: $(params.context) taskRef: name: mirror-image - name: 7-docker-io-jaegertracing-all-in-one-1-9 params: - name: inputImage value: docker.io/jaegertracing/all-in-one:1.9 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/jaegertracing/all-in-one:1.9 - name: context value: $(params.context) taskRef: name: mirror-image - name: 8-docker-io-kiali-kiali-v0-16 params: - name: inputImage value: docker.io/kiali/kiali:v0.16 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/kiali/kiali:v0.16 - name: context value: $(params.context) taskRef: name: mirror-image - name: 9-docker-io-prom-prometheus-v2-3-1 params: - name: inputImage value: docker.io/prom/prometheus:v2.3.1 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/prom/prometheus:v2.3.1 - name: context value: $(params.context) taskRef: name: mirror-image - name: 10-docker-io-somerepo-image1-v0-16 params: - name: inputImage value: docker.io/somerepo/image1:v0.16 - name: outputImage value: gcr.io/kubeflow-dev/docker.io/somerepo/image1:v0.16 - name: context value: $(params.context) taskRef: name: mirror-image - name: 11-grafana-grafana-6-0-2 params: - name: inputImage value: grafana/grafana:6.0.2 - name: outputImage value: gcr.io/kubeflow-dev/grafana/grafana:6.0.2 - name: context value: $(params.context) taskRef: name: mirror-image status: {} ================================================ FILE: pkg/mirror/testdata/kustomize/kustomization.yaml ================================================ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - istio-noauth.yaml - ../base-pkg namespace: kubeflow images: - name: docker.io/istio/kubectl newName: docker.io/istio/kubectl newTag: 1.1.6 - name: docker.io/istio/galley newName: docker.io/istio/galley newTag: 1.1.6 - name: docker.io/istio/proxyv2 newName: docker.io/istio/proxyv2 newTag: 1.1.6 - name: grafana/grafana newName: grafana/grafana newTag: 6.0.2 - name: docker.io/kiali/kiali newName: docker.io/kiali/kiali newTag: v0.16 - name: docker.io/istio/mixer newName: docker.io/istio/mixer newTag: 1.1.6 - name: docker.io/istio/pilot newName: docker.io/istio/pilot newTag: 1.1.6 - name: docker.io/prom/prometheus newName: docker.io/prom/prometheus newTag: v2.3.1 - name: docker.io/istio/citadel newName: docker.io/istio/citadel newTag: 1.1.6 - name: docker.io/istio/sidecar_injector newName: docker.io/istio/sidecar_injector newTag: 1.1.6 - name: docker.io/jaegertracing/all-in-one newName: docker.io/jaegertracing/all-in-one newTag: '1.9' ================================================ FILE: pkg/utils/awsutil.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 utils import ( "fmt" "os/exec" "regexp" awssdk "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/sts" log "github.com/sirupsen/logrus" ) // CheckAwsStsCallerIdentity runs GetCallIdentity to make sure aws credentials is configured correctly func CheckAwsStsCallerIdentity(sess *session.Session) error { svc := sts.New(sess) input := &sts.GetCallerIdentityInput{} result, err := svc.GetCallerIdentity(input) if err != nil { log.Warnf("AWS Credentials seems not correct %v", err.Error()) return err } log.Infof("Caller ARN Info: %s", result) return nil } // CheckAwsAccountId runs GetCallIdentity to retrieve account information func CheckAwsAccountId(sess *session.Session) (string, error) { svc := sts.New(sess) input := &sts.GetCallerIdentityInput{} output, err := svc.GetCallerIdentity(input) if err != nil { log.Warnf("AWS Credentials seems not correct %v", err.Error()) return "", err } return awssdk.StringValue(output.Account), nil } // CheckCommandExist check if a command can be found in PATH. func CheckCommandExist(commandName string) error { _, err := exec.LookPath(commandName) if err != nil { return err } return nil } // GetEksctlVersion return eksctl version on user's environment func GetEksctlVersion() (string, error) { log.Infof("Running `eksctl version` ...") output, err := exec.Command("eksctl", "version").Output() if err != nil { log.Errorf("Failed to run `eksctl version` command %v", err) return "", err } // [ℹ] version.Info{BuiltAt:"", GitCommit:"", GitTag:"0.1.32"} r := regexp.MustCompile("[0-9]+.[0-9]+.[0-9]+") matchGroups := r.FindStringSubmatch(string(output)) if len(matchGroups) == 0 { return "", fmt.Errorf("can not find eksctl version from %v", string(output)) } version := matchGroups[0] log.Infof("eksctl version: %s", version) return version, nil } ================================================ FILE: pkg/utils/diff.go ================================================ package utils import ( "fmt" "strings" ) // PrintDiff pretty prints file differences. // // TODO(jlewi): We use this functionality across a lot of go packages; not just in kubeflow/kfctl but in other // repos like kubeflow/testing. We should think about moving it into its own go module so it can be easily reused. func PrintDiff(actual string, expected string) { sE, maxLen := convertToArray(expected) sA, _ := convertToArray(actual) format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4) limit := 0 if len(sE) < len(sA) { limit = len(sE) } else { limit = len(sA) } fmt.Printf(format, " ", "EXPECTED", "ACTUAL") fmt.Printf(format, " ", "--------", "------") for i := 0; i < limit; i++ { fmt.Printf(format, hint(sE[i], sA[i]), sE[i], sA[i]) } if len(sE) < len(sA) { for i := len(sE); i < len(sA); i++ { fmt.Printf(format, "X", "", sA[i]) } } else { for i := len(sA); i < len(sE); i++ { fmt.Printf(format, "X", sE[i], "") } } } func tabToSpace(input string) string { var result []string for _, i := range input { if i == 9 { result = append(result, " ") } else { result = append(result, string(i)) } } return strings.Join(result, "") } func convertToArray(x string) ([]string, int) { a := strings.Split(strings.TrimSuffix(x, "\n"), "\n") maxLen := 0 for i, v := range a { z := tabToSpace(v) if len(z) > maxLen { maxLen = len(z) } a[i] = z } return a, maxLen } func hint(a, b string) string { if a == b { return " " } return "X" } ================================================ FILE: pkg/utils/gcputils.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 utils import ( "cloud.google.com/go/container/apiv1" "encoding/base64" "fmt" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" "golang.org/x/net/context" "golang.org/x/oauth2" "google.golang.org/api/option" containerpb "google.golang.org/genproto/googleapis/container/v1" "k8s.io/client-go/rest" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "os/exec" ) // Use default token source and retrieve cluster information with given project/location/cluster // information. func GetClusterInfo(ctx context.Context, project string, loc string, cluster string, ts oauth2.TokenSource) (*containerpb.Cluster, error) { c, err := container.NewClusterManagerClient(ctx, option.WithTokenSource(ts)) if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: err.Error(), } } getClusterReq := &containerpb.GetClusterRequest{ ProjectId: project, Zone: loc, ClusterId: cluster, } if cl, err := c.GetCluster(ctx, getClusterReq); err == nil { return cl, nil } else { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: err.Error(), } } } // BuildConfigFromClusterInfo returns k8s config using gcloud Application Default Credentials // typically $HOME/.config/gcloud/application_default_credentials.json func BuildConfigFromClusterInfo(ctx context.Context, cluster *containerpb.Cluster, ts oauth2.TokenSource) (*rest.Config, error) { t, err := ts.Token() if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Token retrieval error: %v", err.Error()), } } caDec, _ := base64.StdEncoding.DecodeString(cluster.MasterAuth.ClusterCaCertificate) config := &rest.Config{ Host: "https://" + cluster.Endpoint, BearerToken: t.AccessToken, TLSClientConfig: rest.TLSClientConfig{ CAData: []byte(string(caDec)), }, } return config, nil } // Create a config that serves as kubeconfig. func CreateKubeconfig(ctx context.Context, project string, loc string, cluster string, namespace string, ts oauth2.TokenSource) (*clientcmdapi.Config, error) { clusterInfo, err := GetClusterInfo(ctx, project, loc, cluster, ts) if err != nil { return nil, err } config := clientcmdapi.NewConfig() config.Kind = "Config" t, err := ts.Token() if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Token retrieval error: %v", err.Error()), } } caDec, _ := base64.StdEncoding.DecodeString(clusterInfo.MasterAuth.ClusterCaCertificate) gcloudPath, err := exec.LookPath("gcloud") if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Not able to find gcloud: %v", err.Error()), } } config.Contexts[cluster] = &clientcmdapi.Context{ Cluster: cluster, AuthInfo: cluster, Namespace: namespace, } config.Clusters[cluster] = &clientcmdapi.Cluster{ Server: "https://" + clusterInfo.Endpoint, InsecureSkipTLSVerify: false, CertificateAuthorityData: []byte(string(caDec)), } config.AuthInfos[cluster] = &clientcmdapi.AuthInfo{ Token: t.AccessToken, AuthProvider: &clientcmdapi.AuthProviderConfig{ Name: "gcp", Config: map[string]string{ "cmd-path": gcloudPath, "cmd-args": "config config-helper --format=json", "token-key": "{.credential.access_token}", "expiry-key": "{.credential.token_expiry}", }, }, } config.CurrentContext = cluster return config, nil } ================================================ FILE: pkg/utils/iamutils.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 utils import ( "fmt" "github.com/deckarep/golang-set" "github.com/ghodss/yaml" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" log "github.com/sirupsen/logrus" "golang.org/x/net/context" "google.golang.org/api/cloudresourcemanager/v1" "google.golang.org/api/iam/v1" "io/ioutil" "net/http" ) func transformSliceToInterface(slice []string) []interface{} { ret := make([]interface{}, len(slice)) for i, m := range slice { ret[i] = m } return ret } func transformInterfaceToSlice(inter []interface{}) []string { ret := make([]string, len(inter)) for i, m := range inter { ret[i] = m.(string) } return ret } // Gets IAM plicy from GCP for the whole project. func GetIamPolicy(project string, gcpClient *http.Client) (*cloudresourcemanager.Policy, error) { ctx := context.Background() service, serviceErr := cloudresourcemanager.New(gcpClient) if serviceErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: serviceErr.Error(), } } req := &cloudresourcemanager.GetIamPolicyRequest{} if policy, err := service.Projects.GetIamPolicy(project, req).Context(ctx).Do(); err == nil { return policy, nil } else { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: err.Error(), } } } // Modify currentPolicy: Remove existing bindings associated with service accounts of current deployment func ClearIamPolicy(currentPolicy *cloudresourcemanager.Policy, deployName string, project string) { serviceAccounts := map[string]bool{ fmt.Sprintf("serviceAccount:%v-admin@%v.iam.gserviceaccount.com", deployName, project): true, fmt.Sprintf("serviceAccount:%v-user@%v.iam.gserviceaccount.com", deployName, project): true, fmt.Sprintf("serviceAccount:%v-vm@%v.iam.gserviceaccount.com", deployName, project): true, } var newBindings []*cloudresourcemanager.Binding for _, binding := range currentPolicy.Bindings { newBinding := cloudresourcemanager.Binding{ Role: binding.Role, } for _, member := range binding.Members { // Skip bindings for service accounts of current deployment. // We'll reset bindings for them in following steps. if _, ok := serviceAccounts[member]; !ok { newBinding.Members = append(newBinding.Members, member) } } newBindings = append(newBindings, &newBinding) } currentPolicy.Bindings = newBindings } // TODO: Move type definitions to appropriate place. type Members []string type Roles []string type Bindings struct { Members Members Roles Roles } type IamBindingsYAML struct { Bindings []Bindings } // Reads IAM bindings file in YAML format. func ReadIamBindingsYAML(filename string) (*cloudresourcemanager.Policy, error) { buf, bufErr := ioutil.ReadFile(filename) if bufErr != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: bufErr.Error(), } } iam := IamBindingsYAML{} if err := yaml.Unmarshal(buf, &iam); err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: err.Error(), } } entries := make(map[string]mapset.Set) for _, binding := range iam.Bindings { membersSet := mapset.NewSetFromSlice(transformSliceToInterface(binding.Members)) for _, role := range binding.Roles { if m, ok := entries[role]; ok { m.Union(membersSet) } else { entries[role] = membersSet } } } policy := &cloudresourcemanager.Policy{} for role, members := range entries { policy.Bindings = append(policy.Bindings, &cloudresourcemanager.Binding{ Role: role, Members: transformInterfaceToSlice(members.ToSlice()), }) } return policy, nil } // Either patch or remove role bindings from `src` policy. func RewriteIamPolicy(currentPolicy *cloudresourcemanager.Policy, adding *cloudresourcemanager.Policy) { policyMap := map[string]map[string]bool{} for _, binding := range currentPolicy.Bindings { policyMap[binding.Role] = make(map[string]bool) for _, member := range binding.Members { policyMap[binding.Role][member] = true } } for _, binding := range adding.Bindings { for _, member := range binding.Members { if _, ok := policyMap[binding.Role]; !ok { policyMap[binding.Role] = make(map[string]bool) } policyMap[binding.Role][member] = true } } var newBindings []*cloudresourcemanager.Binding for role, memberSet := range policyMap { binding := cloudresourcemanager.Binding{} binding.Role = role for member, exists := range memberSet { if exists { binding.Members = append(binding.Members, member) } } newBindings = append(newBindings, &binding) } currentPolicy.Bindings = newBindings } // "Override" project's IAM policy with given config. func SetIamPolicy(project string, policy *cloudresourcemanager.Policy, gcpClient *http.Client) error { ctx := context.Background() service, serviceErr := cloudresourcemanager.New(gcpClient) if serviceErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: serviceErr.Error(), } } req := &cloudresourcemanager.SetIamPolicyRequest{ Policy: policy, } _, err := service.Projects.SetIamPolicy(project, req).Context(ctx).Do() if err == nil { return nil } else { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: err.Error(), } } } // UpdateWorkloadIdentityBindingsPolicy updates the (service account) IAM policy with workload identity binding. func UpdateWorkloadIdentityBindingsPolicy(currentPolicy *iam.Policy, project string, namespace string, ksa string) error { newBinding := iam.Binding{} newBinding.Role = "roles/iam.workloadIdentityUser" newBinding.Members = []string{ fmt.Sprintf("serviceAccount:%v.svc.id.goog[%v/%v]", project, namespace, ksa), } currentPolicy.Bindings = append(currentPolicy.Bindings, &newBinding) log.Infof("New policy: %v", PrettyPrint(*currentPolicy)) return nil } // GetServingAccountIamPolicy gets IAM policy for a service account func GetServiceAccountIamPolicy(iamService *iam.Service, project string, gsa string) (*iam.Policy, error) { ctx := context.Background() saResource := fmt.Sprintf("projects/%v/serviceAccounts/%v", project, gsa) currentPolicy, err := iamService.Projects.ServiceAccounts.GetIamPolicy(saResource).Context(ctx).Do() if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Get IAM Policy error: %v", err), } } return currentPolicy, nil } // SetServingAccountIamPolicy sets IAM policy for a service account func SetServiceAccountIamPolicy(iamService *iam.Service, policy *iam.Policy, project string, gsa string) error { ctx := context.Background() saResource := fmt.Sprintf("projects/%v/serviceAccounts/%v", project, gsa) req := &iam.SetIamPolicyRequest{ Policy: policy, } _, setIamErr := iamService.Projects.ServiceAccounts.SetIamPolicy(saResource, req).Context(ctx).Do() if setIamErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Set IAM Policy error: %v", setIamErr), } } return nil } ================================================ FILE: pkg/utils/iamutils_test.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 utils import ( "fmt" "reflect" "testing" "google.golang.org/api/cloudresourcemanager/v1" "google.golang.org/api/iam/v1" ) func Test(t *testing.T) { type TestCase struct { // Arguments for GetUpdatedPolicy function. currentPolicy *cloudresourcemanager.Policy // service account policy pending change saPolicy *cloudresourcemanager.Policy // Expected output policy expectedPolicy *cloudresourcemanager.Policy } tests := []TestCase{ { currentPolicy: &cloudresourcemanager.Policy{ Bindings: []*cloudresourcemanager.Binding{ &cloudresourcemanager.Binding{ Role: "roles/source.admin", Members: []string{ "serviceAccount:kfctl-admin@project.iam.gserviceaccount.com", "serviceAccount:kfctl-vm@project.iam.gserviceaccount.com", "serviceAccount:should-stay@project.iam.gserviceaccount.com", }, }, &cloudresourcemanager.Binding{ Role: "roles/editor", Members: []string{ "user:user1@google.com", }, }, }, Etag: "ShouldKeep", }, expectedPolicy: &cloudresourcemanager.Policy{ Bindings: []*cloudresourcemanager.Binding{ // 'kfctl' service accounts binding should be deleted // 'should-stay' service accounts binding should not be deleted &cloudresourcemanager.Binding{ Role: "roles/source.admin", Members: []string{ "serviceAccount:should-stay@project.iam.gserviceaccount.com", }, }, // 'user1@google.com' binding should not be deleted &cloudresourcemanager.Binding{ Role: "roles/editor", Members: []string{ "user:user1@google.com", }, }, }, Etag: "ShouldKeep", }, }, } for _, test := range tests { ClearIamPolicy(test.currentPolicy, "kfctl", "project") if !reflect.DeepEqual(test.currentPolicy, test.expectedPolicy) { t.Errorf("Expect:\n%v; Output:\n%v", PolicyToString(test.expectedPolicy), PolicyToString(test.currentPolicy)) } } } func Test_UpdateWorkloadIdentity(t *testing.T) { type testCase struct { currentPolicy *iam.Policy project string namespace string ksa string expectedPolicy *iam.Policy } testCases := []testCase{ { currentPolicy: &iam.Policy{}, project: "gcp-project", namespace: "ns1", ksa: "ksa", expectedPolicy: &iam.Policy{ Bindings: []*iam.Binding{ { Role: "roles/iam.workloadIdentityUser", Members: []string{ "serviceAccount:gcp-project.svc.id.goog[ns1/ksa]", }, }, }, }, }, } for _, test := range testCases { UpdateWorkloadIdentityBindingsPolicy(test.currentPolicy, test.project, test.namespace, test.ksa) if !reflect.DeepEqual(test.currentPolicy, test.expectedPolicy) { t.Errorf("Expect:\n%v; Output:\n%v", IamPolicyToString(test.expectedPolicy), IamPolicyToString(test.currentPolicy)) } } } func PolicyToString(input *cloudresourcemanager.Policy) string { policy, err := input.MarshalJSON() if err != nil { return fmt.Sprintf("Unable to parse policy: %v", err) } return string(policy) } func IamPolicyToString(input *iam.Policy) string { policy, err := input.MarshalJSON() if err != nil { return fmt.Sprintf("Unable to parse policy: %v", err) } return string(policy) } ================================================ FILE: pkg/utils/k8sAuth.go ================================================ package utils import ( "encoding/base64" "cloud.google.com/go/container/apiv1" "golang.org/x/net/context" "golang.org/x/oauth2" "google.golang.org/api/option" containerpb "google.golang.org/genproto/googleapis/container/v1" "k8s.io/api/rbac/v1" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) func BuildClusterConfig(ctx context.Context, token string, project string, zone string, clusterID string) (*rest.Config, error) { ts := oauth2.StaticTokenSource(&oauth2.Token{ AccessToken: token, }) c, err := container.NewClusterManagerClient(ctx, option.WithTokenSource(ts)) if err != nil { return nil, err } req := &containerpb.GetClusterRequest{ ProjectId: project, Zone: zone, ClusterId: clusterID, } resp, err := c.GetCluster(ctx, req) if err != nil { return nil, err } caDec, _ := base64.StdEncoding.DecodeString(resp.MasterAuth.ClusterCaCertificate) return &rest.Config{ Host: "https://" + resp.Endpoint, BearerToken: token, TLSClientConfig: rest.TLSClientConfig{ CAData: []byte(string(caDec)), }, }, nil } // BuildClientCmdAPI takeks k8s config and access token, build and return clientcmdapi.Config entry func BuildClientCmdAPI(config *rest.Config, token string) *clientcmdapi.Config { return &clientcmdapi.Config{ Kind: "Config", APIVersion: "v1", Clusters: map[string]*clientcmdapi.Cluster{ "activeCluster": { CertificateAuthorityData: config.TLSClientConfig.CAData, Server: config.Host, }, }, Contexts: map[string]*clientcmdapi.Context{ "activeCluster": { Cluster: "activeCluster", AuthInfo: "activeCluster", }, }, CurrentContext: "activeCluster", AuthInfos: map[string]*clientcmdapi.AuthInfo{ "activeCluster": { Token: token, }, }, } } func CreateK8sRoleBing(config *rest.Config, roleBinding *v1.ClusterRoleBinding) error { kubeClient, err := clientset.NewForConfig(config) if err != nil { return err } _, err = kubeClient.RbacV1().ClusterRoleBindings().Create(roleBinding) if err != nil { return err } return nil } ================================================ FILE: pkg/utils/k8utils.go ================================================ /* Copyright (c) 2016-2017 Bitnami 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 utils import ( "bytes" "context" "encoding/json" "fmt" "github.com/cenkalti/backoff" "github.com/ghodss/yaml" goyaml "github.com/go-yaml/yaml" gogetter "github.com/hashicorp/go-getter" configtypes "github.com/kubeflow/kfctl/v3/config" kfapis "github.com/kubeflow/kfctl/v3/pkg/apis" kftypes "github.com/kubeflow/kfctl/v3/pkg/apis/apps" "github.com/pkg/errors" log "github.com/sirupsen/logrus" "io" "io/ioutil" "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" k8stypes "k8s.io/apimachinery/pkg/types" k8syaml "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/printers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" kubectlapply "k8s.io/kubernetes/pkg/kubectl/cmd/apply" kubectldelete "k8s.io/kubernetes/pkg/kubectl/cmd/delete" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "math/rand" netUrl "net/url" "os" "path" "regexp" "sigs.k8s.io/controller-runtime/pkg/client" "strings" "time" // Auth plugins _ "k8s.io/client-go/plugin/pkg/client/auth/azure" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" ) const ( YamlSeparator = "(?m)^---[ \t]*$" CertDir = "/opt/ca" controlPlaneLabel = "control-plane" katibMetricsCollectorLabel = "katib-metricscollector-injection" KfDefAnnotation = "kfctl.kubeflow.io" ForceDelete = "force-delete" SetAnnotation = "set-kubeflow-annotation" KfDefInstance = "kfdef-instance" InstallByOperator = "install-by-operator" ) func generateRandStr(length int) string { chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" b := make([]byte, length) for i := range b { b[i] = chars[rand.Intn(len(chars))] } return string(b) } func NewDefaultBackoff() *backoff.ExponentialBackOff { b := backoff.NewExponentialBackOff() b.InitialInterval = 3 * time.Second b.MaxInterval = 30 * time.Second b.MaxElapsedTime = 5 * time.Minute return b } func CreateResourceFromFile(config *rest.Config, filename string, elems ...configtypes.NameValue) error { elemsMap := make(map[string]configtypes.NameValue) for _, nv := range elems { elemsMap[nv.Name] = nv } c, err := client.New(config, client.Options{}) if err != nil { return errors.WithStack(err) } data, err := ioutil.ReadFile(filename) if err != nil { return errors.WithStack(err) } splitter := regexp.MustCompile(YamlSeparator) objectStrings := splitter.Split(string(data), -1) for _, str := range objectStrings { if strings.TrimSpace(str) == "" { continue } u := &unstructured.Unstructured{} if err := yaml.Unmarshal([]byte(str), u); err != nil { return errors.WithStack(err) } name := u.GetName() namespace := u.GetNamespace() if namespace == "" { if val, exists := elemsMap["namespace"]; exists { u.SetNamespace(val.Value) } else { u.SetNamespace("default") } } log.Infof("Creating %s", name) err := c.Get(context.TODO(), k8stypes.NamespacedName{Name: name, Namespace: namespace}, u.DeepCopy()) if err == nil { log.Info("Object already exists...") continue } if !k8serrors.IsNotFound(err) { return errors.WithStack(err) } err = c.Create(context.TODO(), u) if err != nil { return errors.WithStack(err) } } return nil } // Checks if the path configFile is remote (e.g. http://github...) func IsRemoteFile(configFile string) (bool, error) { if configFile == "" { return false, fmt.Errorf("config file must be a URI or a path") } url, err := netUrl.Parse(configFile) if err != nil { return false, &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("Error parsing file path: %v", err), } } if url.Scheme != "" { return true, nil } return false, nil } func GetObjectKindFromUri(configFile string) (string, error) { isRemoteFile, err := IsRemoteFile(configFile) if err != nil { return "", err } // We will read from appFile. appFile := configFile if isRemoteFile { // Download it to a tmp file, and set appFile. appDir, err := ioutil.TempDir("", "") if err != nil { return "", fmt.Errorf("Create a temporary directory to copy the file to.") } // Open config file appFile = path.Join(appDir, "tmp.yaml") log.Infof("Downloading %v to %v", configFile, appFile) err = gogetter.GetFile(appFile, configFile) if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not fetch specified config %s: %v", configFile, err), } } } // Read contents configFileBytes, err := ioutil.ReadFile(appFile) if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not read from config file %s: %v", configFile, err), } } BUFSIZE := 1024 buf := bytes.NewBufferString(string(configFileBytes)) job := &unstructured.Unstructured{} err = k8syaml.NewYAMLOrJSONDecoder(buf, BUFSIZE).Decode(job) if err != nil { return "", &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("could not decode specified config %s: %v", configFile, err), } } return job.GetKind(), nil } func DeleteResourceFromFile(config *rest.Config, filename string) error { c, err := client.New(config, client.Options{}) if err != nil { return errors.WithStack(err) } data, err := ioutil.ReadFile(filename) if err != nil { return errors.WithStack(err) } splitter := regexp.MustCompile(YamlSeparator) objectStrings := splitter.Split(string(data), -1) for _, str := range objectStrings { if strings.TrimSpace(str) == "" { continue } u := &unstructured.Unstructured{} if err := yaml.Unmarshal([]byte(str), u); err != nil { return errors.WithStack(err) } name := u.GetName() namespace := u.GetNamespace() log.Infof("Deleting %s", name) err := c.Get(context.TODO(), k8stypes.NamespacedName{Name: name, Namespace: namespace}, u.DeepCopy()) if k8serrors.IsNotFound(err) { log.Info("Object already deleted...") continue } if err != nil { return errors.WithStack(err) } err = c.Delete(context.TODO(), u) if err != nil { return errors.WithStack(err) } } return nil } type Apply struct { matchVersionKubeConfigFlags *cmdutil.MatchVersionFlags factory cmdutil.Factory clientset *kubernetes.Clientset options *kubectlapply.ApplyOptions tmpfile *os.File stdin *os.File } func NewApply(namespace string, restConfig *rest.Config) (*Apply, error) { configFlags := genericclioptions.NewConfigFlags(false) if restConfig != nil { certFile := path.Join(CertDir, generateRandStr(10)) if err := ioutil.WriteFile(certFile, restConfig.TLSClientConfig.CAData, 0644); err != nil { return nil, err } configFlags.CAFile = &certFile configFlags.BearerToken = &(restConfig.BearerToken) configFlags.APIServer = &(restConfig.Host) } apply := &Apply{ matchVersionKubeConfigFlags: cmdutil.NewMatchVersionFlags(configFlags), } apply.factory = cmdutil.NewFactory(apply.matchVersionKubeConfigFlags) clientset, err := apply.factory.KubernetesClientSet() if err != nil { return nil, &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not get clientset: %v", err), } } apply.clientset = clientset err = apply.namespace(namespace) if err != nil { return nil, err } // Change behaviour of error from exit to panic. cmdutil.BehaviorOnFatal(func(s string, i int) { panic(fmt.Errorf("Encountered error: %s. Exiting with code: %d.", s, i)) }) return apply, nil } func (a *Apply) IfNamespaceExist(name string) bool { _, nsMissingErr := a.clientset.CoreV1().Namespaces().Get(name, metav1.GetOptions{}) if nsMissingErr != nil { return false } return true } func (a *Apply) Apply(data []byte) error { a.tmpfile = a.tempFile(data) a.stdin = os.Stdin os.Stdin = a.tmpfile defer a.cleanup() ioStreams := genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr} a.options = kubectlapply.NewApplyOptions(ioStreams) a.options.DeleteFlags = a.deleteFlags("that contains the configuration to apply") initializeErr := a.init() if initializeErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("could not initialize : %v", initializeErr), } } var err error func() { defer func() { if temp := recover(); temp != nil { err = temp.(error) } }() err = a.run() }() if err != nil { return err } return nil } func (a *Apply) run() error { resourcesErr := a.options.Run() if resourcesErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("Apply.Run : %v", resourcesErr), } } return nil } func (a *Apply) cleanup() error { os.Stdin = a.stdin if a.tmpfile != nil { if err := a.tmpfile.Close(); err != nil { return err } return os.Remove(a.tmpfile.Name()) } return nil } func (a *Apply) init() error { var err error var o = a.options var f = a.factory // allow for a success message operation to be specified at print time o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) { o.PrintFlags.NamePrintFlags.Operation = operation if o.DryRun { err = o.PrintFlags.Complete("%s (dry run)") if err != nil { return nil, err } } if o.ServerDryRun { err = o.PrintFlags.Complete("%s (server dry run)") if err != nil { return nil, err } } return o.PrintFlags.ToPrinter() } o.DiscoveryClient, err = f.ToDiscoveryClient() if err != nil { return err } dynamicClient, err := f.DynamicClient() if err != nil { return err } o.DeleteOptions = o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) o.OpenAPIPatch = true o.OpenAPISchema, _ = f.OpenAPISchema() o.Validator, err = f.Validator(false) o.Builder = f.NewBuilder() o.Mapper, err = f.ToRESTMapper() if err != nil { return err } o.DynamicClient, err = f.DynamicClient() if err != nil { return err } o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace() if err != nil { return err } return nil } func (a *Apply) patchNamespaceWithLabel(namespace string, labelKey string, labelValue string) error { var labelPatchMap = map[string]metav1.ObjectMeta{ "metadata": metav1.ObjectMeta{ Labels: map[string]string{labelKey: labelValue}, }, } labelPatchJSON, err := json.Marshal(labelPatchMap) if err != nil { return err } log.Infof("Labeling Namespace: %v", namespace) _, err = a.clientset.CoreV1().Namespaces().Patch( namespace, "application/strategic-merge-patch+json", []byte(labelPatchJSON), ) if err != nil { return err } return nil } func (a *Apply) namespace(namespace string) error { log.Infof(string(kftypes.NAMESPACE)+": %v", namespace) namespaceInstance, nsMissingErr := a.clientset.CoreV1().Namespaces().Get( namespace, metav1.GetOptions{}, ) if nsMissingErr != nil { log.Infof("Creating namespace: %v", namespace) nsSpec := &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, Labels: map[string]string{ controlPlaneLabel: "kubeflow", katibMetricsCollectorLabel: "enabled", }, }, } _, nsErr := a.clientset.CoreV1().Namespaces().Create(nsSpec) if nsErr != nil { return &kfapis.KfError{ Code: int(kfapis.INVALID_ARGUMENT), Message: fmt.Sprintf("couldn't create %v %v Error: %v", string(kftypes.NAMESPACE), namespace, nsErr), } } } else { if _, ok := namespaceInstance.ObjectMeta.Labels[controlPlaneLabel]; !ok { patchErr := a.patchNamespaceWithLabel( namespace, controlPlaneLabel, "kubeflow", ) if patchErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't patch %v Error: %v", namespace, patchErr), } } } if _, ok := namespaceInstance.ObjectMeta.Labels[katibMetricsCollectorLabel]; !ok { patchErr := a.patchNamespaceWithLabel( namespace, katibMetricsCollectorLabel, "enabled", ) if patchErr != nil { return &kfapis.KfError{ Code: int(kfapis.INTERNAL_ERROR), Message: fmt.Sprintf("couldn't patch %v Error: %v", namespace, patchErr), } } } } return nil } func (a *Apply) tempFile(data []byte) *os.File { tmpfile, err := ioutil.TempFile("/tmp", "kout") if err != nil { log.Fatal(err) } if _, err := tmpfile.Write(data); err != nil { log.Fatal(err) } if _, err := tmpfile.Seek(0, 0); err != nil { log.Fatal(err) } return tmpfile } func (a *Apply) deleteFlags(usage string) *kubectldelete.DeleteFlags { cascade := true gracePeriod := -1 // setup command defaults all := false force := false ignoreNotFound := false now := false output := "" labelSelector := "" fieldSelector := "" timeout := time.Duration(0) wait := true filenames := []string{a.tmpfile.Name()} recursive := false return &kubectldelete.DeleteFlags{ FileNameFlags: &genericclioptions.FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive}, LabelSelector: &labelSelector, FieldSelector: &fieldSelector, Cascade: &cascade, GracePeriod: &gracePeriod, All: &all, Force: &force, IgnoreNotFound: &ignoreNotFound, Now: &now, Timeout: &timeout, Wait: &wait, Output: &output, } } // DeleteResource removes resource. Prior to that it checks whether the resource is created through the kubeflow operator. // always removes the resource if it is not created by the Kubeflow operator, otherwise checks the annotation to // be sure the resource is part of the deployment and then remove. func DeleteResource(resourceBytes []byte, kubeclient client.Client, timeout time.Duration, byOperator bool) error { // Convert to unstructured in order to access object metadata resourceMap := map[string]interface{}{} err := yaml.Unmarshal(resourceBytes, &resourceMap) if err != nil { return err } unstructuredObject := &unstructured.Unstructured{ Object: resourceMap, } name, namespace := unstructuredObject.GetName(), unstructuredObject.GetNamespace() log.Infof("Deleting Kind '%s' in APIVersion '%s' with name '%s' in namespace '%s'", unstructuredObject.GetKind(), unstructuredObject.GetAPIVersion(), name, namespace) // Check if resource exists err = kubeclient.Get(context.TODO(), k8stypes.NamespacedName{Name: name, Namespace: namespace}, unstructuredObject) if k8serrors.IsNotFound(err) { log.Warnf("Resource %s/%s not found", namespace, name) return nil } if _, ok := err.(*meta.NoKindMatchError); ok { log.Warnf("No matches for Kind %s in Group %s", unstructuredObject.GetKind(), unstructuredObject.GetAPIVersion()) return nil } if err != nil { return err } // if the func is called by the Kubeflow operator, validate it is installed through the operator if byOperator { anns := unstructuredObject.GetAnnotations() kfdefAnn := strings.Join([]string{KfDefAnnotation, KfDefInstance}, "/") _, found := anns[kfdefAnn] if !found { return nil } } // Resource exists, try to delete if unstructuredObject.GetDeletionTimestamp().IsZero() { err = kubeclient.Delete(context.TODO(), unstructuredObject) if err != nil { return errors.Wrapf(err, "Failed to delete resource %s/%s", namespace, name) } } // Delete succeeded, poll until the delete is completed interval := 5 * time.Second b := backoff.WithMaxRetries(backoff.NewConstantBackOff(interval), uint64(timeout/interval+1)) err = backoff.Retry(func() error { err := kubeclient.Get(context.TODO(), k8stypes.NamespacedName{Name: name, Namespace: namespace}, unstructuredObject.DeepCopy()) if !k8serrors.IsNotFound(err) { return errors.New("deleted resource is not cleaned up yet") } return nil }, b) if err != nil { return errors.New(fmt.Sprintf("Timed out waiting for resource %s/%s to be deleted. Error %v", namespace, name, err)) } return nil } func SplitYAML(resources []byte) ([][]byte, error) { dec := goyaml.NewDecoder(bytes.NewReader(resources)) var res [][]byte for { var value interface{} err := dec.Decode(&value) if err == io.EOF { break } if err != nil { return nil, err } valueBytes, err := goyaml.Marshal(value) if err != nil { return nil, err } res = append(res, valueBytes) } return res, nil } ================================================ FILE: pkg/utils/k8utils_test.go ================================================ package utils import ( "testing" ) func Test_IsRemoteFile(t *testing.T) { type testCase struct { filePath string isRemote bool } testCases := []testCase{ { filePath: "http://github.com", isRemote: true, }, { filePath: "../abc.txt", isRemote: false, }, { filePath: "/ab/c.txt", isRemote: false, }, { filePath: "abc.txt", isRemote: false, }, } for _, test := range testCases { isRemote, err := IsRemoteFile(test.filePath) if err != nil { t.Errorf("Error checking IsRemoteFile: %v", err) } if isRemote != test.isRemote { t.Errorf("check if path %v is remote; expect %v, got %v", test.filePath, test.isRemote, isRemote) } } } func TestSplitYAML(t *testing.T) { tests := []struct { name string yaml []byte expected [][]byte }{ { name: "simple", yaml: []byte("a: b\n---\nc: d"), expected: [][]byte{[]byte("a: b\n"), []byte("c: d\n")}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { resources, err := SplitYAML(test.yaml) if err != nil { t.Fatalf("Unexpected error: %v", err) } for idx := range resources { if string(resources[idx]) != string(test.expected[idx]) { t.Fatalf("Resource in place %v. Got '%s', Want '%s'.", idx, resources[idx], test.expected[idx]) } } }) } } ================================================ FILE: pkg/utils/kindsorter.go ================================================ package utils import ( "sigs.k8s.io/kustomize/v3/pkg/resource" "sort" ) // SortOrder is an ordering of Kinds. type SortOrder []string // InstallOrder is the order in which resources should be installed (by Kind). // Those occurring earlier in the list get installed before those occurring later in the list. var InstallOrder SortOrder = []string{ "Namespace", "ResourceQuota", "LimitRange", "PodSecurityPolicy", "Secret", "ConfigMap", "StorageClass", "PersistentVolume", "PersistentVolumeClaim", "ServiceAccount", "CustomResourceDefinition", "ClusterRole", "ClusterRoleBinding", "Role", "RoleBinding", "Service", "DaemonSet", "Pod", "ReplicationController", "ReplicaSet", "Deployment", "StatefulSet", "Job", "CronJob", "Ingress", "MutatingWebhookConfiguration", "ValidatingWebhookConfiguration", "APIService", } // UninstallOrder is the order in which resources should be uninstalled (by Kind). // Those occurring earlier in the list get uninstalled before those occurring later in the list. // Reason to move CustomResourceDefinition earlier is we want to leverage finalizer to delete created resources // like profile -> namespaces, etc var UninstallOrder SortOrder = []string{ "APIService", "ValidatingWebhookConfiguration", "MutatingWebhookConfiguration", "CustomResourceDefinition", "Ingress", "Service", "CronJob", "Job", "StatefulSet", "Deployment", "ReplicaSet", "ReplicationController", "Pod", "DaemonSet", "RoleBinding", "Role", "ClusterRoleBinding", "ClusterRole", "ServiceAccount", "PersistentVolumeClaim", "PersistentVolume", "StorageClass", "ConfigMap", "Secret", "PodSecurityPolicy", "LimitRange", "ResourceQuota", "Namespace", } // SortByKind does an in-place sort of resources by Kind. Results are sorted by 'ordering' func SortByKind(manifests []*resource.Resource, ordering SortOrder) []*resource.Resource { ks := newKindSorter(manifests, ordering) sort.Sort(ks) return ks.resources } type kindSorter struct { ordering map[string]int resources []*resource.Resource } func newKindSorter(r []*resource.Resource, s SortOrder) *kindSorter { o := make(map[string]int, len(s)) for v, k := range s { o[k] = v } return &kindSorter{ resources: r, ordering: o, } } func (k *kindSorter) Len() int { return len(k.resources) } func (k *kindSorter) Swap(i, j int) { k.resources[i], k.resources[j] = k.resources[j], k.resources[i] } func (k *kindSorter) Less(i, j int) bool { a := k.resources[i] b := k.resources[j] first, aok := k.ordering[a.GetKind()] second, bok := k.ordering[b.GetKind()] // if same kind (including unknown) sub sort alphanumeric if first == second { // if both are unknown and of different kind sort by kind alphabetically if !aok && !bok && a.GetKind() != b.GetKind() { return a.GetKind() < b.GetKind() } return a.GetKind() < b.GetKind() } // unknown kind is last if !aok { return false } if !bok { return true } // sort different kinds return first < second } ================================================ FILE: pkg/utils/logging.go ================================================ package utils import ( "encoding/json" "fmt" log "github.com/sirupsen/logrus" ) // PrettyPrint returns a pretty format output of any value. func PrettyPrint(value interface{}) string { if s, ok := value.(string); ok { return s } valueJson, err := json.MarshalIndent(value, "", " ") if err != nil { log.Errorf("Failed to marshal value; error %v", err) return fmt.Sprintf("%+v", value) } return string(valueJson) } ================================================ FILE: prow_config.yaml ================================================ ## This file configures the workflows to trigger in our Prow jobs. ## see kubeflow/testing/py/run_e2e_workflow.py python_paths: # Need to place kubeflow/testing in front of kubeflow/testing so that the package can # be correctly located. - kubeflow/testing/py - kubeflow/kfctl/py workflows: - py_func: kubeflow.kfctl.testing.ci.kfctl_e2e_workflow.create_workflow name: kfctl-e2e job_types: # Disable presubmit E2E test because large refactoring in manifests repo # Details can be found https://github.com/kubeflow/manifests/pull/1719 # - presubmit - periodic include_dirs: - config/* - cmd/* - pkg/* - py/* kwargs: build_and_apply: false config_path: https://raw.githubusercontent.com/kubeflow/manifests/master/kfdef/kfctl_istio_dex.yaml ================================================ FILE: py/kubeflow/__init__.py ================================================ __path__ = __import__('pkgutil').extend_path(__path__, __name__) ================================================ FILE: py/kubeflow/kfctl/__init__.py ================================================ ================================================ FILE: py/kubeflow/kfctl/testing/__init__.py ================================================ ================================================ FILE: py/kubeflow/kfctl/testing/ci/__init__.py ================================================ ================================================ FILE: py/kubeflow/kfctl/testing/ci/kfctl_e2e_workflow.py ================================================ """"Define the E2E workflow for kfctl. Rapid iteration. Here are some pointers for rapidly iterating on the workflow during development. 1. You can use the e2e_tool.py to directly launch the workflow on a K8s cluster. If you don't have CLI access to the kubeflow-ci cluster (most folks) then you would need to setup your own test cluster. 2. To avoid redeploying on successive runs set the following parameters --app_name=name for kfapp --delete_kubeflow=False Setting these parameters will cause the same KF deployment to be reused across invocations. As a result successive runs won't have to redeploy KF. Example running with E2E tool export PYTHONPATH=${PYTHONPATH}:${KFCTL_REPO}/py:${KUBEFLOW_TESTING_REPO}/py python -m kubeflow.testing.e2e_tool apply \ kubeflow.kfctl.testing.ci.kfctl_e2e_workflow.create_workflow --name=${USER}-kfctl-test-$(date +%Y%m%d-%H%M%S) \ --namespace=kubeflow-test-infra \ --test-endpoint=true \ --kf-app-name=${KFAPPNAME} \ --delete-kf=false --open-in-chrome=true We set kf-app-name and delete-kf to false to allow reusing the deployment across successive runs. To use code from a pull request set the prow envariables; e.g. export JOB_NAME="jlewi-test" export JOB_TYPE="presubmit" export BUILD_ID=1234 export PROW_JOB_ID=1234 export REPO_OWNER=kubeflow export REPO_NAME=kubeflow export PULL_NUMBER=4148 """ from kubeflow.testing import argo_build_util from kubeflow.testing import util import logging import os import uuid # The name of the NFS volume claim to use for test files. NFS_VOLUME_CLAIM = "nfs-external" # The name to use for the volume to use to contain test data DATA_VOLUME = "kubeflow-test-volume" # This is the main dag with the entrypoint E2E_DAG_NAME = "e2e" EXIT_DAG_NAME = "exit-handler" TEMPLATE_LABEL = "kfctl_e2e" DEFAULT_REPOS = [ "kubeflow/kfctl@HEAD", "kubeflow/kubeflow@HEAD", "kubeflow/testing@HEAD", "kubeflow/tf-operator@HEAD" ] class Builder(object): def __init__(self, name=None, namespace="kubeflow-test-infra", config_path=("https://raw.githubusercontent.com/kubeflow" "/manifests/master/kfdef/kfctl_istio_dex.v1.1.0.yaml"), bucket="aws-kubeflow-jenkins", use_basic_auth=False, build_and_apply=False, test_target_name=None, eks_cluster_version="1.17", extra_repos="", **kwargs): """Initialize a builder. Args: name: Name for the workflow. namespace: Namespace for the workflow. config_path: Path to the KFDef spec file. bucket: The bucket to upload artifacts to. If not set use default determined by prow_artifacts.py. test_endpoint: Whether to test the endpoint is ready. use_basic_auth: Whether to use basic_auth. test_target_name: (Optional) Name to use as the test target to group tests. delete_kf: (Optional) Don't run the step to delete Kubeflow. Set to true if you want to leave the deployment up for some reason. """ self.name = name self.namespace = namespace self.bucket = bucket if bucket else self.bucket self.config_path = config_path self.build_and_apply = build_and_apply #**************************************************************************** # Define directory locations #**************************************************************************** # mount_path is the directory where the volume to store the test data # should be mounted. self.mount_path = "/mnt/" + "test-data-volume" # test_dir is the root directory for all data for a particular test run. self.test_dir = self.mount_path + "/" + self.name # output_dir is the directory to sync to S3 to contain the output for this # job. self.output_dir = self.test_dir + "/output" self.artifactsDir = self.output_dir + "/artifacts" # We prefix the artifacts directory with junit because # that's what spyglass/prow requires. This ensures multiple # instances of a workflow triggered by the same prow job # don't end up clobbering each other self.artifacts_dir = self.output_dir + "/artifacts/junit_{0}".format(name) # source directory where all repos should be checked out self.src_root_dir = self.test_dir + "/src" # The directory containing the kubeflow/kfctl repo self.src_dir = self.src_root_dir + "/kubeflow/kfctl" self.kubeflow_dir = self.src_root_dir + "/kubeflow/kubeflow" # Directory in kubeflow/kfctl containing the pytest files. self.kfctl_pytest_dir = os.path.join(self.src_dir, "py/kubeflow/kfctl/testing/pytests") # Top level directories for python testing code in kfctl. self.kfctl_py = os.path.join(self.src_dir, "py") # Build a string of key value pairs that can be passed to various test # steps to allow them to do substitution into different values. values = { "srcrootdir": self.src_root_dir, } value_pairs = ["{0}={1}".format(k,v) for k,v in values.items()] self.values_str = ",".join(value_pairs) # The directory within the kubeflow_testing submodule containing # py scripts to use. self.kubeflow_testing_py = self.src_root_dir + "/kubeflow/testing/py" self.tf_operator_root = os.path.join(self.src_root_dir, "kubeflow/tf-operator") self.tf_operator_py = os.path.join(self.tf_operator_root, "py") self.go_path = self.test_dir # Name for the Kubeflow app. # This needs to be unique for each test run because it is # used to name AWS resources # TODO(jlewi): Might be good to include pull number or build id in the name # Not sure if being non-deterministic is a good idea. # A better approach might be to hash the workflow name to generate a unique # name dependent on the workflow name. We know there will be one workflow # per cluster. self.uuid = uuid.uuid4().hex[0:8] # Name for ephemeral EKS cluster self.cluster_name = "eks-cluster-" + self.uuid # Version for ephemeral EKS clsuter self.eks_cluster_version = eks_cluster_version # Config name is the name of the config file. This is used to give junit # files unique names. self.config_name = os.path.splitext(os.path.basename(config_path))[0] # The class name to label junit files. # We want to be able to group related tests in test grid. # Test grid allows grouping by target which corresponds to the classname # attribute in junit files. # So we set an environment variable to the desired class name. # The pytest modules can then look at this environment variable to # explicitly override the classname. # The classname should be unique for each run so it should take into # account the different parameters if test_target_name: self.test_target_name = test_target_name else: self.test_target_name = self.config_name # app_name is the name of the Kubeflow deployment. # This needs to be unique per run since we name AWS resources with it. self.app_name = self.cluster_name # AWS service accounts can only be max 100 characters. Service account names # are generated by taking the app_name and appending suffixes like "user" # and "admin" if len(self.app_name) > 99: raise ValueError(("app_name {0} is longer than 100 characters; this will" "likely exceed AWS naming restrictions.").format( self.app_name)) # Directory for the KF app. self.app_dir = os.path.join(self.test_dir, self.app_name) self.use_basic_auth = use_basic_auth # The name space we create KF artifacts in; e.g. TFJob and notebooks. # TODO(jlewi): These should no longer be running the system namespace but # should move into the namespace associated with the default profile. self.steps_namespace = "kubeflow" self.kfctl_path = os.path.join(self.src_dir, "bin/kfctl") # Fetch the main repo from Prow environment. self.main_repo = argo_build_util.get_repo_from_prow_env() # extra_repos is a list of comma separated repo names with commits, # in the format /@, # e.g. "kubeflow/tf-operator@12345,kubeflow/manifests@23456". # This will be used to override the default repo branches. self.extra_repos = [] if extra_repos: self.extra_repos = extra_repos.split(',') def _build_workflow(self): """Create the scaffolding for the Argo workflow""" workflow = { "apiVersion": "argoproj.io/v1alpha1", "kind": "Workflow", "metadata": { "name": self.name, "namespace": self.namespace, "labels": argo_build_util.add_dicts([{ "workflow": self.name, "workflow_template": TEMPLATE_LABEL, }, argo_build_util.get_prow_labels()]), }, "spec": { "entrypoint": E2E_DAG_NAME, # Have argo garbage collect old workflows otherwise we overload the API # server. "ttlSecondsAfterFinished": 7 * 24 * 60 * 60, "volumes": [ { "name": DATA_VOLUME, "persistentVolumeClaim": { "claimName": NFS_VOLUME_CLAIM, }, }, ], "onExit": EXIT_DAG_NAME, "templates": [ { "dag": { "tasks": [], }, "name": E2E_DAG_NAME, }, { "dag": { "tasks": [], }, "name": EXIT_DAG_NAME, } ], }, # spec } # workflow return workflow def _build_task_template(self): """Return a template for all the tasks""" task_template = {'activeDeadlineSeconds': 3000, 'container': {'command': [], 'env': [ { "name": "AWS_ACCESS_KEY_ID", "valueFrom": { "secretKeyRef": { "name": "aws-credentials", "key": "AWS_ACCESS_KEY_ID", }, }, }, { "name": "AWS_SECRET_ACCESS_KEY", "valueFrom": { "secretKeyRef": { "name": "aws-credentials", "key": "AWS_SECRET_ACCESS_KEY", }, }, }, { "name": "AWS_DEFAULT_REGION", "value": "us-west-2", }, { "name": "GITHUB_TOKEN", "valueFrom": { "secretKeyRef": { "name": "github-token", "key": "github_token", }, }, }, {"name": "TEST_TARGET_NAME", "value": self.test_target_name}, ], 'image': 'public.ecr.aws/j1r0q0g6/kubeflow-testing:latest', 'imagePullPolicy': 'Always', 'name': '', 'resources': {'limits': {'cpu': '4', 'memory': '4Gi'}, 'requests': {'cpu': '1', 'memory': '1536Mi'}}, 'volumeMounts': [{'mountPath': '/mnt/test-data-volume', 'name': 'kubeflow-test-volume'}]}, 'metadata': {'labels': { 'workflow_template': TEMPLATE_LABEL}}, 'outputs': {}} # Define common environment variables to be added to all steps common_env = [ {'name': 'PYTHONPATH', 'value': ":".join([self.kubeflow_testing_py, self.kfctl_py, self.tf_operator_py])}, {'name': 'GOPATH', 'value': self.go_path}, ] task_template["container"]["env"].extend(common_env) task_template = argo_build_util.add_prow_env(task_template) return task_template def _build_step(self, name, workflow, dag_name, task_template, command, dependences): """Syntactic sugar to add a step to the workflow""" step = argo_build_util.deep_copy(task_template) step["name"] = name step["container"]["command"] = command return argo_build_util.add_task_to_dag(workflow, dag_name, step, dependences) def _build_tests_dag(self, dependences): """Build the dag for the set of tests to run against a KF deployment.""" task_template = self._build_task_template() #************************************************************************* # Test pytorch job step_name = "pytorch-job-deploy" command = ["pytest", "pytorch_job_deploy.py", "-s", "--timeout=600", "--junitxml=" + self.artifacts_dir + "/junit_pytorch-test.xml", "--kfctl_repo_path=" + self.src_dir, "--namespace=" + self.steps_namespace, "--cluster_name=" + self.cluster_name, ] pytorch_test = self._build_step(step_name, self.workflow, E2E_DAG_NAME, task_template, command, dependences) pytorch_test["container"]["workingDir"] = self.kfctl_pytest_dir # *************************************************************************** # kfam test step_name = "kfam-test" command = ["pytest", "kfam_test.py", "-s", "--timeout=600", "--junitxml=" + self.artifacts_dir + "/junit_kfam-test.xml", "--cluster_name=" + self.cluster_name, ] kfam_test = self._build_step(step_name, self.workflow, E2E_DAG_NAME, task_template, command, dependences) kfam_test["container"]["workingDir"] = self.kfctl_pytest_dir test_dependences = [kfam_test["name"], pytorch_test["name"]] return test_dependences def _build_exit_dag(self): """Build the exit handler dag""" task_template = self._build_task_template() step_name = "cluster-delete" command = [ "pytest", "kfctl_delete_cluster_test.py", "-s", "--log-cli-level=info", "--timeout=1000", "--junitxml=" + self.artifacts_dir + "/junit_kfctl-go-delete-test.xml", "--cluster_deletion_script=" + "/usr/local/bin/delete-eks-cluster.sh", "--cluster_name=" + self.cluster_name, ] cluster_delete = self._build_step(step_name, self.workflow, EXIT_DAG_NAME, task_template, command, []) cluster_delete["container"]["workingDir"] = self.kfctl_pytest_dir step_name = "copy-artifacts" command = ["python", "-m", "kubeflow.testing.cloudprovider.aws.prow_artifacts", "--artifacts_dir=" + self.output_dir, "copy_artifacts_to_s3", "--bucket=" + self.bucket, ] dependences = [cluster_delete["name"]] copy_artifacts = self._build_step(step_name, self.workflow, EXIT_DAG_NAME, task_template, command, dependences) step_name = "test-dir-delete" command = ["python", "-m", "kubeflow.kfctl.testing.util.run_with_retry", "--retries=5", "--", "rm", "-rf", self.test_dir,] dependences = [copy_artifacts["name"]] copy_artifacts = self._build_step(step_name, self.workflow, EXIT_DAG_NAME, task_template, command, dependences) # We don't want to run from the directory we are trying to delete. copy_artifacts["container"]["workingDir"] = "/" def build(self): self.workflow = self._build_workflow() task_template = self._build_task_template() py3_template = argo_build_util.deep_copy(task_template) py3_template["container"]["image"] = "public.ecr.aws/j1r0q0g6/kubeflow-testing:latest" default_namespace = "kubeflow" #************************************************************************** # Checkout # create the checkout step checkout = argo_build_util.deep_copy(task_template) # Construct the list of repos to checkout list_of_repos = DEFAULT_REPOS list_of_repos.append(self.main_repo) list_of_repos.extend(self.extra_repos) repos = util.combine_repos(list_of_repos) repos_str = ','.join(['%s@%s' % (key, value) for (key, value) in repos.items()]) # If we are using a specific branch (e.g. periodic tests for release branch) # then we need to use depth = all; otherwise checkout out the branch # will fail. Otherwise we checkout with depth=30. We want more than # depth=1 because the depth will determine our ability to find the common # ancestor which affects our ability to determine which files have changed depth = 30 if os.getenv("BRANCH_NAME"): logging.info("BRANCH_NAME=%s; setting detph=all", os.getenv("BRANCH_NAME")) depth = "all" checkout["name"] = "checkout" checkout["container"]["command"] = ["/usr/local/bin/checkout_repos.sh", "--repos=" + repos_str, "--depth={0}".format(depth), "--src_dir=" + self.src_root_dir] argo_build_util.add_task_to_dag(self.workflow, E2E_DAG_NAME, checkout, []) # Change the working directory for all subsequent steps task_template["container"]["workingDir"] = os.path.join( self.kfctl_pytest_dir) py3_template["container"]["workingDir"] = os.path.join(self.kfctl_pytest_dir) #*************************************************************************** # create_pr_symlink #*************************************************************************** # TODO(jlewi): run_e2e_workflow.py should probably create the PR symlink step_name = "create-pr-symlink" command = ["python", "-m", "kubeflow.testing.cloudprovider.aws.prow_artifacts", "--artifacts_dir=" + self.output_dir, "create_pr_symlink_s3", "--bucket=" + self.bucket] dependences = [checkout["name"]] symlink = self._build_step(step_name, self.workflow, E2E_DAG_NAME, task_template, command, dependences) #************************************************************************** # Run build_kfctl step_name = "kfctl-build-deploy" command = [ "pytest", "kfctl_go_test.py", # I think -s mean stdout/stderr will print out to aid in debugging. # Failures still appear to be captured and stored in the junit file. "-s", "--config_path=" + self.config_path, "--values=" + self.values_str, # Increase the log level so that info level log statements show up. # TODO(https://github.com/kubeflow/testing/issues/372): If we # set a unique artifacts dir for each workflow with the proper # prefix that should work. "--log-cli-level=info", "--junitxml=" + self.artifacts_dir + "/junit_kfctl-build-test" + self.config_name + ".xml", # TODO(jlewi) Test suite name needs to be unique based on parameters. "-o", "junit_suite_name=test_kfctl_go_deploy_" + self.config_name, "--kfctl_repo_path=" + self.src_dir, ] dependences = [checkout["name"]] build_kfctl = self._build_step(step_name, self.workflow, E2E_DAG_NAME, py3_template, command, dependences) #************************************************************************** # Create EKS cluster for E2E test step_name = "kfctl-create-cluster" command = [ "pytest", "kfctl_create_cluster_test.py", # I think -s mean stdout/stderr will print out to aid in debugging. # Failures still appear to be captured and stored in the junit file. "-s", "--cluster_name=" + self.cluster_name, "--eks_cluster_version=" + str(self.eks_cluster_version), # Embedded Script in the ECR Image "--cluster_creation_script=" + "/usr/local/bin/create-eks-cluster.sh", "--values=" + self.values_str, # Increase the log level so that info level log statements show up. # TODO(https://github.com/kubeflow/testing/issues/372): If we # set a unique artifacts dir for each workflow with the proper # prefix that should work. "--log-cli-level=info", "--junitxml=" + self.artifacts_dir + "/junit_kfctl-build-test" + self.config_name + ".xml", # TODO(jlewi) Test suite name needs to be unique based on parameters. "-o", "junit_suite_name=test_kfctl_go_deploy_" + self.config_name, ] dependences = [checkout["name"]] create_cluster = self._build_step(step_name, self.workflow, E2E_DAG_NAME, py3_template, command, dependences) #************************************************************************** # Deploy Kubeflow step_name = "kfctl-deploy-kubeflow" command = [ "pytest", "kfctl_deploy_kubeflow_test.py", # I think -s mean stdout/stderr will print out to aid in debugging. # Failures still appear to be captured and stored in the junit file. "-s", "--cluster_name=" + self.cluster_name, # Embedded Script in the ECR Image "--cluster_creation_script=" + "/usr/local/bin/create-eks-cluster.sh", "--config_path=" + self.config_path, "--values=" + self.values_str, "--build_and_apply=" + str(self.build_and_apply), # Increase the log level so that info level log statements show up. # TODO(https://github.com/kubeflow/testing/issues/372): If we # set a unique artifacts dir for each workflow with the proper # prefix that should work. "--log-cli-level=info", "--junitxml=" + self.artifacts_dir + "/junit_kfctl-build-test" + self.config_name + ".xml", # TODO(jlewi) Test suite name needs to be unique based on parameters. "-o", "junit_suite_name=test_kfctl_go_deploy_" + self.config_name, "--app_path=" + self.app_dir, "--kfctl_repo_path=" + self.src_dir, ] dependences = [build_kfctl["name"], create_cluster["name"], symlink["name"]] deploy_kf = self._build_step(step_name, self.workflow, E2E_DAG_NAME, py3_template, command, dependences) #************************************************************************** # Wait for Kubeflow to be ready step_name = "kubeflow-is-ready" command = [ "pytest", "kf_is_ready_test.py", # I think -s mean stdout/stderr will print out to aid in debugging. # Failures still appear to be captured and stored in the junit file. "-s", # TODO(jlewi): We should update kf_is_ready_test to take the config # path and then based on the KfDef spec kf_is_ready_test should # figure out what to do. "--use_basic_auth={0}".format(self.use_basic_auth), # Increase the log level so that info level log statements show up. "--log-cli-level=info", "--junitxml=" + os.path.join(self.artifacts_dir, "junit_kfctl-is-ready-test-" + self.config_name + ".xml"), # Test suite name needs to be unique based on parameters "-o", "junit_suite_name=test_kf_is_ready_" + self.config_name, "--app_path=" + self.app_dir, "--cluster_name=" + self.cluster_name, "--namespace=" + default_namespace, ] dependences = [deploy_kf["name"]] kf_is_ready = self._build_step(step_name, self.workflow, E2E_DAG_NAME, task_template, command, dependences) #************************************************************************** # Run functional tests dependences = [kf_is_ready["name"]] dependences = self._build_tests_dag(dependences=dependences) #*********************************************************************** # Delete Kubeflow # Putting Delete Kubeflow here is deletion functionality should be tested out of exit DAG step_name = "kfctl-delete-wrong-host" command = [ "pytest", "kfctl_delete_wrong_cluster.py", "-s", "--log-cli-level=info", "--timeout=1000", "--junitxml=" + self.artifacts_dir + "/junit_kfctl-go-delete-wrong-cluster-test.xml", "--app_path=" + self.app_dir, "--kfctl_path=" + self.kfctl_path, "--cluster_name=" + self.cluster_name, ] kfctl_delete_wrong_cluster = self._build_step(step_name, self.workflow, E2E_DAG_NAME, task_template, command, dependences) kfctl_delete_wrong_cluster["container"]["workingDir"] = self.kfctl_pytest_dir step_name = "kfctl-delete" command = [ "pytest", "kfctl_delete_test.py", "-s", "--log-cli-level=info", "--timeout=1000", "--junitxml=" + self.artifacts_dir + "/junit_kfctl-go-delete-test.xml", "--app_path=" + self.app_dir, "--kfctl_path=" + self.kfctl_path, "--cluster_name=" + self.cluster_name, ] kfctl_delete = self._build_step(step_name, self.workflow, E2E_DAG_NAME, task_template, command, ["kfctl-delete-wrong-host"]) kfctl_delete["container"]["workingDir"] = self.kfctl_pytest_dir #*************************************************************************** # Exit DAG #*************************************************************************** self._build_exit_dag() # Set the labels on all templates self.workflow = argo_build_util.set_task_template_labels(self.workflow) return self.workflow # TODO(jlewi): This is an unnecessary layer of indirection around the builder # We should allow py_func in prow_config to point to the builder and # let e2e_tool take care of this. def create_workflow(**kwargs): # pylint: disable=too-many-statements """Create workflow returns an Argo workflow to test kfctl upgrades. Args: name: Name to give to the workflow. This can also be used to name things associated with the workflow. """ builder = Builder(**kwargs) return builder.build() ================================================ FILE: py/kubeflow/kfctl/testing/ci/kfctl_go_build_test.py ================================================ import logging import os import pytest from kubeflow.testing import util import kfctl_go_test_utils as kfctl_util def test_build_kfctl_go(record_xml_attribute): """Test building of kfctl go. """ util.set_pytest_junit(record_xml_attribute, "test_build_kfctl_go") # Need to activate account for scopes. if os.getenv("GOOGLE_APPLICATION_CREDENTIALS"): util.run([ "gcloud", "auth", "activate-service-account", "--key-file=" + os.environ["GOOGLE_APPLICATION_CREDENTIALS"] ]) kfctl_path = kfctl_util.build_kfctl_go() logging.info("kfctl go binary path %s", kfctl_path) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/ci/kfctl_go_deploy_test.py ================================================ import logging import os import pytest import kfctl_go_test_utils as kfctl_util from kubeflow.testing import util def test_deploy_kfctl_go(record_xml_attribute, app_path, project, use_basic_auth, use_istio, config_path, kfctl_path): """Test deploying Kubeflow. Args: app_path: The path to the Kubeflow app. project: The GCP project to use. """ util.set_pytest_junit(record_xml_attribute, "test_deploy_kfctl_go") # Need to activate account for scopes. if os.getenv("GOOGLE_APPLICATION_CREDENTIALS"): util.run([ "gcloud", "auth", "activate-service-account", "--key-file=" + os.environ["GOOGLE_APPLICATION_CREDENTIALS"] ]) kfctl_util.kfctl_deploy_kubeflow(app_path, project, use_basic_auth, use_istio, config_path, kfctl_path) kfctl_util.verify_kubeconfig(app_path) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/ci/kfctl_upgrade_e2e_workflow.py ================================================ """"Define the E2E workflow for kfctl. Rapid iteration. Here are some pointers for rapidly iterating on the workflow during development. 1. You can use the e2e_tool.py to directly launch the workflow on a K8s cluster. If you don't have CLI access to the kubeflow-ci cluster (most folks) then you would need to setup your own test cluster. 2. To avoid redeploying on successive runs set the following parameters --app_name=name for kfapp --delete_kubeflow=False Setting these parameters will cause the same KF deployment to be reused across invocations. As a result successive runs won't have to redeploy KF. Example running with E2E tool export PYTHONPATH=${PYTHONPATH}:${KUBEFLOW_REPO}/py:${KUBEFLOW_TESTING_REPO}/py python -m kubeflow.testing.e2e_tool apply \ kubeflow.kubeflow.ci.kfctl_e2e_workflow.create_workflow --name=${USER}-kfctl-test-$(date +%Y%m%d-%H%M%S) \ --namespace=kubeflow-test-infra \ --test-endpoint=true \ --kf-app-name=${KFAPPNAME} \ --delete-kf=false --open-in-chrome=true We set kf-app-name and delete-kf to false to allow reusing the deployment across successive runs. To use code from a pull request set the prow envariables; e.g. export JOB_NAME="jlewi-test" export JOB_TYPE="presubmit" export BUILD_ID=1234 export PROW_JOB_ID=1234 export REPO_OWNER=kubeflow export REPO_NAME=kubeflow export PULL_NUMBER=4148 """ import datetime from kubeflow.kfctl.testing.ci import kfctl_e2e_workflow from kubeflow.testing import argo_build_util import logging import os import uuid UPGRADE_DAG_NAME = "upgrade-dag" READY_AFTER_UPGRADE = "ready-after-upgrade" TEMPLATE_LABEL = "kfctl_upgrade_e2e" class Builder(kfctl_e2e_workflow.Builder): def __init__(self, upgrade_spec_path=("https://raw.githubusercontent.com/kubeflow" "/manifests/v0.7-branch/kfdef/kfctl_upgrade_gcp_iap_0.7.1.yaml"), **kwargs): """Initialize a builder.""" super(Builder, self).__init__(**kwargs) self.upgrade_spec_path = upgrade_spec_path def _build_upgrade_dag(self): """Build the dag of steps to run upgrade.""" # Add the dag to the workflow. self.workflow["spec"]["templates"].append({ "dag": { "tasks": [], }, "name": UPGRADE_DAG_NAME, }) task_template = self._build_task_template() # Change the workfing directory for all subsequent steps task_template["container"]["workingDir"] = os.path.join(self.kfctl_pytest_dir) #*************************************************************************** # Run kfctl upgrade step_name = "upgrade" command = [ "pytest", "kfctl_upgrade_test.py", "-s", "--log-cli-level=info", "--junitxml=" + os.path.join(self.artifacts_dir, "junit_kfctl-upgrade-test-" + self.config_name + ".xml"), # Test suite name needs to be unique based on parameters "-o", "junit_suite_name=test_kfctl_upgrade_" + self.config_name, "--app_path=" + self.app_dir, "--kfctl_path=" + self.kfctl_path, "--upgrade_spec_path=" + self.upgrade_spec_path, ] dependences = [] upgrade_step = self._build_step(step_name, self.workflow, UPGRADE_DAG_NAME, task_template, command, dependences) def build(self): self.workflow = super(Builder, self).build() task_template = self._build_task_template() # Change the workflow_template labels self.workflow["metadata"]["labels"]["workflow_template"] = TEMPLATE_LABEL # Add the dag to upgrade Kubeflow to the workflow self._build_upgrade_dag() # Add a task to the E2E dag to run the dag to upgrade Kubeflow. dependencies = [self._run_tests_step_name] if self._test_endpoint_step_name: dependencies.append(self._test_endpoint_step_name) step_name = UPGRADE_DAG_NAME template_name = UPGRADE_DAG_NAME argo_build_util.add_task_only_to_dag(self.workflow, kfctl_e2e_workflow.E2E_DAG_NAME, step_name, template_name, dependencies) # Wait for Kubeflow to be ready after upgrading step_name = READY_AFTER_UPGRADE template_name = "kubeflow-is-ready" command = [ "pytest", "kf_is_ready_test.py", "-s", "--log-cli-level=info", "--junitxml=" + os.path.join(self.artifacts_dir, "junit_ready-after-upgrade-test-" + self.config_name + ".xml"), "-o", "junit_suite_name=test_ready_after_upgrade_" + self.config_name, "--app_path=" + self.app_dir, ] dependencies = [UPGRADE_DAG_NAME] argo_build_util.add_task_only_to_dag(self.workflow, kfctl_e2e_workflow.E2E_DAG_NAME, step_name, template_name, dependencies) #**************************************************************************** # Add tests DAG #**************************************************************************** # After running upgrade we want to rerun the DAG(s) that validate the deployment is healthy step_name = "test-after-upgrade" template_name = kfctl_e2e_workflow.TESTS_DAG_NAME dependencies = [READY_AFTER_UPGRADE] argo_build_util.add_task_only_to_dag(self.workflow, kfctl_e2e_workflow.E2E_DAG_NAME, step_name, template_name, dependencies) # Test the endpoint after upgrade if self.test_endpoint: dependencies = [UPGRADE_DAG_NAME] step_name = "upgraded-endpoint-ready" argo_build_util.add_task_only_to_dag(self.workflow, kfctl_e2e_workflow.E2E_DAG_NAME, step_name, self._test_endpoint_template_name, dependencies) # Reset the labels on all templates to pick up the updated workflow template label self.workflow = argo_build_util.set_task_template_labels(self.workflow) return self.workflow # TODO(jlewi): This is an unnecessary layer of indirection around the builder # We should allow py_func in prow_config to point to the builder and # let e2e_tool take care of this. def create_workflow(**kwargs): # pylint: disable=too-many-statements """Create workflow returns an Argo workflow to test kfctl upgrades. Args: name: Name to give to the workflow. This can also be used to name things associated with the workflow. """ builder = Builder(**kwargs) return builder.build() ================================================ FILE: py/kubeflow/kfctl/testing/ci/update_jupyter_web_app.py ================================================ """Script to build and update the Jupyter WebApp image. Requires python3 hub CLI depends on an OAuth token with repo permissions: https://hub.github.com/hub.1.html * It will look for environment variable GITHUB_TOKEN """ import logging import os import tempfile import yaml import fire import git import httplib2 from kubeflow.kfctl.testing.util import application_util from kubeflow.testing import util # pylint: disable=no-name-in-module from containerregistry.client import docker_creds from containerregistry.client import docker_name from containerregistry.client.v2_2 import docker_http from containerregistry.client.v2_2 import docker_image as v2_2_image from containerregistry.transport import transport_pool # The image name as defined in the kustomization file JUPYTER_WEB_APP_IMAGE_NAME = "gcr.io/kubeflow-images-public/jupyter-web-app" class WebAppUpdater(object): # pylint: disable=useless-object-inheritance def __init__(self): self._last_commit = None self.manifests_repo_dir = None def build_image(self, build_project, registry_project): """Build the image. Args: build_project: GCP project used to build the image. registry_project: GCP project used to host the image. """ env = dict() env.update(os.environ) env["PROJECT"] = build_project env["REGISTRY_PROJECT"] = registry_project env["GIT_TAG"] = self._last_commit with tempfile.NamedTemporaryFile() as hf: name = hf.name env["OUTPUT"] = name web_dir = self._component_dir() util.run(["make", "build-gcb"], env=env, cwd=web_dir) # TODO(jlewi): We want to get the actual image produced by GCB. Right # now this is a bit brittle because we have multiple layers of substitution # e.g. in the Makefile and then the GCB YAML. # It might be better to parse the stdout of make-build-gcb to get the # GCB job name and then fetch the GCB info specifying the images. with open(name) as hf: data = yaml.load(hf) return data["image"] @property def last_commit(self): """Get the last commit of a change to the source for the jupyter-web-app.""" if not self._last_commit: # Get the hash of the last commit to modify the source for the Jupyter web # app image self._last_commit = util.run(["git", "log", "-n", "1", "--pretty=format:\"%h\"", "components/jupyter-web-app"], cwd=self._root_dir()).strip("\"") return self._last_commit def _find_remote_repo(self, repo, remote_url): # pylint: disable=no-self-use """Find the remote repo if it has already been added. Args: repo: The git python repo object. remote_url: The URL of the remote repo e.g. git@github.com:jlewi/kubeflow.git Returns: remote: git-python object representing the remote repo or none if it isn't present. """ for r in repo.remotes: for u in r.urls: if remote_url == u: return r return None def all(self, build_project, registry_project, remote_fork, # pylint: disable=too-many-statements,too-many-branches kustomize_file, add_github_host=False): """Build the latest image and update the prototype. Args: build_project: GCP project used to build the image. registry_project: GCP project used to host the image. remote_fork: Url of the remote fork. The remote fork used to create the PR; e.g. git@github.com:jlewi/kubeflow.git. currently only ssh is supported. kustomize_file: Path to the kustomize file add_github_host: If true will add the github ssh host to known ssh hosts. """ # TODO(jlewi): How can we automatically determine the root of the git # repo containing the kustomize_file? self.manifests_repo_dir = util.run(["git", "rev-parse", "--show-toplevel"], cwd=os.path.dirname(kustomize_file)) repo = git.Repo(self.manifests_repo_dir) util.maybe_activate_service_account() last_commit = self.last_commit # Ensure github.com is in the known hosts if add_github_host: output = util.run(["ssh-keyscan", "github.com"]) with open(os.path.join(os.getenv("HOME"), ".ssh", "known_hosts"), mode='a') as hf: hf.write(output) if not remote_fork.startswith("git@github.com"): raise ValueError("Remote fork currently only supports ssh") remote_repo = self._find_remote_repo(repo, remote_fork) if not remote_repo: fork_name = remote_fork.split(":", 1)[-1].split("/", 1)[0] logging.info("Adding remote %s=%s", fork_name, remote_fork) remote_repo = repo.create_remote(fork_name, remote_fork) logging.info("Last change to components-jupyter-web-app was %s", last_commit) base = "gcr.io/{0}/jupyter-web-app".format(registry_project) # Check if there is already an image tagged with this commit. image = base + ":" + self.last_commit transport = transport_pool.Http(httplib2.Http) src = docker_name.from_string(image) creds = docker_creds.DefaultKeychain.Resolve(src) image_exists = False try: with v2_2_image.FromRegistry(src, creds, transport) as src_image: logging.info("Image %s exists; digest: %s", image, src_image.digest()) image_exists = True except docker_http.V2DiagnosticException as e: if e.status == 404: logging.info("%s doesn't exist", image) else: raise if not image_exists: logging.info("Building the image") image = self.build_image(build_project, registry_project) logging.info("Created image: %s", image) else: logging.info("Image %s already exists", image) # TODO(jlewi): What if the file was already modified so we didn't # modify it in this run but we still need to commit it? image_updated = application_util.set_kustomize_image( kustomize_file, JUPYTER_WEB_APP_IMAGE_NAME, image) if not image_updated: logging.info("kustomization not updated so not creating a PR.") return application_util.regenerate_manifest_tests(self.manifests_repo_dir) branch_name = "update_jupyter_{0}".format(last_commit) if repo.active_branch.name != branch_name: logging.info("Creating branch %s", branch_name) branch_names = [b.name for b in repo.branches] if branch_name in branch_names: logging.info("Branch %s exists", branch_name) util.run(["git", "checkout", branch_name], cwd=self.manifests_repo_dir) else: util.run(["git", "checkout", "-b", branch_name], cwd=self.manifests_repo_dir) if self._check_if_pr_exists(commit=last_commit): # Since a PR already exists updating to the specified commit # don't create a new one. # We don't want to just push -f because if the PR already exists # git push -f will retrigger the tests. # To force a recreate of the PR someone could close the existing # PR and a new PR will be created on the next cron run. return logging.info("Add file %s to repo", kustomize_file) repo.index.add([kustomize_file]) repo.index.add([os.path.join(self.manifests_repo_dir, "tests/*")]) repo.index.commit("Update the jupyter web app image to {0}".format(image)) util.run(["git", "push", "-f", remote_repo.name, "{0}:{0}".format(branch_name)], cwd=self.manifests_repo_dir) self.create_pull_request(commit=last_commit) def _pr_title(self, commit): pr_title = "[auto PR] Update the jupyter-web-app image to {0}".format( commit) return pr_title def _check_if_pr_exists(self, commit=None): """Check if a PR is already open. Returns: exists: True if a PR updating the image to the specified commit already exists and false otherwise. """ # TODO(jlewi): Modeled on # https://github.com/kubeflow/examples/blob/master/code_search/docker/ks/update_index.sh # TODO(jlewi): We should use the GitHub API and check if there is an # existing open pull request. Or potentially just use the hub CLI. if not commit: commit = self.last_commit logging.info("No commit specified defaulting to %s", commit) pr_title = self._pr_title(commit) # See hub conventions: # https://hub.github.com/hub.1.html # The GitHub repository is determined automatically based on the name # of remote repositories output = util.run(["hub", "pr", "list", "--format=%U;%t\n"], cwd=self.manifests_repo_dir) lines = output.splitlines() prs = {} for l in lines: n, t = l.split(";", 1) prs[t] = n if pr_title in prs: logging.info("PR %s already exists to update the Jupyter web app image " "to %s", prs[pr_title], commit) return True return False def create_pull_request(self, base="kubeflow:master", commit=None): """Create a pull request. Args: base: The base to use. Defaults to "kubeflow:master". This should be in the form : """ pr_title = self._pr_title(commit) with tempfile.NamedTemporaryFile(delete=False, mode="w") as hf: hf.write(pr_title) hf.write("\n") hf.write("\n") hf.write( "Image built from commit https://github.com/kubeflow/kubeflow/" "commit/{0}".format(self._last_commit)) message_file = hf.name # TODO(jlewi): -f creates the pull requests even if there are local changes # this was useful during development but we may want to drop it. util.run(["hub", "pull-request", "-f", "--base=" + base, "-F", message_file], cwd=self.manifests_repo_dir) def _root_dir(self): this_dir = os.path.dirname(__file__) return os.path.abspath(os.path.join(this_dir, "..", "..", "..", "..")) def _component_dir(self): return os.path.join(self._root_dir(), "components", "jupyter-web-app") if __name__ == '__main__': logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) fire.Fire(WebAppUpdater) ================================================ FILE: py/kubeflow/kfctl/testing/pytests/conftest.py ================================================ import pytest def pytest_addoption(parser): parser.addoption( "--app_path", action="store", default="", help="Path where the KF application should be stored") parser.addoption( "--app_name", action="store", default="", help="Name of the KF application") parser.addoption( "--cluster_name", action="store", default="", help="Name of ephemeral EKS cluster for e2e test.") parser.addoption( "--kfctl_path", action="store", default="", help="Path to kfctl.") parser.addoption( "--kfctl_repo_path", action="store", default="", help="Path to kfctl repo.") parser.addoption( "--namespace", action="store", default="kubeflow", help="Namespace to use.") parser.addoption( "--project", action="store", default="kubeflow-ci-deployment", help="GCP project to deploy Kubeflow to") parser.addoption( "--config_path", action="store", default="", help=("The config to use for kfctl init. The path can use python style " "go format strings; e.g. " "--config_path=/{srcdir}/kubeflow/manifests/kfdef/kfctl_gcp.yaml" " The values should be supplied by --values.")) parser.addoption( "--values", action="store", default="", help=("A comma separated list of key value pairs to be used for " "subsitution in --config_path")) parser.addoption( "--build_and_apply", action="store", default="False", help="Whether to build and apply or apply in kfctl" ) # TODO(jlewi): This flag is deprecated this should be determined now from the KFDef spec. parser.addoption( "--use_basic_auth", action="store", default="False", help="Use basic auth.") # TODO(jlewi): This flag is deprecated this should be determined now from the KFDef spec parser.addoption( "--use_istio", action="store", default="True", help="Use istio.") parser.addoption( "--eks_cluster_version", action="store", default="", help="Version of ephemeral EKS cluster") parser.addoption( "--cluster_creation_script", action="store", default="", help="The script to use to create a K8s cluster before running kfctl.") parser.addoption( "--cluster_deletion_script", action="store", default="", help="The script to use to delete a K8s cluster before running kfctl.") parser.addoption( "--self_signed_cert", action="store", default="False", help="Whether to use self-signed cert for ingress.") parser.addoption( "--upgrade_spec_path", action="store", default="", help=("The spec for upgrading Kubeflow. The path can use python style " "go format strings; e.g. " "--upgrade_spec_path=/{srcdir}/kubeflow/manifests/kfdef/kfctl_gcp_upgrade.yaml")) @pytest.fixture def app_path(request): return request.config.getoption("--app_path") @pytest.fixture def app_name(request): return request.config.getoption("--app_name") @pytest.fixture def kfctl_path(request): return request.config.getoption("--kfctl_path") @pytest.fixture def kfctl_repo_path(request): return request.config.getoption("--kfctl_repo_path") @pytest.fixture def namespace(request): return request.config.getoption("--namespace") @pytest.fixture def project(request): return request.config.getoption("--project") @pytest.fixture def config_path(request): return request.config.getoption("--config_path") @pytest.fixture def values(request): return request.config.getoption("--values") @pytest.fixture def eks_cluster_version(request): return request.config.getoption("--eks_cluster_version") @pytest.fixture def cluster_creation_script(request): return request.config.getoption("--cluster_creation_script") @pytest.fixture def cluster_deletion_script(request): return request.config.getoption("--cluster_deletion_script") @pytest.fixture def cluster_name(request): return request.config.getoption("--cluster_name") @pytest.fixture def build_and_apply(request): value = request.config.getoption("--build_and_apply").lower() if value in ["t", "true"]: return True else: return False @pytest.fixture def use_basic_auth(request): value = request.config.getoption("--use_basic_auth").lower() if value in ["t", "true"]: return True else: return False @pytest.fixture def use_istio(request): value = request.config.getoption("--use_istio").lower() if value in ["t", "true"]: return True else: return False @pytest.fixture def self_signed_cert(request): value = request.config.getoption("--self_signed_cert").lower() if value in ["t", "true"]: return True else: return False @pytest.fixture def upgrade_spec_path(request): return request.config.getoption("--upgrade_spec_path") ================================================ FILE: py/kubeflow/kfctl/testing/pytests/endpoint_ready_test.py ================================================ import json import logging import os import pytest from kubeflow.testing import util from kubeflow.kfctl.testing.util import gcp_util # There's really no good reason to run test_endpoint during presubmits. # We shouldn't need it to feel confident that kfctl is working. @pytest.mark.skipif(os.getenv("JOB_TYPE") == "presubmit", reason="test endpoint doesn't run in presubmits") def test_endpoint_is_ready(record_xml_attribute, project, app_path, app_name, use_basic_auth): """Test that Kubeflow was successfully deployed. Args: project: The gcp project that we deployed kubeflow app_name: The name of the kubeflow deployment """ util.set_pytest_junit(record_xml_attribute, "test_endpoint_is_ready") url = "https://{}.endpoints.{}.cloud.goog".format(app_name, project) if use_basic_auth: with open(os.path.join(app_path, "login.json"), "r") as f: login = json.load(f) # Let it fail if login info cannot be found. username = login["username"] password = login["password"] if not gcp_util.basic_auth_is_ready(url, username, password): raise Exception("Basic auth endpoint is not ready") else: # Owned by project kubeflow-ci-deployment. os.environ["CLIENT_ID"] = "29647740582-7meo6c7a9a76jvg54j0g2lv8lrsb4l8g.apps.googleusercontent.com" if not gcp_util.iap_is_ready(url): raise Exception("IAP endpoint is not ready") if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/jupyter_test.py ================================================ """Test jupyter custom resource. This file tests that we can create notebooks using the Jupyter custom resource. It is an integration test as it depends on having access to a Kubeflow cluster with the custom resource test installed. We use the pytest framework because 1. It can output results in junit format for prow/gubernator 2. It has good support for configuring tests using command line arguments (https://docs.pytest.org/en/latest/example/simple.html) Python Path Requirements: kubeflow/testing/py - https://github.com/kubeflow/testing/tree/master/py * Provides utilities for testing Manually running the test 1. Configure your KUBECONFIG file to point to the desired cluster """ import logging import os import pytest from kubernetes import client as k8s_client from kubeflow.testing import util from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util def test_jupyter(record_xml_attribute, kfctl_repo_path, namespace, cluster_name): """Test the jupyter notebook. Args: record_xml_attribute: Test fixture provided by pytest. kfctl_repo_path: path to local kfctl repository. namespace: namespace to run in. """ kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) logging.info("using kfctl repo: %s" % kfctl_repo_path) util.run(["kubectl", "apply", "-f", os.path.join(kfctl_repo_path, "py/kubeflow/kfctl/testing/pytests/testdata/jupyter_test.yaml")]) api_client = k8s_client.ApiClient() api = k8s_client.CoreV1Api(api_client) resp = api.list_namespaced_service(namespace) names = [service.metadata.name for service in resp.items] if not "jupyter-test" in names: raise ValueError("not able to find jupyter-test service.") if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kf_is_ready_test.py ================================================ import logging import os import yaml import pytest from kubeflow.testing import util from kubeflow.kfctl.testing.util import deploy_utils from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util def set_logging(): logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) def get_platform_app_name(app_path): with open(os.path.join(app_path, "tmp.yaml")) as f: kfdef = yaml.safe_load(f) app_name = kfdef["metadata"]["name"] platform = "" apiVersion = kfdef["apiVersion"].strip().split("/") if len(apiVersion) != 2: raise RuntimeError("Invalid apiVersion: " + kfdef["apiVersion"].strip()) if apiVersion[-1] == "v1alpha1": platform = kfdef["spec"]["platform"] elif apiVersion[-1] in ["v1beta1", "v1"]: for plugin in kfdef["spec"].get("plugins", []): if plugin.get("kind", "") == "KfGcpPlugin": platform = "gcp" elif plugin.get("kind", "") == "KfAwsPlugin": platform = "aws" elif plugin.get("kind", "") == "KfExistingArriktoPlugin": platform = "existing_arrikto" else: # Indicate agnostic Kubeflow Platform platform = "agnostic" else: raise RuntimeError("Unknown version: " + apiVersion[-1]) return platform, app_name def check_deployments_ready(record_xml_attribute, namespace, name, deployments, cluster_name): """Test that Kubeflow deployments are successfully deployed. Args: namespace: The namespace Kubeflow is deployed to. """ set_logging() util.set_pytest_junit(record_xml_attribute, name) kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) api_client = deploy_utils.create_k8s_client() for deployment_name in deployments: logging.info("Verifying that deployment %s started...", deployment_name) util.wait_for_deployment(api_client, namespace, deployment_name, 10) def test_admission_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "admission-webhook-deployment" ] check_deployments_ready(record_xml_attribute, namespace, "test_admission_is_ready", deployment_names, cluster_name) def test_katib_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "katib-controller", "katib-mysql", "katib-db-manager", "katib-ui", ] check_deployments_ready(record_xml_attribute, namespace, "test_katib_is_ready", deployment_names, cluster_name) def test_metadata_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "metadata-grpc-deployment", "metadata-db", "metadata-envoy-deployment", "metadata-writer", ] check_deployments_ready(record_xml_attribute, namespace, "test_metadata_is_ready", deployment_names, cluster_name) def test_pipeline_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "argo-ui", "cache-deployer-deployment", "cache-server", "kubeflow-pipelines-profile-controller", "minio", "ml-pipeline", "ml-pipeline-persistenceagent", "ml-pipeline-scheduledworkflow", "ml-pipeline-ui", "ml-pipeline-viewer-crd", "ml-pipeline-visualizationserver", "mysql", ] check_deployments_ready(record_xml_attribute, namespace, "test_pipeline_is_ready", deployment_names, cluster_name) def test_notebook_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "jupyter-web-app-deployment", "notebook-controller-deployment", ] check_deployments_ready(record_xml_attribute, namespace, "test_notebook_is_ready", deployment_names, cluster_name) def test_centraldashboard_is_ready(record_xml_attribute, namespace, cluster_name): check_deployments_ready(record_xml_attribute, namespace, "test_centraldashboard_is_ready", ["centraldashboard"], cluster_name) def test_profiles_is_ready(record_xml_attribute, namespace, cluster_name): check_deployments_ready(record_xml_attribute, namespace, "test_profile_is_ready", ["profiles-deployment"], cluster_name) def test_seldon_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "seldon-controller-manager" ] check_deployments_ready(record_xml_attribute, namespace, "test_seldon_is_ready", deployment_names, cluster_name) def test_spark_is_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "spark-operatorsparkoperator" ] check_deployments_ready(record_xml_attribute, namespace, "test_spark_is_ready", deployment_names, cluster_name) def test_training_operators_are_ready(record_xml_attribute, namespace, cluster_name): deployment_names = [ "mpi-operator", "mxnet-operator", "pytorch-operator", "tf-job-operator", ] check_deployments_ready(record_xml_attribute, namespace, "test_training_is_ready", deployment_names, cluster_name) def test_workflow_controller_is_ready(record_xml_attribute, namespace, cluster_name): check_deployments_ready(record_xml_attribute, namespace, "test_workflow_controller_is_ready", ["workflow-controller"], cluster_name) def test_kf_is_ready(record_xml_attribute, namespace, use_basic_auth, app_path, cluster_name): """Test that Kubeflow was successfully deployed. Args: namespace: The namespace Kubeflow is deployed to. """ set_logging() util.set_pytest_junit(record_xml_attribute, "test_kf_is_ready") kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) api_client = deploy_utils.create_k8s_client() # Verify that components are actually deployed. deployment_names = [] stateful_set_names = [] daemon_set_names = [] platform, _ = get_platform_app_name(app_path) # TODO(PatrickXYS): not sure why istio-galley can't found ingress_related_deployments = [ "cluster-local-gateway", "istio-citadel", "istio-ingressgateway", "istio-pilot", "istio-policy", "istio-sidecar-injector", "istio-telemetry", "prometheus", ] ingress_related_stateful_sets = [] knative_namespace = "knative-serving" knative_related_deployments = [ "activator", "autoscaler", "controller", "networking-istio", "webhook", ] if platform == "gcp": deployment_names.extend(["cloud-endpoints-controller"]) stateful_set_names.extend(["kfserving-controller-manager"]) if use_basic_auth: deployment_names.extend(["basic-auth-login"]) ingress_related_stateful_sets.extend(["backend-updater"]) else: ingress_related_deployments.extend(["iap-enabler"]) ingress_related_stateful_sets.extend(["backend-updater"]) elif platform == "existing_arrikto": deployment_names.extend(["dex"]) ingress_related_deployments.extend(["authservice"]) knative_related_deployments = [] elif platform == "aws": # TODO(PatrickXYS): Extend List with AWS Deployment deployment_names.extend(["alb-ingress-controller"]) daemon_set_names.extend(["nvidia-device-plugin-daemonset"]) # TODO(jlewi): Might want to parallelize this. for deployment_name in deployment_names: logging.info("Verifying that deployment %s started...", deployment_name) util.wait_for_deployment(api_client, namespace, deployment_name, 10) ingress_namespace = "istio-system" for deployment_name in ingress_related_deployments: logging.info("Verifying that deployment %s started...", deployment_name) util.wait_for_deployment(api_client, ingress_namespace, deployment_name, 10) all_stateful_sets = [(namespace, name) for name in stateful_set_names] all_stateful_sets.extend([(ingress_namespace, name) for name in ingress_related_stateful_sets]) for ss_namespace, name in all_stateful_sets: logging.info("Verifying that stateful set %s.%s started...", ss_namespace, name) try: util.wait_for_statefulset(api_client, ss_namespace, name) except: # Collect debug information by running describe util.run(["kubectl", "-n", ss_namespace, "describe", "statefulsets", name]) raise all_daemon_sets = [(namespace, name) for name in daemon_set_names] for ds_namespace, name in all_daemon_sets: logging.info("Verifying that daemonset set %s.%s started...", ds_namespace, name) try: util.wait_for_daemonset(api_client, ds_namespace, name) except: # Collect debug information by running describe util.run(["kubectl", "-n", ds_namespace, "describe", "daemonset", name]) raise ingress_names = ["istio-ingress"] # Check if Ingress is Ready and Healthy if platform in ["aws"]: for ingress_name in ingress_names: logging.info("Verifying that ingress %s started...", ingress_name) util.wait_for_ingress(api_client, ingress_namespace, ingress_name, 10) for deployment_name in knative_related_deployments: logging.info("Verifying that deployment %s started...", deployment_name) util.wait_for_deployment(api_client, knative_namespace, deployment_name, 10) # Check if Dex is Ready and Healthy dex_deployment_names = ["dex"] dex_namespace = "auth" for dex_deployment_name in dex_deployment_names: logging.info("Verifying that deployment %s started...", dex_deployment_name) util.wait_for_deployment(api_client, dex_namespace, dex_deployment_name, 10) # Check if Cert-Manager is Ready and Healthy cert_manager_deployment_names = [ "cert-manager", "cert-manager-cainjector", "cert-manager-webhook", ] cert_manager_namespace = "cert-manager" for cert_manager_deployment_name in cert_manager_deployment_names: logging.info("Verifying that deployment %s started...", cert_manager_deployment_name) util.wait_for_deployment(api_client, cert_manager_namespace, cert_manager_deployment_name, 10) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfam_test.py ================================================ import logging import pytest from kubeflow.testing import util import json from retrying import retry from time import sleep import uuid from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util def test_kfam(record_xml_attribute, cluster_name): util.set_pytest_junit(record_xml_attribute, "test_kfam_e2e") kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) getcmd = "kubectl get pods -n kubeflow -l=app=jupyter-web-app --template '{{range.items}}{{.metadata.name}}{{end}}'" jupyterpod = util.run(getcmd.split(' '))[1:-1] logging.info("accessing kfam svc from jupyter pod %s" % jupyterpod) sleep(10) # Profile Creation profile_name = "testprofile-%s" % uuid.uuid4().hex[0:7] util.run(['kubectl', 'exec', jupyterpod, '-n', 'kubeflow', '--', 'curl', '--silent', '-X', 'POST', '-d', '{"metadata":{"name":"%s"},"spec":{"owner":{"kind":"User","name":"user1@kubeflow.org"}}}' % profile_name, 'profiles-kfam.kubeflow:8081/kfam/v1/profiles']) assert verify_profile_creation(jupyterpod, profile_name) @retry(wait_fixed=2000, stop_max_delay=20 * 1000) def verify_profile_creation(jupyterpod, profile_name): # Verify Profile Creation bindingsstr = util.run(['kubectl', 'exec', jupyterpod, '-n', 'kubeflow', '--', 'curl', '--silent', 'profiles-kfam.kubeflow:8081/kfam/v1/bindings']) bindings = json.loads(bindingsstr) if profile_name not in [binding['referredNamespace'] for binding in bindings['bindings']]: raise Exception("testprofile not created yet!") return True if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_create_cluster_test.py ================================================ import logging import pytest import os from kubeflow.testing import util def test_create_cluster(record_xml_attribute, cluster_name, eks_cluster_version, cluster_creation_script, values): """Test Create Cluster For E2E Test. Args: cluster_name: Name of EKS cluster eks_cluster_version: Version of EKS cluster cluster_creation_script: script invoked to create a new cluster values: Comma separated list of variables to substitute into config_path """ util.set_pytest_junit(record_xml_attribute, "test_create_cluster") if values: pairs = values.split(",") path_vars = {} for p in pairs: k, v = p.split("=") path_vars[k] = v # Create EKS Cluster logging.info("Creating EKS Cluster") os.environ["CLUSTER_NAME"] = cluster_name os.environ["EKS_CLUSTER_VERSION"] = eks_cluster_version util.run(["/bin/bash", "-c", cluster_creation_script]) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_delete_cluster_test.py ================================================ """Run kfctl delete as a pytest. We use this in order to generate a junit_xml file. """ import logging import pytest import os from kubeflow.testing import util def test_kfctl_delete(record_xml_attribute, cluster_deletion_script, cluster_name): util.set_pytest_junit(record_xml_attribute, "test_cluster_delete") if cluster_deletion_script: logging.info("cluster_deletion_script specified: %s", cluster_deletion_script) os.environ["CLUSTER_NAME"] = cluster_name util.run(["/bin/bash", "-c", cluster_deletion_script]) return if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_delete_test.py ================================================ """Run kfctl delete as a pytest. We use this in order to generate a junit_xml file. """ import logging import os from retrying import retry import pytest from kubeflow.testing import util from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util # TODO(https://github.com/kubeflow/kfctl/issues/56): test_kfctl_delete is flaky # and more importantly failures block upload of GCS artifacts so for now we mark # it as expected to fail. @pytest.mark.xfail def test_kfctl_delete(record_xml_attribute, kfctl_path, app_path, cluster_name): util.set_pytest_junit(record_xml_attribute, "test_kfctl_delete") # TODO(PatrickXYS): do we need to load kubeconfig again? if not kfctl_path: raise ValueError("kfctl_path is required") if not app_path: raise ValueError("app_path is required") logging.info("Using kfctl path %s", kfctl_path) logging.info("Using app path %s", app_path) kfdef_path = os.path.join(app_path, "tmp.yaml") logging.info("Using kfdef file path %s", kfdef_path) kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) # We see failures because delete operation will delete cert-manager and # knative-serving, and encounter timeout. To deal with this we do retries. # This has a potential downside of hiding errors that are fixed by retrying. @retry(stop_max_delay=60*3*1000) def run_delete(): util.run([kfctl_path, "delete", "-V", "-f", kfdef_path], cwd=app_path) run_delete() if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_delete_wrong_cluster.py ================================================ """Run kfctl delete as a pytest. Deletion should fail because the host is wrong. We use this in order to generate a junit_xml file. """ import logging import os import subprocess import yaml from retrying import retry import pytest from kubeflow.testing import util from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util def test_kfctl_delete_wrong_cluster(record_xml_attribute, kfctl_path, app_path, cluster_name): util.set_pytest_junit(record_xml_attribute, "test_kfctl_delete_wrong_cluster") if not kfctl_path: raise ValueError("kfctl_path is required") if not app_path: raise ValueError("app_path is required") logging.info("Using kfctl path %s", kfctl_path) logging.info("Using app path %s", app_path) kfdef_path = os.path.join(app_path, "tmp.yaml") kfdef = {} with open(kfdef_path, "r") as f: kfdef = yaml.safe_load(f) # Make sure we copy the correct host instead of string reference. cluster = kfdef.get("metadata", {}).get("clusterName", "")[:] if not cluster: raise ValueError("cluster is not written to kfdef") kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) @retry(stop_max_delay=60*3*1000) def run_delete(): try: # Put an obvious wrong cluster into KfDef kfdef["metadata"]["clusterName"] = "dummy" with open(kfdef_path, "w") as f: yaml.dump(kfdef, f) util.run([kfctl_path, "delete", "-V", "-f", kfdef_path], cwd=app_path) except subprocess.CalledProcessError as e: if e.output.find("cluster name doesn't match") != -1: return else: # Re-throw error if it's not expected. raise e finally: # Restore the correct host info. kfdef["metadata"]["clusterName"] = cluster[:] with open(kfdef_path, "w") as f: yaml.dump(kfdef, f) run_delete() if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_deploy_kubeflow_test.py ================================================ import logging import pytest import os from kubeflow.kfctl.testing.util import kfctl_go_test_utils as kfctl_util from kubeflow.testing import util def test_build_kfctl_go(record_xml_attribute, app_path, project, use_basic_auth, use_istio, config_path, build_and_apply, kfctl_repo_path, cluster_name, values): """Test building and deploying Kubeflow. Args: app_path: The path to the Kubeflow app. project: The GCP project to use. use_basic_auth: Whether to use basic_auth. use_istio: Whether to use Istio or not config_path: Path to the KFDef spec file. cluster_name: Name of EKS cluster build_and_apply: whether to build and apply or apply kfctl_repo_path: path to the kubeflow/kfctl repo. values: Comma separated list of variables to substitute into config_path """ util.set_pytest_junit(record_xml_attribute, "test_deploy_kubeflow") if values: pairs = values.split(",") path_vars = {} for p in pairs: k, v = p.split("=") path_vars[k] = v config_path = config_path.format(**path_vars) logging.info("config_path after substitution: %s", config_path) kfctl_path = os.path.join(kfctl_repo_path, "bin", "kfctl") app_path = kfctl_util.kfctl_deploy_kubeflow( app_path, config_path, kfctl_path, build_and_apply, cluster_name) logging.info("kubeflow app path: %s", app_path) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_go_test.py ================================================ import logging import pytest from kubeflow.kfctl.testing.util import kfctl_go_test_utils as kfctl_util from kubeflow.testing import util def test_build_kfctl_go(record_xml_attribute, config_path, kfctl_repo_path, values): """Test building and deploying Kubeflow. Args: config_path: Path to the KFDef spec file. kfctl_repo_path: path to the kubeflow/kfctl repo. values: Comma separated list of variables to substitute into config_path """ util.set_pytest_junit(record_xml_attribute, "test_build_kfctl_go") logging.info("using kfctl repo: %s" % kfctl_repo_path) if values: pairs = values.split(",") path_vars = {} for p in pairs: k, v = p.split("=") path_vars[k] = v config_path = config_path.format(**path_vars) logging.info("config_path after substitution: %s", config_path) kfctl_util.build_kfctl_go(kfctl_repo_path) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_second_apply.py ================================================ import logging import os import pytest from kubeflow.kfctl.testing.util import kfctl_go_test_utils as kfctl_util from kubeflow.testing import util def test_second_apply(record_xml_attribute, app_path, kfctl_path): """Test that we can run kfctl apply again with error. Args: app_path: The app dir of kubeflow deployment. kfctl_path: The path to kfctl binary. """ if not os.path.exists(kfctl_path): msg = "kfctl Go binary not found: {path}".format(path=kfctl_path) logging.error(msg) raise RuntimeError(msg) # Need to activate account for scopes. if os.getenv("GOOGLE_APPLICATION_CREDENTIALS"): util.run(["gcloud", "auth", "activate-service-account", "--key-file=" + os.environ["GOOGLE_APPLICATION_CREDENTIALS"]]) util.run([kfctl_path, "apply", "-V", "-f=" + os.path.join(app_path, "tmp.yaml")], cwd=app_path) ================================================ FILE: py/kubeflow/kfctl/testing/pytests/kfctl_upgrade_test.py ================================================ import logging import os import pytest from kubernetes import client as k8s_client from kubeflow.kfctl.testing.util import kfctl_go_test_utils as kfctl_util from kubeflow.testing import util def test_upgrade_kubeflow(record_xml_attribute, app_path, kfctl_path, upgrade_spec_path): """Test that we can run upgrade on a Kubeflow cluster. Args: app_path: The app dir of kubeflow deployment. kfctl_path: The path to kfctl binary. upgrade_spec_path: The path to the upgrade spec file. """ kfctl_util.kfctl_upgrade_kubeflow(app_path, kfctl_path, upgrade_spec_path) ================================================ FILE: py/kubeflow/kfctl/testing/pytests/pytorch_job_deploy.py ================================================ import datetime import logging import os import pytest from kubeflow.testing import util from kubernetes import client as k8s_client from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util @pytest.mark.xfail(reason=("See: https://github.com/kubeflow/kfctl/issues/199; " "test is flaky.")) def test_deploy_pytorchjob(kfctl_repo_path, namespace, cluster_name): """Deploy PytorchJob.""" kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) logging.info("using kfctl repo: %s" % kfctl_repo_path) util.run(["kubectl", "apply", "-f", os.path.join(kfctl_repo_path, "py/kubeflow/kfctl/testing/pytests/testdata/pytorch_job.yaml")]) api_client = k8s_client.ApiClient() api = k8s_client.CoreV1Api(api_client) # If the call throws exception, let it emit as an error case. resp = api.list_namespaced_pod(namespace) names = { "pytorch-mnist-ddp-cpu-master-0": False, "pytorch-mnist-ddp-cpu-worker-0": False, } for pod in resp.items: name = pod.metadata.name if name in names: names[name] = True msg = [] for n in names: if not names[n]: msg.append("pod %s is not found" % n) if msg: raise ValueError("; ".join(msg)) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) pytest.main() ================================================ FILE: py/kubeflow/kfctl/testing/pytests/testdata/jupyter_test.yaml ================================================ apiVersion: kubeflow.org/v1 kind: Notebook metadata: name: jupyter-test spec: template: spec: containers: - image: gcr.io/kubeflow-images-public/tensorflow-1.14.0-notebook-cpu:v1.0.0 name: notebook resources: requests: cpu: 500m memory: 1Gi ================================================ FILE: py/kubeflow/kfctl/testing/pytests/testdata/pytorch_job.yaml ================================================ apiVersion: kubeflow.org/v1 kind: PyTorchJob metadata: name: pytorch-mnist-ddp-cpu spec: pytorchReplicaSpecs: Master: replicas: 1 restartPolicy: OnFailure template: spec: containers: - image: gcr.io/kubeflow-ci/pytorch-mnist/traincpu:latest name: pytorch Worker: replicas: 1 restartPolicy: OnFailure template: spec: containers: - image: gcr.io/kubeflow-ci/pytorch-mnist/traincpu:latest name: pytorch ================================================ FILE: py/kubeflow/kfctl/testing/test_deploy.py ================================================ #!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2018 The Kubeflow Authors All rights reserved. # # 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. """Test deploying Kubeflow. Requirements: This project assumes the py directory in github.com/kubeflow/tf-operator corresponds to a top level Python package on the Python path. TODO(jlewi): Come up with a better story for how we reuse the py package in kubeflow/tf-operator. We should probably turn that into a legit Python pip package that is built and released as part of the kubeflow/tf-operator project. """ import argparse import datetime import json import logging import os import errno import re import shutil import subprocess import tempfile import time import uuid import requests import yaml from googleapiclient import discovery, errors from kubernetes import client as k8s_client from kubernetes.client import rest from kubernetes.config import kube_config from oauth2client.client import GoogleCredentials from kubeflow.testing import test_util, util # pylint: disable=no-name-in-module from kubeflow.kfctl.testing.util import vm_util # The ksonnet binary ks = "ks-13" def _setup_test(api_client, run_label): """Create the namespace for the test. Returns: test_dir: The local test directory. """ api = k8s_client.CoreV1Api(api_client) namespace = k8s_client.V1Namespace() namespace.api_version = "v1" namespace.kind = "Namespace" namespace.metadata = k8s_client.V1ObjectMeta( name=run_label, labels={ "app": "kubeflow-e2e-test", }) try: logging.info("Creating namespace %s", namespace.metadata.name) namespace = api.create_namespace(namespace) logging.info("Namespace %s created.", namespace.metadata.name) except rest.ApiException as e: if e.status == 409: logging.info("Namespace %s already exists.", namespace.metadata.name) else: raise return namespace def create_k8s_client(_): # We need to load the kube config so that we can have credentials to # talk to the APIServer. util.load_kube_config(persist_config=False) # Create an API client object to talk to the K8s master. api_client = k8s_client.ApiClient() return api_client # TODO(jlewi): We should make this a reusable function in kubeflow/testing # because we will probably want to use it in other places as well. def setup_kubeflow_ks_app(args, api_client): """Create a ksonnet app for Kubeflow""" try: os.makedirs(args.test_dir) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(args.test_dir): pass else: raise logging.info("Using test directory: %s", args.test_dir) namespace_name = args.namespace namespace = _setup_test(api_client, namespace_name) logging.info("Using namespace: %s", namespace) if args.github_token: logging.info("Setting GITHUB_TOKEN to %s.", args.github_token) # Set a GITHUB_TOKEN so that we don't rate limited by GitHub; # see: https://github.com/ksonnet/ksonnet/issues/233 os.environ["GITHUB_TOKEN"] = args.github_token if not os.getenv("GITHUB_TOKEN"): logging.warning("GITHUB_TOKEN not set; you will probably hit Github API " "limits.") # Initialize a ksonnet app. app_name = "kubeflow-test-" + uuid.uuid4().hex[0:4] util.run([ ks, "init", app_name, ], cwd=args.test_dir) app_dir = os.path.join(args.test_dir, app_name) kubeflow_registry = "github.com/kubeflow/kubeflow/tree/master/kubeflow" util.run([ks, "registry", "add", "kubeflow", kubeflow_registry], cwd=app_dir) # Install required packages packages = [ "kubeflow/common", "kubeflow/tf-training", "kubeflow/pytorch-job", "kubeflow/argo" ] # Instead of installing packages we edit the app.yaml file directly #for p in packages: # util.run([ks, "pkg", "install", p], cwd=app_dir) app_file = os.path.join(app_dir, "app.yaml") with open(app_file) as f: app_yaml = yaml.load(f) libraries = {} for pkg in packages: pkg = pkg.split("/")[1] libraries[pkg] = { 'gitVersion': { 'commitSha': 'fake', 'refSpec': 'fake' }, 'name': pkg, 'registry': "kubeflow" } app_yaml['libraries'] = libraries with open(app_file, "w") as f: yaml.dump(app_yaml, f) # Create vendor directory with a symlink to the src # so that we use the code at the desired commit. target_dir = os.path.join(app_dir, "vendor", "kubeflow") REPO_ORG = "kubeflow" REPO_NAME = "kubeflow" REGISTRY_PATH = "kubeflow" source = os.path.join(args.test_dir, "src", REPO_ORG, REPO_NAME, REGISTRY_PATH) logging.info("Creating link %s -> %s", target_dir, source) os.symlink(source, target_dir) return app_dir def deploy_model(args): """Deploy a TF model using the TF serving component.""" api_client = create_k8s_client(args) app_dir = setup_kubeflow_ks_app(args, api_client) logging.info("Deploying tf-serving.") params = {} for pair in args.params.split(","): k, v = pair.split("=", 1) if k != "namespace": params[k] = v else: namespace = v if namespace == None: raise ValueError("namespace must be supplied in args.") # deployment component deployComponent = "modelServer" generate_command = [ ks, "generate", "tf-serving-deployment-gcp", deployComponent ] util.run(generate_command, cwd=app_dir) ks_deploy( app_dir, deployComponent, params, env=None, account=None, namespace=namespace) # service component serviceComponent = "modelServer-service" generate_command = [ks, "generate", "tf-serving-service", serviceComponent] util.run(generate_command, cwd=app_dir) ks_deploy( app_dir, serviceComponent, params, env=None, account=None, namespace=namespace) core_api = k8s_client.CoreV1Api(api_client) deploy = core_api.read_namespaced_service(args.deploy_name, args.namespace) cluster_ip = deploy.spec.cluster_ip if not cluster_ip: raise ValueError("inception service wasn't assigned a cluster ip.") util.wait_for_deployment( api_client, namespace, args.deploy_name, timeout_minutes=10) logging.info("Verified TF serving started.") def test_successful_deployment(deployment_name): """ Tests if deployment_name is successfully running using kubectl """ # TODO use the python kubernetes library to get deployment status # This is using kubectl right now retries = 20 i = 0 while True: if i == retries: raise Exception('Deployment failed: ' + deployment_name) try: output = util.run(["kubectl", "get", "deployment", deployment_name, "-n", "kubeflow"]) logging.info("output = \n" + output) if output.count('\n') == 1: output = output.split('\n')[1] output = re.split(' +', output) desired_pods = output[1] current_pods = output[2] uptodate_pods = output[3] available_pods = output[4] logging.info("desired_pods " + desired_pods) logging.info("current_pods " + current_pods) logging.info("uptodate_pods " + uptodate_pods) logging.info("available_pods " + available_pods) if desired_pods == current_pods and \ desired_pods == uptodate_pods and \ desired_pods == available_pods: return True except subprocess.CalledProcessError as e: logging.error(e) logging.info("Sleeping 5 seconds and retrying..") time.sleep(5) i += 1 def test_katib(args): test_successful_deployment('katib-mysql') test_successful_deployment('katib-db-manager') test_successful_deployment('katib-ui') test_successful_deployment('katib-controller') def deploy_argo(args): api_client = create_k8s_client(args) app_dir = setup_kubeflow_ks_app(args, api_client) component = "argo" logging.info("Deploying argo") generate_command = [ks, "generate", "argo", component, "--name", "argo"] util.run(generate_command, cwd=app_dir) ks_deploy(app_dir, component, {}, env=None, account=None, namespace=None) # Create a hello world workflow util.run([ "kubectl", "create", "-n", "default", "-f", "https://raw.githubusercontent.com/argoproj/argo/master/examples/hello-world.yaml" ], cwd=app_dir) # Wait for 200 seconds to check if the hello-world pod was created retries = 20 i = 0 while True: if i == retries: raise Exception('Failed to run argo workflow') output = util.run([ "kubectl", "get", "pods", "-n", "default", "-lworkflows.argoproj.io/workflow" ]) if "hello-world-" in output: return True time.sleep(10) i += 1 def deploy_pytorchjob(args): """Deploy Pytorchjob using the pytorch-job component""" api_client = create_k8s_client(args) app_dir = setup_kubeflow_ks_app(args, api_client) component = "example-job" logging.info("Deploying pytorch.") generate_command = [ks, "generate", "pytorch-job", component] util.run(generate_command, cwd=app_dir) params = {} for pair in args.params.split(","): k, v = pair.split("=", 1) params[k] = v ks_deploy(app_dir, component, params, env=None, account=None, namespace=None) def teardown(args): # Delete the namespace logging.info("Deleting namespace %s", args.namespace) api_client = create_k8s_client(args) core_api = k8s_client.CoreV1Api(api_client) core_api.delete_namespace(args.namespace, {}) def determine_test_name(args): if args.deploy_name: return args.func.__name__ + "-" + args.deploy_name return args.func.__name__ # TODO(jlewi): We should probably make this a generic function in # kubeflow.testing.` def wrap_test(args): """Run the tests given by args.func and output artifacts as necessary. """ test_name = determine_test_name(args) test_case = test_util.TestCase() test_case.class_name = "KubeFlow" test_case.name = args.workflow_name + "-" + test_name try: def run(): args.func(args) test_util.wrap_test(run, test_case) finally: # Test grid has problems with underscores in the name. # https://github.com/kubeflow/kubeflow/issues/631 # TestGrid currently uses the regex junit_(^_)*.xml so we only # want one underscore after junit. junit_name = test_case.name.replace("_", "-") junit_path = os.path.join(args.artifacts_dir, "junit_{0}.xml".format(junit_name)) logging.info("Writing test results to %s", junit_path) test_util.create_junit_xml_file([test_case], junit_path) # TODO(jlewi): We should probably make this a reusable function since a # lot of test code code use it. def ks_deploy(app_dir, component, params, env=None, account=None, namespace=None): """Deploy the specified ksonnet component. Args: app_dir: The ksonnet directory component: Name of the component to deployed params: A dictionary of parameters to set; can be empty but should not be None. env: (Optional) The environment to use, if none is specified a new one is created. account: (Optional) The account to use. namespace: (Optional) The namespace to use when adding the environment Raises: ValueError: If input arguments aren't valid. """ if not component: raise ValueError("component can't be None.") # TODO(jlewi): It might be better if the test creates the app and uses # the latest stable release of the ksonnet configs. That however will cause # problems when we make changes to the TFJob operator that require changes # to the ksonnet configs. One advantage of checking in the app is that # we can modify the files in vendor if needed so that changes to the code # and config can be submitted in the same pr. now = datetime.datetime.now() if not env: env = "e2e-" + now.strftime("%m%d-%H%M-") + uuid.uuid4().hex[0:4] logging.info("Using app directory: %s", app_dir) if not namespace: util.run([ks, "env", "add", env], cwd=app_dir) else: util.run([ks, "env", "add", env, "--namespace=" + namespace], cwd=app_dir) for k, v in params.iteritems(): util.run([ks, "param", "set", "--env=" + env, component, k, v], cwd=app_dir) apply_command = [ks, "apply", env, "-c", component] if account: apply_command.append("--as=" + account) util.run(apply_command, cwd=app_dir) def modify_minikube_config(config_path, certs_dir): """Modify the kube config file used with minikube. This function changes the location of the certificates to certs_dir. Args: config_path: The path of the Kubernetes config file. certs_dir: The directory where the certs to use with minikube are stored. """ with open(config_path, "r") as hf: config = yaml.load(hf) for cluster in config["clusters"]: authority = cluster["cluster"]["certificate-authority"] authority = os.path.join(certs_dir, os.path.basename(authority)) cluster["cluster"]["certificate-authority"] = authority for user in config["users"]: for k in ["client-certificate", "client-key"]: user["user"][k] = os.path.join(certs_dir, os.path.basename(user["user"][k])) logging.info("Updating path of certificates in %s", config_path) with open(config_path, "w") as hf: yaml.dump(config, hf) def deploy_minikube(args): """Create a VM and setup minikube.""" credentials = GoogleCredentials.get_application_default() gce = discovery.build( "compute", "v1", credentials=credentials, cache_discovery=False) instances = gce.instances() body = { "name": args.vm_name, "machineType": "zones/{0}/machineTypes/n1-standard-16".format(args.zone), "disks": [ { "boot": True, "initializeParams": { "sourceImage": "projects/ubuntu-os-cloud/global/images/family/ubuntu-1604-lts", "diskSizeGb": 100, "autoDelete": True, }, }, ], "networkInterfaces": [ { "accessConfigs": [ { "name": "external-nat", "type": "ONE_TO_ONE_NAT", }, ], "network": "global/networks/default", }, ], } request = instances.insert(project=args.project, zone=args.zone, body=body) response = None try: response = request.execute() print("done") except errors.HttpError as e: if not e.content: raise content = json.loads(e.content) if content.get("error", {}).get("code") == requests.codes.CONFLICT: # We don't want to keep going so we reraise the error after logging # a helpful error message. logging.error( "Either the VM or the disk %s already exists in zone " "%s in project %s ", args.vm_name, args.zone, args.project) raise else: raise op_id = response.get("name") final_op = vm_util.wait_for_operation(gce, args.project, args.zone, op_id) logging.info("Final result for insert operation: %s", final_op) if final_op.get("status") != "DONE": raise ValueError("Insert operation has status %s", final_op.get("status")) if final_op.get("error"): message = "Insert operation resulted in error %s".format( final_op.get("error")) logging.error(message) raise ValueError(message) # Locate the install minikube script. install_script = os.path.join( os.path.dirname(__file__), "install_minikube.sh") if not os.path.exists(install_script): logging.error("Could not find minikube install script: %s", install_script) vm_util.wait_for_vm(args.project, args.zone, args.vm_name) vm_util.execute_script(args.project, args.zone, args.vm_name, install_script) # Copy the .kube and .minikube files to test_dir target = "~/.kube" full_target = "{0}:{1}".format(args.vm_name, target) logging.info("Copying %s to %s", target, args.test_dir) util.run([ "gcloud", "compute", "--project=" + args.project, "scp", "--recurse", full_target, args.test_dir, "--zone=" + args.zone ]) # The .minikube directory contains some really large ISO and other files that we don't need; so we # only copy the files we need. minikube_dir = os.path.join(args.test_dir, ".minikube") try: os.makedirs(minikube_dir) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(minikube_dir): pass else: raise for target in ["~/.minikube/*.crt", "~/.minikube/client.key"]: full_target = "{0}:{1}".format(args.vm_name, target) logging.info("Copying %s to %s", target, minikube_dir) util.run([ "gcloud", "compute", "--project=" + args.project, "scp", "--recurse", full_target, minikube_dir, "--zone=" + args.zone ]) config_path = os.path.join(args.test_dir, ".kube", "config") modify_minikube_config(config_path, minikube_dir) def teardown_minikube(args): """Delete the VM used for minikube.""" credentials = GoogleCredentials.get_application_default() gce = discovery.build("compute", "v1", credentials=credentials) instances = gce.instances() request = instances.delete( project=args.project, zone=args.zone, instance=args.vm_name) response = request.execute() op_id = response.get("name") final_op = vm_util.wait_for_operation(gce, args.project, args.zone, op_id) logging.info("Final result for delete operation: %s", final_op) if final_op.get("status") != "DONE": raise ValueError("Delete operation has status %s", final_op.get("status")) if final_op.get("error"): message = "Delete operation resulted in error %s".format( final_op.get("error")) logging.error(message) raise ValueError(message) # Ensure the disk is deleted. The disk should be auto-deleted with # the VM but just in case we issue a delete request anyway. disks = gce.disks() request = disks.delete( project=args.project, zone=args.zone, disk=args.vm_name) response = None try: response = request.execute() except errors.HttpError as e: if not e.content: raise content = json.loads(e.content) if content.get("error", {}).get("code") == requests.codes.NOT_FOUND: logging.info("Disk %s in zone %s in project %s already deleted.", args.vm_name, args.zone, args.project) else: raise if response: logging.info("Waiting for disk to be deleted.") op_id = response.get("name") final_op = vm_util.wait_for_operation(gce, args.project, args.zone, op_id) logging.info("Final result for disk delete operation: %s", final_op) if final_op.get("status") != "DONE": raise ValueError("Disk delete operation has status %s", final_op.get("status")) if final_op.get("error"): message = "Delete disk operation resulted in error %s".format( final_op.get("error")) logging.error(message) raise ValueError(message) def get_gcp_identity(): identity = util.run_and_output(["gcloud", "config", "get-value", "account"]) logging.info("Current GCP account: %s", identity) return identity def main(): # pylint: disable=too-many-locals,too-many-statements logging.getLogger().setLevel(logging.INFO) # pylint: disable=too-many-locals # create the top-level parser parser = argparse.ArgumentParser(description="Test Kubeflow E2E.") parser.add_argument( "--test_dir", default="", type=str, help="Directory to use for all the test files. If not set a temporary " "directory is created.") parser.add_argument( "--artifacts_dir", default="", type=str, help="Directory to use for artifacts that should be preserved after " "the test runs. Defaults to test_dir if not set.") parser.add_argument( "--as_gcloud_user", dest="as_gcloud_user", action="store_true", help=("Impersonate the user corresponding to the gcloud " "command with kubectl and ks.")) parser.add_argument( "--no-as_gcloud_user", dest="as_gcloud_user", action="store_false") parser.set_defaults(as_gcloud_user=False) # TODO(jlewi): This should not be a global flag. parser.add_argument( "--project", default=None, type=str, help="The project to use.") # TODO(jlewi): This should not be a global flag. parser.add_argument( "--namespace", default=None, type=str, help=("The namespace to use.")) parser.add_argument( "--github_token", default=None, type=str, help=( "The GitHub API token to use. This is needed since ksonnet uses the " "GitHub API and without it we get rate limited. For more info see: " "https://github.com/ksonnet/ksonnet/blob/master/docs" "/troubleshooting.md. Can also be set using environment variable " "GITHUB_TOKEN.")) parser.add_argument( "--deploy_name", default="", type=str, help="The name of the deployment.") parser.add_argument( "--workflow_name", default="", type=str, help="The name of the workflow.") subparsers = parser.add_subparsers() parser_teardown = subparsers.add_parser( "teardown", help="teardown the test infrastructure.") parser_teardown.set_defaults(func=teardown) parser_tf_serving = subparsers.add_parser( "deploy_model", help="Deploy a TF serving model.") parser_tf_serving.set_defaults(func=deploy_model) parser_tf_serving.add_argument( "--params", default="", type=str, help=("Comma separated list of parameters to set on the model.")) parser_pytorch_job = subparsers.add_parser( "deploy_pytorchjob", help="Deploy a pytorch-job") parser_pytorch_job.set_defaults(func=deploy_pytorchjob) parser_pytorch_job.add_argument( "--params", default="", type=str, help=("Comma separated list of parameters to set on the model.")) parser_argo_job = subparsers.add_parser("deploy_argo", help="Deploy argo") parser_argo_job.set_defaults(func=deploy_argo) parser_katib_test = subparsers.add_parser("test_katib", help="Test Katib") parser_katib_test.set_defaults(func=test_katib) parser_minikube = subparsers.add_parser( "deploy_minikube", help="Setup a K8s cluster on minikube.") parser_minikube.set_defaults(func=deploy_minikube) parser_minikube.add_argument( "--vm_name", required=True, type=str, help="The name of the VM to use.") parser_minikube.add_argument( "--zone", default="us-east1-d", type=str, help="The zone for the cluster.") parser_teardown_minikube = subparsers.add_parser( "teardown_minikube", help="Delete the VM running minikube.") parser_teardown_minikube.set_defaults(func=teardown_minikube) parser_teardown_minikube.add_argument( "--zone", default="us-east1-d", type=str, help="The zone for the cluster.") parser_teardown_minikube.add_argument( "--vm_name", required=True, type=str, help="The name of the VM to use.") args = parser.parse_args() if not args.test_dir: logging.info("--test_dir not set; using a temporary directory.") now = datetime.datetime.now() label = "test_deploy-" + now.strftime("%m%d-%H%M-") + uuid.uuid4().hex[0:4] # Create a temporary directory for this test run args.test_dir = os.path.join(tempfile.gettempdir(), label) if not args.artifacts_dir: args.artifacts_dir = args.test_dir test_log = os.path.join( args.artifacts_dir, "logs", "test_deploy." + args.func.__name__ + args.deploy_name + ".log.txt") try: os.makedirs(os.path.dirname(test_log)) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(os.path.dirname(test_log)): pass else: raise # TODO(jlewi): We should make this a util routine in kubeflow.testing.util # Setup a logging file handler. This way we can upload the log outputs # to gubernator. root_logger = logging.getLogger() file_handler = logging.FileHandler(test_log) root_logger.addHandler(file_handler) # We need to explicitly set the formatter because it will not pick up # the BasicConfig. formatter = logging.Formatter( fmt=("%(levelname)s|%(asctime)s" "|%(pathname)s|%(lineno)d| %(message)s"), datefmt="%Y-%m-%dT%H:%M:%S") file_handler.setFormatter(formatter) logging.info("Logging to %s", test_log) util.run([ks, "version"]) util.maybe_activate_service_account() config_file = os.path.expanduser(kube_config.KUBE_CONFIG_DEFAULT_LOCATION) # Print out the config to help debugging. output = util.run_and_output(["gcloud", "config", "config-helper"]) logging.info("gcloud config: \n%s", output) wrap_test(args) if __name__ == "__main__": logging.basicConfig( level=logging.INFO, format=('%(levelname)s|%(asctime)s' '|%(pathname)s|%(lineno)d| %(message)s'), datefmt='%Y-%m-%dT%H:%M:%S', ) logging.getLogger().setLevel(logging.INFO) main() ================================================ FILE: py/kubeflow/kfctl/testing/test_deploy_test.py ================================================ # -*- coding: utf-8 -*- import tempfile import unittest import yaml from kubeflow.kfctl.testing import test_deploy class TestDeploy(unittest.TestCase): def testModifyMinikubeConfig(self): """Test modeify_minikube_config""" config_path = None with tempfile.NamedTemporaryFile(delete=False) as hf: config_path = hf.name hf.write("""apiVersion: v1 clusters: - cluster: certificate-authority: /home/jlewi/.minikube/ca.crt server: https://10.240.0.18:8443 name: minikube contexts: - context: cluster: minikube user: minikube name: minikube current-context: minikube kind: Config preferences: {} users: - name: minikube user: as-user-extra: {} client-certificate: /home/jlewi/.minikube/client.crt client-key: /home/jlewi/.minikube/client.key """) test_deploy.modify_minikube_config(config_path, "/test/.minikube") # Load the output. with open(config_path) as hf: config = yaml.load(hf) expected = { "apiVersion": "v1", "clusters": [{ "cluster": { "certificate-authority": "/test/.minikube/ca.crt", "server": "https://10.240.0.18:8443" }, "name": "minikube" }], "contexts": [{ "context": { "cluster": "minikube", "user": "minikube" }, "name": "minikube" }], "current-context": "minikube", "kind": "Config", "preferences": {}, "users": [{ "name": "minikube", "user": { "as-user-extra": {}, "client-certificate": "/test/.minikube/client.crt", "client-key": "/test/.minikube/client.key" } }] } self.assertDictEqual(expected, config) if __name__ == "__main__": unittest.main() ================================================ FILE: py/kubeflow/kfctl/testing/util/__init__.py ================================================ ================================================ FILE: py/kubeflow/kfctl/testing/util/application_util.py ================================================ """Utilities for updating various Kubeflow applications.""" import logging import os import pathlib import tempfile from kubeflow.testing import util # pylint: disable=no-name-in-module import yaml def set_kustomize_image(kustomize_file, image_name, image): """Set the image using kustomize. Args: kustomize_file: Path to the kustomize file image_name: The name for the image as defined in the images section of the kustomization file image: New image to set Returns: True if the image was updated and false other wise """ kustomize_dir = os.path.dirname(kustomize_file) with open(kustomize_file) as hf: config = yaml.load(hf) old_image = "" for i in config.get("images"): if i["name"] == image_name: old_image = i.get("newName", image_name) + ":" + i.get("newTag", "") break if old_image == image: logging.info("Not updating %s; image is already %s", kustomize_file, image) return False util.run(["kustomize", "edit", "set", "image", "{0}={1}".format(image_name, image)], cwd=kustomize_dir) return True def regenerate_manifest_tests(manifests_dir): """Regenerate manifest tests Args: manifests_dir: Directory where kubeflow/manifests is checked out """ # See https://github.com/kubeflow/manifests/issues/317 # We can only run make generate under our GOPATH # So first we have to ensure the source code is linked # from our gopath. go_path = os.getenv("GOPATH") if not go_path: raise ValueError("GOPATH not set") parent_dir = os.path.join(go_path, "src", "github.com", "kubeflow") if not os.path.exists(parent_dir): logging.info("Creating directory %s", parent_dir) os.makedirs(parent_dir) else: logging.info("Directory %s already exists", parent_dir) target = os.path.join(parent_dir, "manifests") if os.path.exists(target): logging.info("%s already exists", target) p = pathlib.Path(target) if p.resolve() != pathlib.Path(manifests_dir): raise ValueError("%s exists but doesn't point to %s", target, manifests_dir) else: logging.info("Creating symlink %s -> %s", target, manifests_dir) os.symlink(manifests_dir, target) test_dir = os.path.join(target, "tests") with tempfile.NamedTemporaryFile(delete=False, mode="w") as hf: hf.write("#!/bin/bash\n") hf.write("set -ex\n") hf.write("cd {0}\n".format(test_dir)) hf.write("make generate \n") script = hf.name # TODO(jlewi): This is a weird hack to run make generate for the tests. # make generate needs to be run from ${GOPATH}/src/kubeflow/manifests. # Simply setting cwd doesn't appear to impact the script; probably something # to do with symlinks? So we write a simply script that executes a CD # and then runs make generate. util.run(["bash", script], cwd=os.path.join(target, "tests")) ================================================ FILE: py/kubeflow/kfctl/testing/util/application_util_test.py ================================================ import logging import os import shutil import tempfile import unittest from kubeflow.kfctl.testing.util import application_util from kubeflow.kfctl.testing.ci import update_jupyter_web_app import yaml class ApplicationUttilTest(unittest.TestCase): def test_set_image(self): """Verify that we can set the image""" temp_dir = tempfile.mkdtemp() this_dir = os.path.dirname(__file__) test_app = os.path.join(this_dir, "test_data", "test_app") logging.info("Copying %s to %s", test_app, temp_dir) app_dir = os.path.join(temp_dir, "test_app") shutil.copytree(test_app, app_dir) kustomize_file = os.path.join(app_dir, "kustomization.yaml") image_name = update_jupyter_web_app.JUPYTER_WEB_APP_IMAGE_NAME new_image = "gcr.io/newrepo/newwebapp:1.0" application_util.set_kustomize_image(kustomize_file, image_name, new_image) with open(os.path.join(app_dir, "kustomization.yaml")) as hf: new_config = yaml.load(hf) self.assertEqual(new_config["images"][0]["newName"], "gcr.io/newrepo/newwebapp") self.assertEqual(new_config["images"][0]["newTag"], "1.0") if __name__ == "__main__": logging.getLogger().setLevel(logging.INFO) unittest.main() ================================================ FILE: py/kubeflow/kfctl/testing/util/aws_util.py ================================================ import os import logging from kubeflow.testing import util from kubeflow.testing.cloudprovider.aws import util as aws_util def aws_auth_load_kubeconfig(cluster_name): logging.info("updating ~/.kube/config file of the EKS cluster") util.run(["aws", "eks", "update-kubeconfig", "--name=" + cluster_name]) aws_util.load_kube_config() ================================================ FILE: py/kubeflow/kfctl/testing/util/deploy_utils.py ================================================ # -*- coding: utf-8 -*- import argparse import datetime import json import logging import os import shutil import ssl import tempfile import time import uuid import requests import yaml from googleapiclient import discovery, errors from kubernetes import client as k8s_client from kubernetes.client import rest from kubernetes.config import kube_config from oauth2client.client import GoogleCredentials from kubeflow.testing import test_util, util # pylint: disable=no-name-in-module # noqa: E501 from kubeflow.kfctl.testing.util import vm_util def get_gcp_identity(): identity = util.run(["gcloud", "config", "get-value", "account"]) logging.info("Current GCP account: %s", identity) return identity def create_k8s_client(): # We need to load the kube config so that we can have credentials to # talk to the APIServer. util.load_kube_config(persist_config=False) # Create an API client object to talk to the K8s master. api_client = k8s_client.ApiClient() return api_client def _setup_test(api_client, run_label): """Create the namespace for the test. Returns: test_dir: The local test directory. """ api = k8s_client.CoreV1Api(api_client) namespace = k8s_client.V1Namespace() namespace.api_version = "v1" namespace.kind = "Namespace" namespace.metadata = k8s_client.V1ObjectMeta( name=run_label, labels={ "app": "kubeflow-e2e-test", }) try: logging.info("Creating namespace %s", namespace.metadata.name) namespace = api.create_namespace(namespace) logging.info("Namespace %s created.", namespace.metadata.name) except rest.ApiException as e: if e.status == 409: logging.info("Namespace %s already exists.", namespace.metadata.name) else: raise return namespace def setup_kubeflow_ks_app(dir, namespace, github_token, api_client): """Create a ksonnet app for Kubeflow""" util.makedirs(dir) logging.info("Using test directory: %s", dir) namespace_name = namespace namespace = _setup_test(api_client, namespace_name) logging.info("Using namespace: %s", namespace) if github_token: logging.info("Setting GITHUB_TOKEN to %s.", github_token) # Set a GITHUB_TOKEN so that we don't rate limited by GitHub; # see: https://github.com/ksonnet/ksonnet/issues/233 os.environ["GITHUB_TOKEN"] = github_token if not os.getenv("GITHUB_TOKEN"): logging.warning("GITHUB_TOKEN not set; you will probably hit Github API " "limits.") # Initialize a ksonnet app. app_name = "kubeflow-test-" + uuid.uuid4().hex[0:4] util.run([ "ks", "init", app_name, ], cwd=dir) app_dir = os.path.join(dir, app_name) # Set the default namespace. util.run(["ks", "env", "set", "default", "--namespace=" + namespace_name], cwd=app_dir) kubeflow_registry = "github.com/kubeflow/kubeflow/tree/master/kubeflow" util.run(["ks", "registry", "add", "kubeflow", kubeflow_registry], cwd=app_dir) # Install required packages packages = [ "kubeflow/common", "kubeflow/gcp", "kubeflow/jupyter", "kubeflow/tf-serving", "kubeflow/tf-job", "kubeflow/tf-training", "kubeflow/pytorch-job", "kubeflow/argo", "kubeflow/katib" ] # Instead of installing packages we edit the app.yaml file directly for p in # packages: # util.run(["ks", "pkg", "install", p], cwd=app_dir) app_file = os.path.join(app_dir, "app.yaml") with open(app_file) as f: app_yaml = yaml.load(f) libraries = {} for pkg in packages: pkg = pkg.split("/")[1] libraries[pkg] = { 'gitVersion': { 'commitSha': 'fake', 'refSpec': 'fake' }, 'name': pkg, 'registry': "kubeflow" } app_yaml['libraries'] = libraries with open(app_file, "w") as f: yaml.dump(app_yaml, f) # Create vendor directory with a symlink to the src so that we use the code # at the desired commit. target_dir = os.path.join(app_dir, "vendor", "kubeflow") REPO_ORG = "kubeflow" REPO_NAME = "kubeflow" REGISTRY_PATH = "kubeflow" source = os.path.join(dir, "src", REPO_ORG, REPO_NAME, REGISTRY_PATH) logging.info("Creating link %s -> %s", target_dir, source) os.symlink(source, target_dir) return app_dir def log_operation_status(operation): """A callback to use with wait_for_operation.""" name = operation.get("name", "") status = operation.get("status", "") logging.info("Operation %s status %s", name, status) def wait_for_operation(client, project, op_id, timeout=datetime.timedelta(hours=1), polling_interval=datetime.timedelta(seconds=5), status_callback=log_operation_status): """Wait for the specified operation to complete. Args: client: Client for the API that owns the operation. project: project op_id: Operation id. timeout: A datetime.timedelta expressing the amount of time to wait before giving up. polling_interval: A datetime.timedelta to represent the amount of time to wait between requests polling for the operation status. Returns: op: The final operation. Raises: TimeoutError: if we timeout waiting for the operation to complete. """ endtime = datetime.datetime.now() + timeout while True: try: op = client.operations().get(project=project, operation=op_id).execute() if status_callback: status_callback(op) status = op.get("status", "") # Need to handle other status's if status == "DONE": return op except ssl.SSLError as e: logging.error("Ignoring error %s", e) if datetime.datetime.now() > endtime: raise TimeoutError( "Timed out waiting for op: {0} to complete.".format(op_id)) time.sleep(polling_interval.total_seconds()) # Linter complains if we don't have a return here even though its unreachable return None ================================================ FILE: py/kubeflow/kfctl/testing/util/gcp_util.py ================================================ import datetime import logging import os from time import sleep from google.auth.transport.requests import Request from google.oauth2 import id_token import requests from retrying import retry from requests.exceptions import SSLError from requests.exceptions import ConnectionError as ReqConnectionError COOKIE_NAME = "KUBEFLOW-AUTH-KEY" def may_get_env_var(name): env_val = os.getenv(name) if env_val: logging.info("%s is set", name) return env_val raise Exception("%s not set" % name) # Code copied from: # https://cloud.google.com/iap/docs/authentication-howto#iap_make_request-python def make_iap_request(url, client_id, method='GET', **kwargs): """Makes a request to an application protected by Identity-Aware Proxy. Args: url: The Identity-Aware Proxy-protected URL to fetch. client_id: The client ID used by Identity-Aware Proxy. method: The request method to use ('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE') **kwargs: Any of the parameters defined for the request function: https://github.com/requests/requests/blob/master/requests/api.py If no timeout is provided, it is set to 90 by default. Returns: The page body, or raises an exception if the page couldn't be retrieved. """ # Set the default timeout, if missing if 'timeout' not in kwargs: kwargs['timeout'] = 90 # Obtain an OpenID Connect (OIDC) token from metadata server or using service # account. google_open_id_connect_token = id_token.fetch_id_token(Request(), client_id) # Fetch the Identity-Aware Proxy-protected URL, including an # Authorization header containing "Bearer " followed by a # Google-issued OpenID Connect token for the service account. resp = requests.request( method, url, headers={'Authorization': 'Bearer {}'.format( google_open_id_connect_token)}, **kwargs) if resp.status_code == 403: # pylint: disable=no-else-raise raise Exception('Service account does not have permission to ' 'access the IAP-protected application.') elif resp.status_code != 200: # pylint: disable=no-else-raise raise Exception( 'Bad response from application: {!r} / {!r} / {!r}'.format( resp.status_code, resp.headers, resp.text)) else: return resp.text def iap_is_ready(url, wait_min=15): """ Checks if the kubeflow endpoint is ready. Args: url: The url endpoint Returns: True if the url is ready """ client_id = may_get_env_var("CLIENT_ID") # Wait up to 30 minutes for IAP access test. num_req = 0 end_time = datetime.datetime.now() + datetime.timedelta( minutes=wait_min) while datetime.datetime.now() < end_time: num_req += 1 logging.info("Trying url: %s", url) try: resp = make_iap_request(url, client_id, method="GET", verify=False) logging.info("Response: %s", resp) logging.info("Endpoint is ready for %s!", url) return True except Exception as e: # pylint: disable=broad-except logging.info("%s: Endpoint not ready, exception caught %s, request " "number: %s", url, str(e), num_req) sleep(10) return False def _send_req(wait_sec, url, req_gen, retry_result_code=None): """ Helper function to send requests and retry when the endpoint is not ready. Args: wait_sec: int, max time to wait and retry in seconds. url: str, url to send the request, used only for logging. req_gen: lambda, no parameter function to generate requests.Request for the function to send to the endpoint. retry_result_code: int (optional), status code to match or retry the request. Returns: requests.Response """ def retry_on_error(e): return isinstance(e, (SSLError, ReqConnectionError)) # generates function to see if the request needs to be retried. # if param `code` is None, will not retry and directly pass back the response. # Otherwise will retry if status code is not matched. def retry_on_result_func(code): if code is None: return lambda _: False return lambda resp: not resp or resp.status_code != code @retry(stop_max_delay=wait_sec * 1000, wait_fixed=10 * 1000, retry_on_exception=retry_on_error, retry_on_result=retry_on_result_func(retry_result_code)) def _send(url, req_gen): resp = None logging.info("sending request to %s", url) try: resp = req_gen() except Exception as e: logging.warning("%s: request with error: %s", url, e) raise e return resp return _send(url, req_gen) # TODO(jlewi): basic_auth is no longer supported so we could probably # delete this code path. def basic_auth_is_ready(url, username, password, wait_min=15): get_url = url + "/kflogin" post_url = url + "/apikflogin" end_time = datetime.datetime.now() + datetime.timedelta( minutes=wait_min) wait_time = datetime.datetime.now() - end_time resp = _send_req(wait_time.seconds, get_url, lambda: requests.request( "GET", get_url, verify=False), retry_result_code=200) logging.info("%s: endpoint is ready; response: %s", get_url, resp.text) logging.info("%s: testing login API", post_url) wait_time = datetime.datetime.now() - end_time resp = _send_req(wait_time.seconds, post_url, lambda: requests.post( post_url, auth=(username, password), headers={ "x-from-login": "true", }, verify=False)) logging.info("%s: %s", post_url, resp.text) if resp.status_code != 205: logging.error("%s: login is failed", post_url) return False logging.info("%s: testing cookies credentials", url) cookie = None for c in resp.cookies: if c.name == COOKIE_NAME: cookie = c break if cookie is None: logging.error("%s: auth cookie cannot be found; name: %s", post_url, COOKIE_NAME) return False wait_time = datetime.datetime.now() - end_time resp = _send_req(wait_time.seconds, url, lambda: requests.get( url, cookies={ cookie.name: cookie.value, }, verify=False)) logging.info("%s: %s", url, resp.status_code) logging.info(resp.content) return resp.status_code == 200 ================================================ FILE: py/kubeflow/kfctl/testing/util/kfctl_go_test_utils.py ================================================ """Common reusable steps for kfctl go testing.""" import datetime import json import logging import os import tempfile import urllib import uuid import requests import yaml from kubeflow.testing import util from kubeflow.testing.cloudprovider.aws import util as aws_util from kubeflow.kfctl.testing.util import aws_util as kfctl_aws_util from kubeflow.testing.cloudprovider.aws import prow_artifacts as aws_prow_artifacts from retrying import retry # retry 4 times, waiting 3 minutes between retries @retry(stop_max_attempt_number=4, wait_fixed=180000) def run_with_retries(*args, **kwargs): util.run(*args, **kwargs) def build_kfctl_go(kfctl_repo_path): """build the kfctl go binary and return the path for the same. Args: kfctl_repo_path (str): Path to kfctl repo. Return: kfctl_path (str): Path where kfctl go binary has been built. will be Kubeflow/kubeflow/bootstrap/bin/kfctl """ kfctl_path = os.path.join(kfctl_repo_path, "bin", "kfctl") # We need to use retry builds because when building in the test cluster # we see intermittent failures pulling dependencies run_with_retries(["make", "build-kfctl"], cwd=kfctl_repo_path) return kfctl_path def get_or_create_app_path_and_parent_dir(app_path): """Get a valid app_path and parent dir. Create if they are not existing. """ if not app_path: logging.info("--app_path not specified") stamp = datetime.datetime.now().strftime("%H%M") parent_dir = tempfile.gettempdir() app_path = os.path.join( parent_dir, "kfctl-{0}-{1}".format(stamp, uuid.uuid4().hex[0:4])) else: parent_dir = os.path.dirname(app_path) if not os.path.exists(parent_dir): os.makedirs(parent_dir) if not os.path.exists(app_path): os.makedirs(app_path) return app_path, parent_dir def load_config(config_path): """Load specified KFDef. Args: config_path: Path to a YAML file containing a KFDef object. Can be a local path or a URI like https://raw.githubusercontent.com/kubeflow/manifests/master/kfdef/kfctl_gcp_iap.yaml Returns: config_spec: KfDef spec """ url_for_spec = urllib.parse.urlparse(config_path) if url_for_spec.scheme in ["http", "https"]: data = requests.get(config_path) return yaml.load(data.content) else: with open(config_path, 'r') as f: config_spec = yaml.load(f) return config_spec def set_env_for_auth(use_basic_auth): logging.info("use_basic_auth=%s", use_basic_auth) # Set ENV for basic auth username/password. if use_basic_auth: # Don't log the password. # logging.info("Setting environment variables KUBEFLOW_USERNAME and KUBEFLOW_PASSWORD") os.environ["KUBEFLOW_USERNAME"] = "kf-test-user" os.environ["KUBEFLOW_PASSWORD"] = str(uuid.uuid4().hex) else: # Owned by project kubeflow-ci-deployment. logging.info("Setting environment variables CLIENT_SECRET and CLIENT_ID") os.environ["CLIENT_SECRET"] = "CJ4qVPLTi0j0GJMkONj7Quwt" os.environ["CLIENT_ID"] = ( "29647740582-7meo6c7a9a76jvg54j0g2lv8lrsb4l8g" ".apps.googleusercontent.com") def set_env_init_args(config_spec): gcp_plugin = {} for plugin in config_spec.get("spec", {}).get("plugins", []): if plugin.get("kind", "") == "KfGcpPlugin": gcp_plugin = plugin break use_basic_auth = gcp_plugin.get("spec", {}).get("useBasicAuth", False) set_env_for_auth(use_basic_auth) def write_basic_auth_login(filename): """Read basic auth login from ENV and write to the filename given. If username/password cannot be found in ENV, this function will silently return. Args: filename: The filename (directory/file name) the login is writing to. """ username = os.environ.get("KUBEFLOW_USERNAME", "") password = os.environ.get("KUBEFLOW_PASSWORD", "") if not username or not password: return with open(filename, "w") as f: login = { "username": username, "password": password, } json.dump(login, f) def filter_spartakus(spec): """Filter our Spartakus from KfDef spec. Args: spec: KfDef spec Returns: spec: Filtered KfDef spec """ for i, app in enumerate(spec["applications"]): if app["name"] == "spartakus": spec["applications"].pop(i) break return spec def get_config_spec(config_path, app_path, cluster_name): """Generate KfDef spec. Args: config_path: Path to a YAML file containing a KFDef object. Can be a local path or a URI like https://raw.githubusercontent.com/kubeflow/manifests/master/kfdef/kfctl_gcp_iap.yaml app_path: The path to the Kubeflow app. cluster_name: Name of EKS cluster Returns: config_spec: Updated KfDef spec """ # TODO(https://github.com/kubeflow/kubeflow/issues/2831): Once kfctl # supports loading version from a URI we should use that so that we # pull the configs from the repo we checked out. config_spec = load_config(config_path) repos = config_spec["spec"]["repos"] manifests_repo_name = "manifests" if os.getenv("REPO_NAME") == manifests_repo_name: # kfctl_go_test.py was triggered on presubmit from the kubeflow/manifests # repository. In this case we want to use the specified PR of the # kubeflow/manifests repository; so we need to change the repo specification # in the KFDef spec. # TODO(jlewi): We should also point to a specific commit when triggering # postsubmits from the kubeflow/manifests repo for repo in repos: if repo["name"] != manifests_repo_name: continue version = None if os.getenv("PULL_PULL_SHA"): # Presubmit version = os.getenv("PULL_PULL_SHA") # See https://github.com/kubernetes/test-infra/blob/45246b09ed105698aa8fb928b7736d14480def29/prow/jobs.md#job-environment-variables # pylint: disable=line-too-long elif os.getenv("PULL_BASE_SHA"): version = os.getenv("PULL_BASE_SHA") if version: repo["uri"] = ("https://github.com/kubeflow/manifests/archive/" "{0}.tar.gz").format(version) logging.info("Overwriting the URI") else: # Its a periodic job so use whatever value is set in the KFDef logging.info("Not overwriting manifests version") logging.info(str(config_spec)) return config_spec def kfctl_deploy_kubeflow(app_path, config_path, kfctl_path, build_and_apply, cluster_name): """Deploy kubeflow. Args: app_path: The path to the Kubeflow app. config_path: Path to the KFDef spec file. kfctl_path: Path to the kfctl go binary build_and_apply: whether to build and apply or apply cluster_name: Name of EKS cluster Returns: app_path: Path where Kubeflow is installed """ # build_and_apply is a boolean used for testing both the new semantics # test case 1: build_and_apply # kfctl build -f # kfctl apply # test case 2: apply # kfctl apply -f kfctl_aws_util.aws_auth_load_kubeconfig(cluster_name) if not os.path.exists(kfctl_path): msg = "kfctl Go binary not found: {path}".format(path=kfctl_path) logging.error(msg) raise RuntimeError(msg) app_path, parent_dir = get_or_create_app_path_and_parent_dir(app_path) logging.info("app path %s", app_path) logging.info("kfctl path %s", kfctl_path) config_spec = get_config_spec(config_path, app_path, cluster_name) with open(os.path.join(app_path, "tmp.yaml"), "w") as f: yaml.dump(config_spec, f) # build_and_apply logging.info("running kfctl with build and apply: %s \n", build_and_apply) logging.info("switching working directory to: %s \n", app_path) os.chdir(app_path) # push newly built kfctl to S3 push_kfctl_to_s3(kfctl_path) # Workaround to fix issue # msg="Encountered error applying application bootstrap: (kubeflow.error): Code 500 with message: Apply.Run # : error when creating \"/tmp/kout927048001\": namespaces \"kubeflow-test-infra\" not found" # filename="kustomize/kustomize.go:266" # TODO(PatrickXYS): fix the issue permanentely rather than work-around util.run(["kubectl", "create", "namespace", "kubeflow-test-infra"]) # Do not run with retries since it masks errors logging.info("Running kfctl with config:\n%s", yaml.safe_dump(config_spec)) if build_and_apply: build_and_apply_kubeflow(kfctl_path, app_path) else: apply_kubeflow(kfctl_path, app_path) return app_path def push_kfctl_to_s3(kfctl_path): bucket = aws_prow_artifacts.AWS_PROW_RESULTS_BUCKET logging.info("Bucket name: %s", aws_prow_artifacts.get_s3_dir(bucket)) s3_path = os.path.join(aws_prow_artifacts.get_s3_dir(bucket) + "/artifacts/build_bin/kfctl") aws_util.upload_file_to_s3(kfctl_path, s3_path) def apply_kubeflow(kfctl_path, app_path): util.run([kfctl_path, "apply", "-V", "-f=" + os.path.join(app_path, "tmp.yaml")], cwd=app_path) return app_path def build_and_apply_kubeflow(kfctl_path, app_path): util.run([kfctl_path, "build", "-V", "-f=" + os.path.join(app_path, "tmp.yaml")], cwd=app_path) util.run([kfctl_path, "apply", "-V", "-f=" + os.path.join(app_path, "tmp.yaml")], cwd=app_path) return app_path def upgrade_kubeflow(kfctl_path, parent_dir): util.run([kfctl_path, "apply", "-V", "-f=" + os.path.join(parent_dir, "upgrade.yaml")], cwd=parent_dir) def verify_kubeconfig(app_path): """Verify kubeconfig. Args: app_path: KfDef spec path """ name = os.path.basename(app_path) context = util.run(["kubectl", "config", "current-context"]).strip() if name == context: logging.info("KUBECONFIG current context name matches app name: %s", name) else: msg = "KUBECONFIG not having expected context: {expected} v.s. {actual}".format( expected=name, actual=context) logging.error(msg) raise RuntimeError(msg) def kfctl_upgrade_kubeflow(app_path, kfctl_path, upgrade_spec_path, use_basic_auth=False): """Upgrade kubeflow. Args: app_path: The path to the Kubeflow app to be upgraded. kfctl_path: The path to the kfctl binary. upgrade_spec_path: The path to the upgrade sepc. use_basic_auth: True if we are using basic auth for GCP. """ if not os.path.exists(kfctl_path): msg = "kfctl Go binary not found: {path}".format(path=kfctl_path) logging.error(msg) raise RuntimeError(msg) app_path, parent_dir = get_or_create_app_path_and_parent_dir(app_path) app_name = os.path.basename(app_path) logging.info("app path %s", app_path) logging.info("app name %s", app_name) logging.info("parent dir %s", parent_dir) logging.info("kfctl path %s", kfctl_path) upgrade_spec = load_config(upgrade_spec_path) upgrade_spec["spec"]["currentKfDef"]["name"] = app_name upgrade_spec["spec"]["newKfDef"]["name"] = app_name with open(os.path.join(parent_dir, "upgrade.yaml"), "w") as f: yaml.dump(upgrade_spec, f) # Set ENV for credentials IAP/basic auth needs. set_env_for_auth(use_basic_auth) # Write basic auth login username/password to a file for later tests. # If the ENVs are not set, this function call will be noop. write_basic_auth_login(os.path.join(app_path, "login.json")) logging.info("switching working directory to: %s \n", parent_dir) os.chdir(parent_dir) # Run upgrade logging.info("Running kfctl with upgrade spec:\n%s", yaml.safe_dump(upgrade_spec)) upgrade_kubeflow(kfctl_path, parent_dir) ================================================ FILE: py/kubeflow/kfctl/testing/util/run_with_retry.py ================================================ # -*- coding: utf-8 -*- """ run_with_retry runs the given binary with the given number of retries This is intended primary for retrying bash scripts. Ideally, we sould use argo's retryStrategy, but there is a bug in it's implementation: https://github.com/argoproj/argo/issues/885 Example: python run_with_retry --retries=5 -- bash my_flaky_script.sh This runs bash my_flaky_script.sh upto 5 times till it succeeds """ import argparse from kubeflow.testing import test_helper, util from retrying import retry def parse_args(): parser = argparse.ArgumentParser() parser.add_argument( "--retries", required=True, type=int, help="The number of retries.") parser.add_argument('remaining_args', nargs=argparse.REMAINDER) args, _ = parser.parse_known_args() return args def run_with_retry(_): """Deploy Kubeflow.""" args = parse_args() @retry(stop_max_attempt_number=args.retries) def run(): util.run(args.remaining_args[1:]) run() def main(): test_case = test_helper.TestCase( name='run_with_retry', test_func=run_with_retry) test_suite = test_helper.init(name='run_with_retry', test_cases=[test_case]) test_suite.run() if __name__ == "__main__": main() ================================================ FILE: py/kubeflow/kfctl/testing/util/vm_util.py ================================================ # -*- coding: utf-8 -*- """Utilities for working with VMs as part of our tests.""" import datetime import logging import os import socket import ssl import subprocess import time import uuid from kubeflow.testing import util # TODO(jlewi): Should we move this to kubeflow/testing def wait_for_operation(client, project, zone, op_id, timeout=datetime.timedelta(hours=1), polling_interval=datetime.timedelta(seconds=5)): """ Wait for the specified operation to complete. Args: client: Client for the API that owns the operation. project: project zone: Zone. Set to none if its a global operation op_id: Operation id/name. timeout: A datetime.timedelta expressing the amount of time to wait before giving up. polling_interval: A datetime.timedelta to represent the amount of time to wait between requests polling for the operation status. Returns: op: The final operation. Raises: TimeoutError: if we timeout waiting for the operation to complete. """ endtime = datetime.datetime.now() + timeout while True: try: if zone: op = client.zoneOperations().get( project=project, zone=zone, operation=op_id).execute() else: op = client.globalOperations().get( project=project, operation=op_id).execute() except socket.error as e: logging.error("Ignoring error %s", e) continue except ssl.SSLError as e: logging.error("Ignoring error %s", e) continue status = op.get("status", "") # Need to handle other status's if status == "DONE": return op if datetime.datetime.now() > endtime: raise TimeoutError( "Timed out waiting for op: {0} to complete.".format(op_id)) time.sleep(polling_interval.total_seconds()) def wait_for_vm(project, zone, vm, timeout=datetime.timedelta(minutes=5), polling_interval=datetime.timedelta(seconds=10)): """ Wait for the VM to be ready. This is measured by trying to ssh into the VM timeout: A datetime.timedelta expressing the amount of time to wait before giving up. polling_interval: A datetime.timedelta to represent the amount of time to wait between requests polling for the operation status. Raises: TimeoutError: if we timeout waiting for the operation to complete. """ endtime = datetime.datetime.now() + timeout while True: try: util.run([ "gcloud", "compute", "--project=" + project, "ssh", "--zone=" + zone, vm, "--", "echo hello world" ]) logging.info("VM is ready") return except subprocess.CalledProcessError: pass if datetime.datetime.now() > endtime: raise util.TimeoutError( ("Timed out waiting for VM to {0} be sshable. Check firewall" "rules aren't blocking ssh.").format(vm)) time.sleep(polling_interval.total_seconds()) def execute(project, zone, vm, commands): """Execute the supplied commands on the VM.""" util.run([ "gcloud", "compute", "--project=" + project, "ssh", "--zone=" + zone, vm, "--", " && ".join(commands) ]) def execute_script(project, zone, vm, script): """Execute the specified script on the VM.""" target_path = os.path.join( "/tmp", os.path.basename(script) + "." + uuid.uuid4().hex[0:4]) target = "{0}:{1}".format(vm, target_path) logging.info("Copying %s to %s", script, target) util.run([ "gcloud", "compute", "--project=" + project, "scp", script, target, "--zone=" + zone ]) util.run([ "gcloud", "compute", "--project=" + project, "ssh", "--zone=" + zone, vm, "--", "chmod a+rx " + target_path + " && " + target_path ]) ================================================ FILE: third_party/README.md ================================================ This folder contains all licenses and source code of third-party dependencies for distributing kfctl tools. For any dependency changes, please follow [this instruction](https://github.com/kubeflow/testing/blob/master/py/kubeflow/testing/go-license-tools/README.md) to update the content of this folder. - `dep.txt` contains third party Go dependencies based `go.mod`. - `license.txt` contains all license content of dependencies. - `license_info.csv` contains license URLs. ================================================ FILE: third_party/check-license.sh ================================================ #!/usr/bin/env bash set -ex # Copyright 2018 The Kubeflow Authors All rights reserved. # # 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. # Script to autoformat libsonnet files. # Assumes jsonnet is on the path. go list -m all | cut -d ' ' -f 1 > /tmp/generated_dep.txt cd third_party if ! diff /tmp/generated_dep.txt dep.txt; then echo "Please update the license file for changed dependencies." exit 1 fi python3 concatenate_license.py --output=/tmp/generated_license.txt if ! diff /tmp/generated_license.txt license.txt; then echo "Please regenerate third_party/license.txt." exit 1 fi ================================================ FILE: third_party/concatenate_license.py ================================================ # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import argparse import requests import sys import traceback parser = argparse.ArgumentParser( description='Generate dependencies json from license.csv file.') parser.add_argument( 'license_info_file', nargs='?', default='license_info.csv', help='CSV file with license info fetched from github using get-github-license-info CLI tool.' +'(default: %(default)s)', ) parser.add_argument( '-o', '--output', dest='output_file', nargs='?', default='license.txt', help= 'Concatenated license file path this command generates. (default: %(default)s)' ) args = parser.parse_args() def fetch_license_text(download_link): response = requests.get(download_link) assert response.ok, 'Fetching {} failed with {} {}'.format( download_link, response.status_code, response.reason) return response.text def main(): with open(args.license_info_file, 'r') as license_info_file, open(args.output_file, 'w') as output_file: repo_failed = [] for line in license_info_file: line = line.strip() [repo, license_link, license_name, license_download_link] = line.split(',') try: print('Repo {} has license download link {}'.format( repo, license_download_link), file=sys.stderr) license_text = fetch_license_text(license_download_link) print( '--------------------------------------------------------------------------------', file=output_file, ) print('{} {} {}'.format(repo, license_name, license_link), file=output_file) print( '--------------------------------------------------------------------------------', file=output_file, ) print(license_text, file=output_file) except Exception as e: # pylint: disable=broad-except print('[failed]', e, file=sys.stderr) traceback.print_exc(file=sys.stderr) repo_failed.append(repo) print('Failed to download license file for {} repos.'.format(len(repo_failed)), file=sys.stderr) for repo in repo_failed: print(repo, file=sys.stderr) main() ================================================ FILE: third_party/dep.txt ================================================ github.com/kubeflow/kfctl/v3 bitbucket.org/bertimus9/systemstat cloud.google.com/go github.com/Azure/azure-sdk-for-go github.com/Azure/go-ansiterm github.com/Azure/go-autorest github.com/BurntSushi/toml github.com/BurntSushi/xgb github.com/GoogleCloudPlatform/k8s-cloud-provider github.com/JeffAshton/win_pdh github.com/MakeNowJust/heredoc github.com/Microsoft/go-winio github.com/Microsoft/hcsshim github.com/NYTimes/gziphandler github.com/PuerkitoBio/purell github.com/PuerkitoBio/urlesc github.com/Rican7/retry github.com/Sirupsen/logrus github.com/alecthomas/template github.com/alecthomas/units github.com/armon/circbuf github.com/armon/consul-api github.com/asaskevich/govalidator github.com/auth0/go-jwt-middleware github.com/aws/aws-sdk-go github.com/bazelbuild/bazel-gazelle github.com/bazelbuild/buildtools github.com/beorn7/perks github.com/bgentry/go-netrc github.com/blang/semver github.com/boltdb/bolt github.com/cenkalti/backoff github.com/cespare/prettybench github.com/chai2010/gettext-go github.com/cheggaaa/pb github.com/client9/misspell github.com/cloudflare/cfssl github.com/clusterhq/flocker-go github.com/codedellemc/goscaleio github.com/codegangsta/negroni github.com/container-storage-interface/spec github.com/containerd/console github.com/containerd/containerd github.com/containerd/typeurl github.com/containernetworking/cni github.com/coreos/bbolt github.com/coreos/etcd github.com/coreos/go-etcd github.com/coreos/go-oidc github.com/coreos/go-semver github.com/coreos/go-systemd github.com/coreos/pkg github.com/coreos/rkt github.com/cpuguy83/go-md2man github.com/cyphar/filepath-securejoin github.com/d2g/dhcp4 github.com/d2g/dhcp4client github.com/davecgh/go-spew github.com/daviddengcn/go-colortext github.com/deckarep/golang-set github.com/dgrijalva/jwt-go github.com/dnaeon/go-vcr github.com/docker/distribution github.com/docker/docker github.com/docker/go-connections github.com/docker/go-units github.com/docker/libnetwork github.com/docker/spdystream github.com/elazarl/goproxy github.com/elazarl/goproxy/ext github.com/emicklei/go-restful github.com/euank/go-kmsg-parser github.com/evanphx/json-patch github.com/exponent-io/jsonpath github.com/fatih/camelcase github.com/fatih/color github.com/fsnotify/fsnotify github.com/ghodss/yaml github.com/globalsign/mgo github.com/go-kit/kit github.com/go-logfmt/logfmt github.com/go-logr/logr github.com/go-logr/zapr github.com/go-openapi/analysis github.com/go-openapi/errors github.com/go-openapi/jsonpointer github.com/go-openapi/jsonreference github.com/go-openapi/loads github.com/go-openapi/runtime github.com/go-openapi/spec github.com/go-openapi/strfmt github.com/go-openapi/swag github.com/go-openapi/validate github.com/go-ozzo/ozzo-validation github.com/go-stack/stack github.com/godbus/dbus github.com/gogo/protobuf github.com/golang/glog github.com/golang/groupcache github.com/golang/mock github.com/golang/protobuf github.com/golangplus/bytes github.com/golangplus/fmt github.com/golangplus/testing github.com/google/btree github.com/google/cadvisor github.com/google/certificate-transparency-go github.com/google/go-cmp github.com/google/gofuzz github.com/google/martian github.com/google/pprof github.com/google/renameio github.com/google/uuid github.com/googleapis/gax-go/v2 github.com/googleapis/gnostic github.com/gophercloud/gophercloud github.com/gopherjs/gopherjs github.com/gorilla/context github.com/gorilla/mux github.com/gorilla/websocket github.com/gregjones/httpcache github.com/grpc-ecosystem/go-grpc-middleware github.com/grpc-ecosystem/go-grpc-prometheus github.com/grpc-ecosystem/grpc-gateway github.com/hashicorp/go-cleanhttp github.com/hashicorp/go-getter github.com/hashicorp/go-safetemp github.com/hashicorp/go-version github.com/hashicorp/golang-lru github.com/hashicorp/hcl github.com/heketi/heketi github.com/heketi/rest github.com/heketi/tests github.com/heketi/utils github.com/hpcloud/tail github.com/imdario/mergo github.com/inconshreveable/mousetrap github.com/jmespath/go-jmespath github.com/jonboulle/clockwork github.com/json-iterator/go github.com/jstemmer/go-junit-report github.com/jteeuwen/go-bindata github.com/jtolds/gls github.com/julienschmidt/httprouter github.com/kardianos/osext github.com/karrick/godirwalk github.com/kisielk/errcheck github.com/kisielk/gotool github.com/konsorten/go-windows-terminal-sequences github.com/kr/fs github.com/kr/logfmt github.com/kr/pretty github.com/kr/pty github.com/kr/text github.com/kubernetes-sigs/application github.com/libopenstorage/openstorage github.com/liggitt/tabwriter github.com/lithammer/dedent github.com/lpabon/godbc github.com/magiconair/properties github.com/mailru/easyjson github.com/marstr/guid github.com/mattn/go-colorable github.com/mattn/go-isatty github.com/mattn/go-runewidth github.com/mattn/go-shellwords github.com/matttproud/golang_protobuf_extensions github.com/mesos/mesos-go github.com/mholt/caddy github.com/miekg/dns github.com/mindprince/gonvml github.com/mistifyio/go-zfs github.com/mitchellh/go-homedir github.com/mitchellh/go-testing-interface github.com/mitchellh/go-wordwrap github.com/mitchellh/mapstructure github.com/modern-go/concurrent github.com/modern-go/reflect2 github.com/mohae/deepcopy github.com/morikuni/aec github.com/mrunalp/fileutils github.com/munnerz/goautoneg github.com/mvdan/xurls github.com/mwitkow/go-conntrack github.com/mxk/go-flowrate github.com/natefinch/lumberjack github.com/onrik/logrus github.com/onsi/ginkgo github.com/onsi/gomega github.com/opencontainers/go-digest github.com/opencontainers/image-spec github.com/opencontainers/runc github.com/opencontainers/runtime-spec github.com/opencontainers/selinux github.com/otiai10/copy github.com/otiai10/curr github.com/otiai10/mint github.com/pborman/uuid github.com/pelletier/go-toml github.com/peterbourgon/diskv github.com/pkg/errors github.com/pkg/sftp github.com/pmezard/go-difflib github.com/pquerna/cachecontrol github.com/pquerna/ffjson github.com/prometheus/client_golang github.com/prometheus/client_model github.com/prometheus/common github.com/prometheus/procfs github.com/quobyte/api github.com/remyoudompheng/bigfft github.com/robfig/cron github.com/rogpeppe/go-charset github.com/rogpeppe/go-internal github.com/rubiojr/go-vhd github.com/russross/blackfriday github.com/satori/go.uuid github.com/seccomp/libseccomp-golang github.com/shurcooL/sanitized_anchor_name github.com/sigma/go-inotify github.com/sirupsen/logrus github.com/smartystreets/assertions github.com/smartystreets/goconvey github.com/soheilhy/cmux github.com/spf13/afero github.com/spf13/cast github.com/spf13/cobra github.com/spf13/jwalterweatherman github.com/spf13/pflag github.com/spf13/viper github.com/storageos/go-api github.com/stretchr/objx github.com/stretchr/testify github.com/syndtr/gocapability github.com/tmc/grpc-websocket-proxy github.com/ugorji/go/codec github.com/ulikunitz/xz github.com/urfave/negroni github.com/vishvananda/netlink github.com/vishvananda/netns github.com/vmware/govmomi github.com/vmware/photon-controller-go-sdk github.com/xanzy/go-cloudstack github.com/xiang90/probing github.com/xlab/handysort github.com/xordataexchange/crypt go.opencensus.io go.uber.org/atomic go.uber.org/multierr go.uber.org/tools go.uber.org/zap golang.org/x/crypto golang.org/x/exp golang.org/x/image golang.org/x/lint golang.org/x/mobile golang.org/x/mod golang.org/x/net golang.org/x/oauth2 golang.org/x/sync golang.org/x/sys golang.org/x/text golang.org/x/time golang.org/x/tools golang.org/x/xerrors gomodules.xyz/jsonpatch/v2 gonum.org/v1/gonum gonum.org/v1/netlib google.golang.org/api google.golang.org/appengine google.golang.org/genproto google.golang.org/grpc gopkg.in/airbrake/gobrake.v2 gopkg.in/alecthomas/kingpin.v2 gopkg.in/check.v1 gopkg.in/cheggaaa/pb.v1 gopkg.in/errgo.v2 gopkg.in/fsnotify.v1 gopkg.in/gcfg.v1 gopkg.in/gemnasium/logrus-airbrake-hook.v2 gopkg.in/inf.v0 gopkg.in/natefinch/lumberjack.v2 gopkg.in/square/go-jose.v2 gopkg.in/tomb.v1 gopkg.in/warnings.v0 gopkg.in/yaml.v1 gopkg.in/yaml.v2 gotest.tools honnef.co/go/tools k8s.io/api k8s.io/apiextensions-apiserver k8s.io/apimachinery k8s.io/apiserver k8s.io/cli-runtime k8s.io/client-go k8s.io/cloud-provider k8s.io/cluster-bootstrap k8s.io/code-generator k8s.io/component-base k8s.io/cri-api k8s.io/csi-translation-lib k8s.io/gengo k8s.io/heapster k8s.io/klog k8s.io/kube-aggregator k8s.io/kube-controller-manager k8s.io/kube-openapi k8s.io/kube-proxy k8s.io/kube-scheduler k8s.io/kubelet k8s.io/kubernetes k8s.io/legacy-cloud-providers k8s.io/metrics k8s.io/repo-infra k8s.io/sample-apiserver k8s.io/utils modernc.org/cc modernc.org/golex modernc.org/mathutil modernc.org/strutil modernc.org/xc sigs.k8s.io/controller-runtime sigs.k8s.io/kustomize sigs.k8s.io/kustomize/v3 sigs.k8s.io/structured-merge-diff sigs.k8s.io/testing_frameworks sigs.k8s.io/yaml vbom.ml/util ================================================ FILE: third_party/dep_repo.manual.csv ================================================ gomodules.xyz/jsonpatch/v2,gomodules/jsonpatch honnef.co/go/tools,dominikh/go-tools k8s.io/repo-infra,kubernetes/repo-infra sigs.k8s.io/kustomize/v3,kubernetes-sigs/kustomize ================================================ FILE: third_party/license.txt ================================================ -------------------------------------------------------------------------------- kubeflow/kfctl Apache License 2.0 https://github.com/kubeflow/kfctl/blob/master/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. -------------------------------------------------------------------------------- GoogleCloudPlatform/gcloud-golang Apache License 2.0 https://github.com/googleapis/google-cloud-go/blob/master/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. -------------------------------------------------------------------------------- Azure/azure-sdk-for-go Apache License 2.0 https://github.com/Azure/azure-sdk-for-go/blob/master/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 2016 Microsoft Corporation 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. -------------------------------------------------------------------------------- Azure/go-ansiterm MIT License https://github.com/Azure/go-ansiterm/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Microsoft Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Azure/go-autorest Apache License 2.0 https://github.com/Azure/go-autorest/blob/master/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 Copyright 2015 Microsoft Corporation 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. -------------------------------------------------------------------------------- BurntSushi/toml MIT License https://github.com/BurntSushi/toml/blob/master/COPYING -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 TOML authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- BurntSushi/xgb BSD 3-Clause "New" or "Revised" License https://github.com/BurntSushi/xgb/blob/master/LICENSE -------------------------------------------------------------------------------- // Copyright (c) 2009 The XGB Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Subject to the terms and conditions of this License, Google 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 this implementation of XGB, where such license // applies only to those patent claims licensable by Google that are // necessarily infringed by use of this implementation of XGB. If You // institute patent litigation against any entity (including a // cross-claim or counterclaim in a lawsuit) alleging that this // implementation of XGB or a Contribution incorporated within this // implementation of XGB constitutes direct or contributory patent // infringement, then any patent licenses granted to You under this // License for this implementation of XGB shall terminate as of the date // such litigation is filed. -------------------------------------------------------------------------------- GoogleCloudPlatform/k8s-cloud-provider Apache License 2.0 https://github.com/GoogleCloudPlatform/k8s-cloud-provider/blob/master/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. -------------------------------------------------------------------------------- JeffAshton/win_pdh BSD 3-Clause "New" or "Revised" License https://github.com/JeffAshton/win_pdh/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2010 The win_pdh Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- MakeNowJust/heredoc MIT License https://github.com/MakeNowJust/heredoc/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014-2019 TSUYUSATO Kitsune Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Microsoft/go-winio MIT License https://github.com/microsoft/go-winio/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Microsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Microsoft/hcsshim MIT License https://github.com/microsoft/hcsshim/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Microsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- NYTimes/gziphandler Apache License 2.0 https://github.com/nytimes/gziphandler/blob/master/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 2016-2017 The New York Times Company 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. -------------------------------------------------------------------------------- PuerkitoBio/purell BSD 3-Clause "New" or "Revised" License https://github.com/PuerkitoBio/purell/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012, Martin Angers All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- PuerkitoBio/urlesc BSD 3-Clause "New" or "Revised" License https://github.com/PuerkitoBio/urlesc/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Rican7/retry MIT License https://github.com/Rican7/retry/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (C) 2016 Trevor N. Suarez (Rican7) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Sirupsen/logrus MIT License https://github.com/sirupsen/logrus/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Simon Eskildsen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- alecthomas/template BSD 3-Clause "New" or "Revised" License https://github.com/alecthomas/template/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- alecthomas/units MIT License https://github.com/alecthomas/units/blob/master/COPYING -------------------------------------------------------------------------------- Copyright (C) 2014 Alec Thomas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- appscode/jsonpatch Apache License 2.0 https://github.com/gomodules/jsonpatch/blob/master/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. -------------------------------------------------------------------------------- armon/circbuf MIT License https://github.com/armon/circbuf/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 Armon Dadgar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- armon/consul-api Mozilla Public License 2.0 https://github.com/armon/consul-api/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- asaskevich/govalidator MIT License https://github.com/asaskevich/govalidator/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Alex Saskevich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- auth0/go-jwt-middleware MIT License https://github.com/auth0/go-jwt-middleware/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Auth0, Inc. (http://auth0.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- aws/aws-sdk-go Apache License 2.0 https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt -------------------------------------------------------------------------------- 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. -------------------------------------------------------------------------------- bazelbuild/bazel-gazelle Apache License 2.0 https://github.com/bazelbuild/bazel-gazelle/blob/master/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. -------------------------------------------------------------------------------- bazelbuild/buildtools Apache License 2.0 https://github.com/bazelbuild/buildtools/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2016 Google Inc. All Rights Reserved. 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. -------------------------------------------------------------------------------- beorn7/perks MIT License https://github.com/beorn7/perks/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (C) 2013 Blake Mizerany Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- bgentry/go-netrc MIT License https://github.com/bgentry/go-netrc/blob/master/LICENSE -------------------------------------------------------------------------------- Original version Copyright © 2010 Fazlul Shahriar . Newer portions Copyright © 2014 Blake Gentry . Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- blang/semver MIT License https://github.com/blang/semver/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License Copyright (c) 2014 Benedikt Lang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- boltdb/bolt MIT License https://github.com/boltdb/bolt/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 Ben Johnson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- cenkalti/backoff MIT License https://github.com/cenkalti/backoff/blob/v4/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Cenk Altı Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- cespare/prettybench MIT License https://github.com/cespare/prettybench/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Copyright (c) 2014 Caleb Spare MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- chai2010/gettext-go BSD 3-Clause "New" or "Revised" License https://github.com/chai2010/gettext-go/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2013 ChaiShushan . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- cheggaaa/pb BSD 3-Clause "New" or "Revised" License https://github.com/cheggaaa/pb/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012-2015, Sergey Cherepanov All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- client9/misspell MIT License https://github.com/client9/misspell/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015-2017 Nick Galbreath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- cloudflare/cfssl BSD 2-Clause "Simplified" License https://github.com/cloudflare/cfssl/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2014 CloudFlare Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- clusterhq/flocker-go Apache License 2.0 https://github.com/ClusterHQ/flocker-go/blob/master/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 Copyright 2014-2016 ClusterHQ 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. -------------------------------------------------------------------------------- codedellemc/goscaleio Apache License 2.0 https://github.com/thecodeteam/goscaleio/blob/master/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. -------------------------------------------------------------------------------- codegangsta/negroni MIT License https://github.com/urfave/negroni/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Jeremy Saenz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- container-storage-interface/spec Apache License 2.0 https://github.com/container-storage-interface/spec/blob/master/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. -------------------------------------------------------------------------------- containerd/console Apache License 2.0 https://github.com/containerd/console/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright The containerd 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 https://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. -------------------------------------------------------------------------------- containerd/containerd Apache License 2.0 https://github.com/containerd/containerd/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright The containerd 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 https://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. -------------------------------------------------------------------------------- containerd/typeurl Apache License 2.0 https://github.com/containerd/typeurl/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright The containerd 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 https://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. -------------------------------------------------------------------------------- containernetworking/cni Apache License 2.0 https://github.com/containernetworking/cni/blob/master/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. -------------------------------------------------------------------------------- coreos/bbolt MIT License https://github.com/etcd-io/bbolt/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 Ben Johnson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- coreos/etcd Apache License 2.0 https://github.com/etcd-io/etcd/blob/master/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. -------------------------------------------------------------------------------- coreos/go-etcd Apache License 2.0 https://github.com/coreos/go-etcd/blob/master/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. -------------------------------------------------------------------------------- coreos/go-oidc Apache License 2.0 https://github.com/coreos/go-oidc/blob/v2/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. -------------------------------------------------------------------------------- coreos/go-semver Apache License 2.0 https://github.com/coreos/go-semver/blob/master/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. -------------------------------------------------------------------------------- coreos/go-systemd Apache License 2.0 https://github.com/coreos/go-systemd/blob/master/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: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and 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 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. -------------------------------------------------------------------------------- coreos/pkg Apache License 2.0 https://github.com/coreos/pkg/blob/master/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. -------------------------------------------------------------------------------- coreos/rkt Apache License 2.0 https://github.com/rkt/rkt/blob/master/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. -------------------------------------------------------------------------------- cpuguy83/go-md2man MIT License https://github.com/cpuguy83/go-md2man/blob/master/LICENSE.md -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Brian Goff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- cyphar/filepath-securejoin BSD 3-Clause "New" or "Revised" License https://github.com/cyphar/filepath-securejoin/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. Copyright (C) 2017 SUSE LLC. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- d2g/dhcp4 BSD 3-Clause "New" or "Revised" License https://github.com/d2g/dhcp4/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013 Skagerrak Software Limited. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Skagerrak Software Limited nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- d2g/dhcp4client Mozilla Public License 2.0 https://github.com/d2g/dhcp4client/blob/v1/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution. 1.3. “Contribution” means Covered Software of a particular Contributor. 1.4. “Covered Software” means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. “Incompatible With Secondary Licenses” means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. “Executable Form” means any form of the work other than Source Code Form. 1.7. “Larger Work” means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. “License” means this document. 1.9. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. “Modifications” means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. “Patent Claims” of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. “Secondary License” means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. “Source Code Form” means the form of the work preferred for making modifications. 1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients’ rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients’ rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - “Incompatible With Secondary Licenses” Notice This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- davecgh/go-spew ISC License https://github.com/davecgh/go-spew/blob/master/LICENSE -------------------------------------------------------------------------------- ISC License Copyright (c) 2012-2016 Dave Collins Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- daviddengcn/go-colortext BSD 3-Clause "New" or "Revised" License https://github.com/daviddengcn/go-colortext/blob/master/LICENSE -------------------------------------------------------------------------------- BSD License =========== Copyright (c) 2016, David Deng All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of go-colortext nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MIT License =========== Copyright (c) 2016 David Deng Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- deckarep/golang-set MIT License https://github.com/deckarep/golang-set/blob/master/LICENSE -------------------------------------------------------------------------------- Open Source Initiative OSI - The MIT License (MIT):Licensing The MIT License (MIT) Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- dgrijalva/jwt-go MIT License https://github.com/dgrijalva/jwt-go/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Dave Grijalva Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- dnaeon/go-vcr BSD 2-Clause "Simplified" License https://github.com/dnaeon/go-vcr/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015-2016 Marin Atanasov Nikolov All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer in this position and unchanged. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- docker/distribution Apache License 2.0 https://github.com/docker/distribution/blob/master/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. -------------------------------------------------------------------------------- docker/docker Apache License 2.0 https://github.com/moby/moby/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright 2013-2018 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://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. -------------------------------------------------------------------------------- docker/go-connections Apache License 2.0 https://github.com/docker/go-connections/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright 2015 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://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. -------------------------------------------------------------------------------- docker/go-units Apache License 2.0 https://github.com/docker/go-units/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright 2015 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://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. -------------------------------------------------------------------------------- docker/libnetwork Apache License 2.0 https://github.com/docker/libnetwork/blob/master/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. -------------------------------------------------------------------------------- docker/spdystream Apache License 2.0 https://github.com/docker/spdystream/blob/master/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 Copyright 2014-2015 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- elazarl/goproxy BSD 3-Clause "New" or "Revised" License https://github.com/elazarl/goproxy/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Elazar Leibovich. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Elazar Leibovich. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- emicklei/go-restful MIT License https://github.com/emicklei/go-restful/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012,2013 Ernest Micklei MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- euank/go-kmsg-parser Apache License 2.0 https://github.com/euank/go-kmsg-parser/blob/master/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. -------------------------------------------------------------------------------- exponent-io/jsonpath MIT License https://github.com/exponent-io/jsonpath/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Exponent Labs LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- fatih/camelcase MIT License https://github.com/fatih/camelcase/blob/master/LICENSE.md -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Fatih Arslan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- fatih/color MIT License https://github.com/fatih/color/blob/master/LICENSE.md -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 Fatih Arslan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- fsnotify/fsnotify BSD 3-Clause "New" or "Revised" License https://github.com/fsnotify/fsnotify/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 The Go Authors. All rights reserved. Copyright (c) 2012-2019 fsnotify Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- ghodss/yaml MIT License https://github.com/ghodss/yaml/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Sam Ghods Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- globalsign/mgo BSD 2-Clause "Simplified" License https://github.com/globalsign/mgo/blob/master/LICENSE -------------------------------------------------------------------------------- mgo - MongoDB driver for Go Copyright (c) 2010-2013 - Gustavo Niemeyer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- go-kit/kit MIT License https://github.com/go-kit/kit/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Peter Bourgon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- go-logfmt/logfmt MIT License https://github.com/go-logfmt/logfmt/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 go-logfmt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- go-logr/logr Apache License 2.0 https://github.com/go-logr/logr/blob/master/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. -------------------------------------------------------------------------------- go-logr/zapr Apache License 2.0 https://github.com/go-logr/zapr/blob/master/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. -------------------------------------------------------------------------------- go-openapi/analysis Apache License 2.0 https://github.com/go-openapi/analysis/blob/master/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. -------------------------------------------------------------------------------- go-openapi/errors Apache License 2.0 https://github.com/go-openapi/errors/blob/master/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. -------------------------------------------------------------------------------- go-openapi/jsonpointer Apache License 2.0 https://github.com/go-openapi/jsonpointer/blob/master/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. -------------------------------------------------------------------------------- go-openapi/jsonreference Apache License 2.0 https://github.com/go-openapi/jsonreference/blob/master/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. -------------------------------------------------------------------------------- go-openapi/loads Apache License 2.0 https://github.com/go-openapi/loads/blob/master/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. -------------------------------------------------------------------------------- go-openapi/runtime Apache License 2.0 https://github.com/go-openapi/runtime/blob/master/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. -------------------------------------------------------------------------------- go-openapi/spec Apache License 2.0 https://github.com/go-openapi/spec/blob/master/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. -------------------------------------------------------------------------------- go-openapi/strfmt Apache License 2.0 https://github.com/go-openapi/strfmt/blob/master/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. -------------------------------------------------------------------------------- go-openapi/swag Apache License 2.0 https://github.com/go-openapi/swag/blob/master/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. -------------------------------------------------------------------------------- go-openapi/validate Apache License 2.0 https://github.com/go-openapi/validate/blob/master/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. -------------------------------------------------------------------------------- go-ozzo/ozzo-validation MIT License https://github.com/go-ozzo/ozzo-validation/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2016, Qiang Xue Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- go-stack/stack MIT License https://github.com/go-stack/stack/blob/master/LICENSE.md -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Chris Hines Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- godbus/dbus BSD 2-Clause "Simplified" License https://github.com/godbus/dbus/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013, Georg Reinke (), Google All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gogo/protobuf BSD 3-Clause "New" or "Revised" License https://github.com/gogo/protobuf/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013, The GoGo Authors. All rights reserved. Protocol Buffers for Go with Gadgets Go support for Protocol Buffers - Google's data interchange format Copyright 2010 The Go Authors. All rights reserved. https://github.com/golang/protobuf Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/glog Apache License 2.0 https://github.com/golang/glog/blob/master/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: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and 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 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. -------------------------------------------------------------------------------- golang/groupcache Apache License 2.0 https://github.com/golang/groupcache/blob/master/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: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and 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 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. -------------------------------------------------------------------------------- golang/mock Apache License 2.0 https://github.com/golang/mock/blob/master/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. -------------------------------------------------------------------------------- golang/protobuf BSD 3-Clause "New" or "Revised" License https://github.com/golang/protobuf/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2010 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golangplus/bytes BSD 3-Clause "New" or "Revised" License https://github.com/golangplus/bytes/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015, Golang Plus All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of bytes nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golangplus/fmt BSD 3-Clause "New" or "Revised" License https://github.com/golangplus/fmt/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015, Golang Plus All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of fmt nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golangplus/testing BSD 3-Clause "New" or "Revised" License https://github.com/golangplus/testing/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015, Golang Plus All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of testing nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- google/btree Apache License 2.0 https://github.com/google/btree/blob/master/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. -------------------------------------------------------------------------------- google/cadvisor Apache License 2.0 https://github.com/google/cadvisor/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2014 The cAdvisor 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. 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 -------------------------------------------------------------------------------- google/certificate-transparency-go Apache License 2.0 https://github.com/google/certificate-transparency-go/blob/master/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. -------------------------------------------------------------------------------- google/go-cmp BSD 3-Clause "New" or "Revised" License https://github.com/google/go-cmp/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2017 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- google/gofuzz Apache License 2.0 https://github.com/google/gofuzz/blob/master/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. -------------------------------------------------------------------------------- google/martian Apache License 2.0 https://github.com/google/martian/blob/master/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. -------------------------------------------------------------------------------- google/pprof Apache License 2.0 https://github.com/google/pprof/blob/master/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. -------------------------------------------------------------------------------- google/renameio Apache License 2.0 https://github.com/google/renameio/blob/master/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. -------------------------------------------------------------------------------- google/uuid BSD 3-Clause "New" or "Revised" License https://github.com/google/uuid/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009,2014 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- googleapis/gnostic Apache License 2.0 https://github.com/googleapis/gnostic/blob/master/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. -------------------------------------------------------------------------------- gophercloud/gophercloud Apache License 2.0 https://github.com/gophercloud/gophercloud/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2012-2013 Rackspace, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ------ 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 -------------------------------------------------------------------------------- gopherjs/gopherjs BSD 2-Clause "Simplified" License https://github.com/gopherjs/gopherjs/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013 Richard Musiol. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gorilla/context BSD 3-Clause "New" or "Revised" License https://github.com/gorilla/context/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Rodrigo Moraes. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gorilla/mux BSD 3-Clause "New" or "Revised" License https://github.com/gorilla/mux/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gorilla/websocket BSD 2-Clause "Simplified" License https://github.com/gorilla/websocket/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gregjones/httpcache MIT License https://github.com/gregjones/httpcache/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Copyright © 2012 Greg Jones (greg.jones@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- grpc-ecosystem/go-grpc-middleware Apache License 2.0 https://github.com/grpc-ecosystem/go-grpc-middleware/blob/master/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. -------------------------------------------------------------------------------- grpc-ecosystem/go-grpc-prometheus Apache License 2.0 https://github.com/grpc-ecosystem/go-grpc-prometheus/blob/master/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. -------------------------------------------------------------------------------- grpc-ecosystem/grpc-gateway BSD 3-Clause "New" or "Revised" License https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Copyright (c) 2015, Gengo, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Gengo, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- hashicorp/go-cleanhttp Mozilla Public License 2.0 https://github.com/hashicorp/go-cleanhttp/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- hashicorp/go-getter Mozilla Public License 2.0 https://github.com/hashicorp/go-getter/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution. 1.3. “Contribution” means Covered Software of a particular Contributor. 1.4. “Covered Software” means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. “Incompatible With Secondary Licenses” means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. “Executable Form” means any form of the work other than Source Code Form. 1.7. “Larger Work” means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. “License” means this document. 1.9. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. “Modifications” means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. “Patent Claims” of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. “Secondary License” means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. “Source Code Form” means the form of the work preferred for making modifications. 1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients’ rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients’ rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - “Incompatible With Secondary Licenses” Notice This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- hashicorp/go-safetemp Mozilla Public License 2.0 https://github.com/hashicorp/go-safetemp/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- hashicorp/go-version Mozilla Public License 2.0 https://github.com/hashicorp/go-version/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution. 1.3. “Contribution” means Covered Software of a particular Contributor. 1.4. “Covered Software” means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. “Incompatible With Secondary Licenses” means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. “Executable Form” means any form of the work other than Source Code Form. 1.7. “Larger Work” means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. “License” means this document. 1.9. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. “Modifications” means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. “Patent Claims” of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. “Secondary License” means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. “Source Code Form” means the form of the work preferred for making modifications. 1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients’ rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients’ rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - “Incompatible With Secondary Licenses” Notice This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- hashicorp/golang-lru Mozilla Public License 2.0 https://github.com/hashicorp/golang-lru/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. "Contributor" means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. "Contributor Version" means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor's Contribution. 1.3. "Contribution" means Covered Software of a particular Contributor. 1.4. "Covered Software" means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. "Incompatible With Secondary Licenses" means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. "Executable Form" means any form of the work other than Source Code Form. 1.7. "Larger Work" means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" means this document. 1.9. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. "Modifications" means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. "Patent Claims" of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. "Secondary License" means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. "Source Code Form" means the form of the work preferred for making modifications. 1.14. "You" (or "Your") means an individual or a legal entity exercising rights under this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party's modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients' rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients' rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an "as is" basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- hashicorp/hcl Mozilla Public License 2.0 https://github.com/hashicorp/hcl/blob/master/LICENSE -------------------------------------------------------------------------------- Mozilla Public License, version 2.0 1. Definitions 1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. 1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a Contributor and that particular Contributor’s Contribution. 1.3. “Contribution” means Covered Software of a particular Contributor. 1.4. “Covered Software” means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. 1.5. “Incompatible With Secondary Licenses” means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or b. that the Covered Software was made available under the terms of version 1.1 or earlier of the License, but not also under the terms of a Secondary License. 1.6. “Executable Form” means any form of the work other than Source Code Form. 1.7. “Larger Work” means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. “License” means this document. 1.9. “Licensable” means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License. 1.10. “Modifications” means any of the following: a. any file in Source Code Form that results from an addition to, deletion from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. 1.11. “Patent Claims” of a Contributor means any patent claim(s), including without limitation, method, process, and apparatus claims, in any patent Licensable by such Contributor that would be infringed, but for the grant of the License, by the making, using, selling, offering for sale, having made, import, or transfer of either its Contributions or its Contributor Version. 1.12. “Secondary License” means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. 1.13. “Source Code Form” means the form of the work preferred for making modifications. 1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions 2.1. Grants Each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license: a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its Contributions, either on an unmodified basis, with Modifications, or as part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for sale, have made, import, and otherwise transfer either its Contributions or its Contributor Version. 2.2. Effective Date The licenses granted in Section 2.1 with respect to any Contribution become effective for each Contribution on the date the Contributor first distributes such Contribution. 2.3. Limitations on Grant Scope The licenses granted in this Section 2 are the only rights granted under this License. No additional rights or licenses will be implied from the distribution or licensing of Covered Software under this License. Notwithstanding Section 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or b. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or c. under Patent Claims infringed by Covered Software in the absence of its Contributions. This License does not grant any rights in the trademarks, service marks, or logos of any Contributor (except as may be necessary to comply with the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this License (see Section 10.2) or under the terms of a Secondary License (if permitted under the terms of Section 3.3). 2.5. Representation Each Contributor represents that the Contributor believes its Contributions are its original creation(s) or it has sufficient rights to grant the rights to its Contributions conveyed by this License. 2.6. Fair Use This License is not intended to limit any rights You have under applicable copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in Section 2.1. 3. Responsibilities 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any Modifications that You create or to which You contribute, must be under the terms of this License. You must inform recipients that the Source Code Form of the Covered Software is governed by the terms of this License, and how they can obtain a copy of this License. You may not attempt to alter or restrict the recipients’ rights in the Source Code Form. 3.2. Distribution of Executable Form If You distribute Covered Software in Executable Form then: a. such Covered Software must also be made available in Source Code Form, as described in Section 3.1, and You must inform recipients of the Executable Form how they can obtain a copy of such Source Code Form by reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and b. You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the license for the Executable Form does not attempt to limit or alter the recipients’ rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered Software with a work governed by one or more Secondary Licenses, and the Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered Software under the terms of either this License or such Secondary License(s). 3.4. Notices You may not remove or alter the substance of any license notices (including copyright notices, patent notices, disclaimers of warranty, or limitations of liability) contained within the Source Code Form of the Covered Software, except that You may alter any license notices to the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, You may do so only on Your own behalf, and not on behalf of any Contributor. You must make it absolutely clear that any such warranty, support, indemnity, or liability obligation is offered by You alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any jurisdiction. 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be placed in a text file included with all distributions of the Covered Software under this License. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Termination 5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received notice of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or Your distributors under this License prior to termination shall survive termination. 6. Disclaimer of Warranty Covered Software is provided under this License on an “as is” basis, without warranty of any kind, either expressed, implied, or statutory, including, without limitation, warranties that the Covered Software is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire risk as to the quality and performance of the Covered Software is with You. Should any Covered Software prove defective in any respect, You (not any Contributor) assume the cost of any necessary servicing, repair, or correction. This disclaimer of warranty constitutes an essential part of this License. No use of any Covered Software is authorized under this License except under this disclaimer. 7. Limitation of Liability Under no circumstances and under no legal theory, whether tort (including negligence), contract, or otherwise, shall any Contributor, or anyone who distributes Covered Software as permitted above, be liable to You for any direct, indirect, special, incidental, or consequential damages of any character including, without limitation, damages for lost profits, loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability shall not apply to liability for death or personal injury resulting from such party’s negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation Any litigation relating to this License may be brought only in the courts of a jurisdiction where the defendant maintains its principal place of business and such litigation shall be governed by laws of that jurisdiction, without reference to its conflict-of-law provisions. Nothing in this Section shall prevent a party’s ability to bring cross-claims or counter-claims. 9. Miscellaneous This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License 10.1. New Versions Mozilla Foundation is the license steward. Except as provided in Section 10.3, no one other than the license steward has the right to modify or publish new versions of this License. Each version will be given a distinguishing version number. 10.2. Effect of New Versions You may distribute the Covered Software under the terms of the version of the License under which You originally received the Covered Software, or under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to create a new license for such software, you may create and use a modified version of this License if you rename the license and remove any references to the name of the license steward (except to note that such modified license differs from this License). 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses If You choose to distribute Source Code Form that is Incompatible With Secondary Licenses under the terms of this version of the License, the notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - “Incompatible With Secondary Licenses” Notice This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- heketi/heketi Apache License 2.0 https://github.com/heketi/heketi/blob/master/LICENSE -------------------------------------------------------------------------------- Heketi code is released under various licenses: The REST API client code (in go and python) is released under a dual license of Apache 2.0 or LGPLv3+. The other parts of heketi (server, cli, tests, ...) are released under a dual license of LGPLv3+ or GPLv2. -------------------------------------------------------------------------------- heketi/rest Apache License 2.0 https://github.com/heketi/rest/blob/master/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. -------------------------------------------------------------------------------- heketi/tests Apache License 2.0 https://github.com/heketi/tests/blob/master/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. -------------------------------------------------------------------------------- hpcloud/tail MIT License https://github.com/hpcloud/tail/blob/master/LICENSE.txt -------------------------------------------------------------------------------- # The MIT License (MIT) # © Copyright 2015 Hewlett Packard Enterprise Development LP Copyright (c) 2014 ActiveState Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- imdario/mergo BSD 3-Clause "New" or "Revised" License https://github.com/imdario/mergo/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013 Dario Castañé. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- inconshreveable/mousetrap Apache License 2.0 https://github.com/inconshreveable/mousetrap/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2014 Alan Shreve 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. -------------------------------------------------------------------------------- jmespath/go-jmespath Apache License 2.0 https://github.com/jmespath/go-jmespath/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2015 James Saryerwinnie 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. -------------------------------------------------------------------------------- jonboulle/clockwork Apache License 2.0 https://github.com/jonboulle/clockwork/blob/master/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. -------------------------------------------------------------------------------- json-iterator/go MIT License https://github.com/json-iterator/go/blob/master/LICENSE -------------------------------------------------------------------------------- MIT License Copyright (c) 2016 json-iterator Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- jstemmer/go-junit-report MIT License https://github.com/jstemmer/go-junit-report/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Joel Stemmer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- jteeuwen/go-bindata Public Domain Dedication https://github.com/jteeuwen/go-bindata/blob/master/LICENSE -------------------------------------------------------------------------------- This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication license. Its contents can be found at: http://creativecommons.org/publicdomain/zero/1.0 -------------------------------------------------------------------------------- jtolds/gls MIT License https://github.com/jtolds/gls/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013, Space Monkey, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- julienschmidt/httprouter BSD 3-Clause "New" or "Revised" License https://github.com/julienschmidt/httprouter/blob/master/LICENSE -------------------------------------------------------------------------------- BSD 3-Clause License Copyright (c) 2013, Julien Schmidt All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- kardianos/osext BSD 3-Clause "New" or "Revised" License https://github.com/kardianos/osext/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- karrick/godirwalk BSD 2-Clause "Simplified" License https://github.com/karrick/godirwalk/blob/master/LICENSE -------------------------------------------------------------------------------- BSD 2-Clause License Copyright (c) 2017, Karrick McDermott All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- kisielk/errcheck MIT License https://github.com/kisielk/errcheck/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013 Kamil Kisiel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- kisielk/gotool MIT License https://github.com/kisielk/gotool/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013 Kamil Kisiel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- konsorten/go-windows-terminal-sequences MIT License https://github.com/konsorten/go-windows-terminal-sequences/blob/master/LICENSE -------------------------------------------------------------------------------- (The MIT License) Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- kr/fs BSD 3-Clause "New" or "Revised" License https://github.com/kr/fs/blob/main/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- kr/pretty MIT License https://github.com/kr/pretty/blob/main/License -------------------------------------------------------------------------------- Copyright 2012 Keith Rarick Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- kr/pty MIT License https://github.com/kr/pty/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2019 Keith Rarick Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- kr/text MIT License https://github.com/kr/text/blob/main/License -------------------------------------------------------------------------------- Copyright 2012 Keith Rarick Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- kubeflow/kubeflow Apache License 2.0 https://github.com/kubeflow/kubeflow/blob/master/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. -------------------------------------------------------------------------------- kubernetes-sigs/application Apache License 2.0 https://github.com/kubernetes-sigs/application/blob/master/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. -------------------------------------------------------------------------------- libopenstorage/openstorage Apache License 2.0 https://github.com/libopenstorage/openstorage/blob/master/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 Copyright 2015 Openstorage.org. 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. -------------------------------------------------------------------------------- liggitt/tabwriter BSD 3-Clause "New" or "Revised" License https://github.com/liggitt/tabwriter/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- lithammer/dedent MIT License https://github.com/lithammer/dedent/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2018 Peter Lithammer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- lpabon/godbc Apache License 2.0 https://github.com/lpabon/godbc/blob/master/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. -------------------------------------------------------------------------------- magiconair/properties BSD 2-Clause "Simplified" License https://github.com/magiconair/properties/blob/master/LICENSE -------------------------------------------------------------------------------- goproperties - properties file decoder for Go Copyright (c) 2013-2018 - Frank Schroeder All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- mailru/easyjson MIT License https://github.com/mailru/easyjson/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2016 Mail.Ru Group Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- marstr/guid MIT License https://github.com/marstr/guid/blob/master/LICENSE.txt -------------------------------------------------------------------------------- MIT License Copyright (c) 2016 Martin Strobel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mattn/go-colorable MIT License https://github.com/mattn/go-colorable/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2016 Yasuhiro Matsumoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mattn/go-isatty MIT License https://github.com/mattn/go-isatty/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) Yasuhiro MATSUMOTO MIT License (Expat) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mattn/go-runewidth MIT License https://github.com/mattn/go-runewidth/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2016 Yasuhiro Matsumoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mattn/go-shellwords MIT License https://github.com/mattn/go-shellwords/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2017 Yasuhiro Matsumoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- matttproud/golang_protobuf_extensions Apache License 2.0 https://github.com/matttproud/golang_protobuf_extensions/blob/master/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. -------------------------------------------------------------------------------- mesos/mesos-go Apache License 2.0 https://github.com/mesos/mesos-go/blob/master/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. -------------------------------------------------------------------------------- mholt/caddy Apache License 2.0 https://github.com/caddyserver/caddy/blob/master/LICENSE.txt -------------------------------------------------------------------------------- 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. -------------------------------------------------------------------------------- miekg/dns BSD 3-Clause "New" or "Revised" License https://github.com/miekg/dns/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. As this is fork of the official Go code the same license applies. Extensions of the original work are copyright (c) 2011 Miek Gieben -------------------------------------------------------------------------------- mindprince/gonvml Apache License 2.0 https://github.com/mindprince/gonvml/blob/master/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. -------------------------------------------------------------------------------- mistifyio/go-zfs Apache License 2.0 https://github.com/mistifyio/go-zfs/blob/master/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 (c) 2014, OmniTI Computer Consulting, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- mitchellh/go-homedir MIT License https://github.com/mitchellh/go-homedir/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 Mitchell Hashimoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mitchellh/go-testing-interface MIT License https://github.com/mitchellh/go-testing-interface/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2016 Mitchell Hashimoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mitchellh/go-wordwrap MIT License https://github.com/mitchellh/go-wordwrap/blob/master/LICENSE.md -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Mitchell Hashimoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mitchellh/mapstructure MIT License https://github.com/mitchellh/mapstructure/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 Mitchell Hashimoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- modern-go/concurrent Apache License 2.0 https://github.com/modern-go/concurrent/blob/master/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. -------------------------------------------------------------------------------- modern-go/reflect2 Apache License 2.0 https://github.com/modern-go/reflect2/blob/master/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. -------------------------------------------------------------------------------- mohae/deepcopy MIT License https://github.com/mohae/deepcopy/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Joel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- morikuni/aec MIT License https://github.com/morikuni/aec/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2016 Taihei Morikuni Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- mrunalp/fileutils Apache License 2.0 https://github.com/mrunalp/fileutils/blob/master/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 Copyright 2014 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- munnerz/goautoneg BSD 3-Clause "New" or "Revised" License https://github.com/munnerz/goautoneg/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2011, Open Knowledge Foundation Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the Open Knowledge Foundation Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- mvdan/xurls BSD 3-Clause "New" or "Revised" License https://github.com/mvdan/xurls/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015, Daniel Martí. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- mwitkow/go-conntrack Apache License 2.0 https://github.com/mwitkow/go-conntrack/blob/master/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. -------------------------------------------------------------------------------- mxk/go-flowrate BSD 3-Clause "New" or "Revised" License https://github.com/mxk/go-flowrate/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2014 The Go-FlowRate Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the go-flowrate project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- natefinch/lumberjack MIT License https://github.com/natefinch/lumberjack/blob/v2.0/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Nate Finch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- onrik/logrus MIT License https://github.com/onrik/logrus/blob/master/LICENSE -------------------------------------------------------------------------------- MIT License Copyright (c) 2016 Andrey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- onsi/ginkgo MIT License https://github.com/onsi/ginkgo/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013-2014 Onsi Fakhouri Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- onsi/gomega MIT License https://github.com/onsi/gomega/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013-2014 Onsi Fakhouri Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- opencontainers/go-digest Apache License 2.0 https://github.com/opencontainers/go-digest/blob/master/LICENSE -------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 https://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 Copyright 2016 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://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. -------------------------------------------------------------------------------- opencontainers/image-spec Apache License 2.0 https://github.com/opencontainers/image-spec/blob/master/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 Copyright 2016 The Linux Foundation. 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. -------------------------------------------------------------------------------- opencontainers/runc Apache License 2.0 https://github.com/opencontainers/runc/blob/master/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 Copyright 2014 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- opencontainers/runtime-spec Apache License 2.0 https://github.com/opencontainers/runtime-spec/blob/master/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 Copyright 2015 The Linux Foundation. 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. -------------------------------------------------------------------------------- opencontainers/selinux Apache License 2.0 https://github.com/opencontainers/selinux/blob/master/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. -------------------------------------------------------------------------------- otiai10/copy MIT License https://github.com/otiai10/copy/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2018 otiai10 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- otiai10/curr Do What The Fuck You Want To Public License Version 2 https://github.com/otiai10/curr/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright © 2015 Hiromu OCHIAI This work is free. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. -------------------------------------------------------------------------------- otiai10/mint MIT License https://github.com/otiai10/mint/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2017 otiai10 (Hiromu OCHIAI) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- pborman/uuid BSD 3-Clause "New" or "Revised" License https://github.com/pborman/uuid/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009,2014 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- pelletier/go-toml MIT License https://github.com/pelletier/go-toml/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- peterbourgon/diskv MIT License https://github.com/peterbourgon/diskv/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2011-2012 Peter Bourgon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- pkg/errors BSD 2-Clause "Simplified" License https://github.com/pkg/errors/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015, Dave Cheney All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- pkg/sftp BSD 2-Clause "Simplified" License https://github.com/pkg/sftp/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013, Dave Cheney All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- pmezard/go-difflib BSD 3-Clause "New" or "Revised" License https://github.com/pmezard/go-difflib/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2013, Patrick Mezard All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- pquerna/cachecontrol Apache License 2.0 https://github.com/pquerna/cachecontrol/blob/master/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. -------------------------------------------------------------------------------- pquerna/ffjson Apache License 2.0 https://github.com/pquerna/ffjson/blob/master/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. -------------------------------------------------------------------------------- prometheus/client_golang Apache License 2.0 https://github.com/prometheus/client_golang/blob/master/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. -------------------------------------------------------------------------------- prometheus/client_model Apache License 2.0 https://github.com/prometheus/client_model/blob/master/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. -------------------------------------------------------------------------------- prometheus/common Apache License 2.0 https://github.com/prometheus/common/blob/master/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. -------------------------------------------------------------------------------- prometheus/procfs Apache License 2.0 https://github.com/prometheus/procfs/blob/master/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. -------------------------------------------------------------------------------- quobyte/api BSD 3-Clause "New" or "Revised" License https://github.com/quobyte/api/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2016, Quobyte Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of quobyte-automation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- remyoudompheng/bigfft BSD 3-Clause "New" or "Revised" License https://github.com/remyoudompheng/bigfft/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- robfig/cron MIT License https://github.com/robfig/cron/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (C) 2012 Rob Figueiredo All Rights Reserved. MIT LICENSE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- rogpeppe/go-charset BSD 2-Clause "Simplified" License https://github.com/rogpeppe/go-charset/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The go-charset Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- rogpeppe/go-internal BSD 3-Clause "New" or "Revised" License https://github.com/rogpeppe/go-internal/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2018 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- rubiojr/go-vhd MIT License https://github.com/rubiojr/go-vhd/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Sergio Rubio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- russross/blackfriday BSD 2-Clause "Simplified" License https://github.com/russross/blackfriday/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Blackfriday is distributed under the Simplified BSD License: > Copyright © 2011 Russ Ross > All rights reserved. > > Redistribution and use in source and binary forms, with or without > modification, are permitted provided that the following conditions > are met: > > 1. Redistributions of source code must retain the above copyright > notice, this list of conditions and the following disclaimer. > > 2. Redistributions in binary form must reproduce the above > copyright notice, this list of conditions and the following > disclaimer in the documentation and/or other materials provided with > the distribution. > > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS > FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE > COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, > INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, > BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; > LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER > CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN > ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- satori/go.uuid MIT License https://github.com/satori/go.uuid/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (C) 2013-2018 by Maxim Bublis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- seccomp/libseccomp-golang BSD 2-Clause "Simplified" License https://github.com/seccomp/libseccomp-golang/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2015 Matthew Heon Copyright (c) 2015 Paul Moore All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- shurcooL/sanitized_anchor_name MIT License https://github.com/shurcooL/sanitized_anchor_name/blob/master/LICENSE -------------------------------------------------------------------------------- MIT License Copyright (c) 2015 Dmitri Shuralyov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- sigma/go-inotify BSD 3-Clause "New" or "Revised" License https://github.com/sigma/go-inotify/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- sirupsen/logrus MIT License https://github.com/sirupsen/logrus/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Simon Eskildsen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- smartystreets/assertions MIT License https://github.com/smartystreets/assertions/blob/master/LICENSE.md -------------------------------------------------------------------------------- Copyright (c) 2016 SmartyStreets, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. NOTE: Various optional and subordinate components carry their own licensing requirements and restrictions. Use of those components is subject to the terms and conditions outlined the respective license of each component. -------------------------------------------------------------------------------- smartystreets/goconvey MIT License https://github.com/smartystreets/goconvey/blob/master/LICENSE.md -------------------------------------------------------------------------------- Copyright (c) 2016 SmartyStreets, LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. NOTE: Various optional and subordinate components carry their own licensing requirements and restrictions. Use of those components is subject to the terms and conditions outlined the respective license of each component. -------------------------------------------------------------------------------- soheilhy/cmux Apache License 2.0 https://github.com/soheilhy/cmux/blob/master/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. -------------------------------------------------------------------------------- spf13/afero Apache License 2.0 https://github.com/spf13/afero/blob/master/LICENSE.txt -------------------------------------------------------------------------------- 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. -------------------------------------------------------------------------------- spf13/cast MIT License https://github.com/spf13/cast/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Steve Francia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- spf13/cobra Apache License 2.0 https://github.com/spf13/cobra/blob/master/LICENSE.txt -------------------------------------------------------------------------------- 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. -------------------------------------------------------------------------------- spf13/jwalterweatherman MIT License https://github.com/spf13/jwalterweatherman/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Steve Francia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- spf13/pflag BSD 3-Clause "New" or "Revised" License https://github.com/spf13/pflag/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Alex Ogier. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- spf13/viper MIT License https://github.com/spf13/viper/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Steve Francia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- storageos/go-api MIT License https://github.com/storageos/go-api/blob/master/LICENCE -------------------------------------------------------------------------------- MIT License Copyright (c) 2015-2018 StorageOS Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2013-2017, go-dockerclient authors All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- stretchr/objx MIT License https://github.com/stretchr/objx/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License Copyright (c) 2014 Stretchr, Inc. Copyright (c) 2017-2018 objx contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- stretchr/testify MIT License https://github.com/stretchr/testify/blob/master/LICENSE -------------------------------------------------------------------------------- MIT License Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- syndtr/gocapability BSD 2-Clause "Simplified" License https://github.com/syndtr/gocapability/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2013 Suryandaru Triandana All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- tmc/grpc-websocket-proxy MIT License https://github.com/tmc/grpc-websocket-proxy/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (C) 2016 Travis Cline Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- ugorji/go MIT License https://github.com/ugorji/go/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- ulikunitz/xz BSD 3-Clause "New" or "Revised" License https://github.com/ulikunitz/xz/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2014-2016 Ulrich Kunitz All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * My name, Ulrich Kunitz, may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- urfave/negroni MIT License https://github.com/urfave/negroni/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Jeremy Saenz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- vishvananda/netlink Apache License 2.0 https://github.com/vishvananda/netlink/blob/master/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 Copyright 2014 Vishvananda Ishaya. Copyright 2014 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- vishvananda/netns Apache License 2.0 https://github.com/vishvananda/netns/blob/master/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 Copyright 2014 Vishvananda Ishaya. Copyright 2014 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- vmware/govmomi Apache License 2.0 https://github.com/vmware/govmomi/blob/master/LICENSE.txt -------------------------------------------------------------------------------- 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. -------------------------------------------------------------------------------- vmware/photon-controller-go-sdk Apache License 2.0 https://github.com/vmware/photon-controller-go-sdk/blob/master/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. -------------------------------------------------------------------------------- xanzy/go-cloudstack Apache License 2.0 https://github.com/xanzy/go-cloudstack/blob/master/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. -------------------------------------------------------------------------------- xiang90/probing MIT License https://github.com/xiang90/probing/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Xiang Li Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- xlab/handysort MIT License https://github.com/xlab/handysort/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Maxim Kupriianov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- xordataexchange/crypt MIT License https://github.com/xordataexchange/crypt/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 XOR Data Exchange, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- census-instrumentation/opencensus-go Apache License 2.0 https://github.com/census-instrumentation/opencensus-go/blob/master/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. -------------------------------------------------------------------------------- uber-go/atomic MIT License https://github.com/uber-go/atomic/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Copyright (c) 2016 Uber Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- uber-go/multierr MIT License https://github.com/uber-go/multierr/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Copyright (c) 2017 Uber Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- uber-go/tools MIT License https://github.com/uber-go/tools/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2017 Uber Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- uber-go/zap MIT License https://github.com/uber-go/zap/blob/master/LICENSE.txt -------------------------------------------------------------------------------- Copyright (c) 2016-2017 Uber Technologies, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- golang/crypto BSD 3-Clause "New" or "Revised" License https://github.com/golang/crypto/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/exp BSD 3-Clause "New" or "Revised" License https://github.com/golang/exp/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/image BSD 3-Clause "New" or "Revised" License https://github.com/golang/image/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/mobile BSD 3-Clause "New" or "Revised" License https://github.com/golang/mobile/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/mod BSD 3-Clause "New" or "Revised" License https://github.com/golang/mod/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/net BSD 3-Clause "New" or "Revised" License https://github.com/golang/net/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/oauth2 BSD 3-Clause "New" or "Revised" License https://github.com/golang/oauth2/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/sync BSD 3-Clause "New" or "Revised" License https://github.com/golang/sync/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/sys BSD 3-Clause "New" or "Revised" License https://github.com/golang/sys/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/text BSD 3-Clause "New" or "Revised" License https://github.com/golang/text/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/time BSD 3-Clause "New" or "Revised" License https://github.com/golang/time/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/tools BSD 3-Clause "New" or "Revised" License https://github.com/golang/tools/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/xerrors BSD 3-Clause "New" or "Revised" License https://github.com/golang/xerrors/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2019 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gomodules/jsonpatch Apache License 2.0 https://github.com/gomodules/jsonpatch/blob/master/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. -------------------------------------------------------------------------------- gonum/gonum BSD 3-Clause "New" or "Revised" License https://github.com/gonum/gonum/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright ©2013 The Gonum Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Gonum project nor the names of its authors and contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gonum/netlib BSD 3-Clause "New" or "Revised" License https://github.com/gonum/netlib/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright ©2013 The gonum Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the gonum project nor the names of its authors and contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- google/google-api-go-client BSD 3-Clause "New" or "Revised" License https://github.com/googleapis/google-api-go-client/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2011 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- golang/appengine Apache License 2.0 https://github.com/golang/appengine/blob/master/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. -------------------------------------------------------------------------------- google/go-genproto Apache License 2.0 https://github.com/googleapis/go-genproto/blob/master/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. -------------------------------------------------------------------------------- grpc/grpc-go Apache License 2.0 https://github.com/grpc/grpc-go/blob/master/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. -------------------------------------------------------------------------------- airbrake/gobrake BSD 3-Clause "New" or "Revised" License https://github.com/airbrake/gobrake/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2014 The Gobrake Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- alecthomas/kingpin MIT License https://github.com/alecthomas/kingpin/blob/master/COPYING -------------------------------------------------------------------------------- Copyright (C) 2014 Alec Thomas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- go-check/check BSD 2-Clause "Simplified" License https://github.com/go-check/check/blob/v1/LICENSE -------------------------------------------------------------------------------- Gocheck - A rich testing framework for Go Copyright (c) 2010-2013 Gustavo Niemeyer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- go-errgo/errgo BSD 3-Clause "New" or "Revised" License https://github.com/go-errgo/errgo/blob/v1/LICENSE -------------------------------------------------------------------------------- Copyright © 2013, Roger Peppe All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of this project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- go-gcfg/gcfg BSD 3-Clause "New" or "Revised" License https://github.com/go-gcfg/gcfg/blob/v1/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- gemnasium/logrus-airbrake-hook MIT License https://github.com/gemnasium/logrus-airbrake-hook/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Gemnasium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- go-inf/inf BSD 3-Clause "New" or "Revised" License https://github.com/go-inf/inf/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- square/go-jose Apache License 2.0 https://github.com/square/go-jose/blob/master/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. -------------------------------------------------------------------------------- src-d/go-billy Apache License 2.0 https://github.com/src-d/go-billy/blob/master/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 2017 Sourced Technologies S.L. 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. -------------------------------------------------------------------------------- src-d/go-git-fixtures Apache License 2.0 https://github.com/src-d/go-git-fixtures/blob/master/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 2017 Sourced Technologies, S.L. 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. -------------------------------------------------------------------------------- src-d/go-git Apache License 2.0 https://github.com/src-d/go-git/blob/master/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 2018 Sourced Technologies, S.L. 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. -------------------------------------------------------------------------------- go-tomb/tomb BSD 3-Clause "New" or "Revised" License https://github.com/go-tomb/tomb/blob/v1/LICENSE -------------------------------------------------------------------------------- tomb - support for clean goroutine termination in Go. Copyright (c) 2010-2011 - Gustavo Niemeyer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- go-warnings/warnings BSD 2-Clause "Simplified" License https://github.com/go-warnings/warnings/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2016 Péter Surányi. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- go-yaml/yaml Apache License 2.0 https://github.com/go-yaml/yaml/blob/v2/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. -------------------------------------------------------------------------------- gotestyourself/gotest.tools Apache License 2.0 https://github.com/gotestyourself/gotest.tools/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2018 gotest.tools 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. -------------------------------------------------------------------------------- go4org/grpc BSD 3-Clause "New" or "Revised" License https://github.com/go4org/grpc/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright 2014, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- dominikh/go-tools MIT License https://github.com/dominikh/go-tools/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2016 Dominik Honnef Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- kubernetes/api Apache License 2.0 https://github.com/kubernetes/api/blob/master/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. -------------------------------------------------------------------------------- kubernetes/apiextensions-apiserver Apache License 2.0 https://github.com/kubernetes/apiextensions-apiserver/blob/master/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. -------------------------------------------------------------------------------- kubernetes/apimachinery Apache License 2.0 https://github.com/kubernetes/apimachinery/blob/master/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. -------------------------------------------------------------------------------- kubernetes/apiserver Apache License 2.0 https://github.com/kubernetes/apiserver/blob/master/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. -------------------------------------------------------------------------------- kubernetes/cli-runtime Apache License 2.0 https://github.com/kubernetes/cli-runtime/blob/master/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. -------------------------------------------------------------------------------- kubernetes/client-go Apache License 2.0 https://github.com/kubernetes/client-go/blob/master/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. -------------------------------------------------------------------------------- kubernetes/cloud-provider Apache License 2.0 https://github.com/kubernetes/cloud-provider/blob/master/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. -------------------------------------------------------------------------------- kubernetes/cluster-bootstrap Apache License 2.0 https://github.com/kubernetes/cluster-bootstrap/blob/master/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. -------------------------------------------------------------------------------- kubernetes/code-generator Apache License 2.0 https://github.com/kubernetes/code-generator/blob/master/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. -------------------------------------------------------------------------------- kubernetes/component-base Apache License 2.0 https://github.com/kubernetes/component-base/blob/master/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. -------------------------------------------------------------------------------- kubernetes/cri-api Apache License 2.0 https://github.com/kubernetes/cri-api/blob/master/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. -------------------------------------------------------------------------------- kubernetes/csi-translation-lib Apache License 2.0 https://github.com/kubernetes/csi-translation-lib/blob/master/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. -------------------------------------------------------------------------------- kubernetes/gengo Apache License 2.0 https://github.com/kubernetes/gengo/blob/master/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 2014 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. -------------------------------------------------------------------------------- kubernetes/heapster Apache License 2.0 https://github.com/kubernetes-retired/heapster/blob/master/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. -------------------------------------------------------------------------------- kubernetes/klog Apache License 2.0 https://github.com/kubernetes/klog/blob/master/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: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and 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 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. -------------------------------------------------------------------------------- kubernetes/kube-aggregator Apache License 2.0 https://github.com/kubernetes/kube-aggregator/blob/master/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. -------------------------------------------------------------------------------- kubernetes/kube-controller-manager Apache License 2.0 https://github.com/kubernetes/kube-controller-manager/blob/master/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. -------------------------------------------------------------------------------- kubernetes/kube-openapi Apache License 2.0 https://github.com/kubernetes/kube-openapi/blob/master/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. -------------------------------------------------------------------------------- kubernetes/kube-proxy Apache License 2.0 https://github.com/kubernetes/kube-proxy/blob/master/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. -------------------------------------------------------------------------------- kubernetes/kube-scheduler Apache License 2.0 https://github.com/kubernetes/kube-scheduler/blob/master/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. -------------------------------------------------------------------------------- kubernetes/kubelet Apache License 2.0 https://github.com/kubernetes/kubelet/blob/master/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. -------------------------------------------------------------------------------- kubernetes/kubernetes Apache License 2.0 https://github.com/kubernetes/kubernetes/blob/master/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. -------------------------------------------------------------------------------- kubernetes/legacy-cloud-providers Apache License 2.0 https://github.com/kubernetes/legacy-cloud-providers/blob/master/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. -------------------------------------------------------------------------------- kubernetes/metrics Apache License 2.0 https://github.com/kubernetes/metrics/blob/master/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. -------------------------------------------------------------------------------- kubernetes/repo-infra Apache License 2.0 https://github.com/kubernetes/repo-infra/blob/master/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. -------------------------------------------------------------------------------- kubernetes/sample-apiserver Apache License 2.0 https://github.com/kubernetes/sample-apiserver/blob/master/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. -------------------------------------------------------------------------------- kubernetes/utils Apache License 2.0 https://github.com/kubernetes/utils/blob/master/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. -------------------------------------------------------------------------------- kubernetes-sigs/controller-runtime Apache License 2.0 https://github.com/kubernetes-sigs/controller-runtime/blob/master/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. -------------------------------------------------------------------------------- kubernetes-sigs/kustomize Apache License 2.0 https://github.com/kubernetes-sigs/kustomize/blob/master/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. -------------------------------------------------------------------------------- kubernetes-sigs/structured-merge-diff Apache License 2.0 https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/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. -------------------------------------------------------------------------------- kubernetes-sigs/testing_frameworks Apache License 2.0 https://github.com/kubernetes-sigs/testing_frameworks/blob/master/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 2018 The Kubernetes Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- kubernetes-sigs/yaml MIT License https://github.com/kubernetes-sigs/yaml/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2014 Sam Ghods Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- sourcegraph/go-diff MIT License https://github.com/sourcegraph/go-diff/blob/master/LICENSE -------------------------------------------------------------------------------- Copyright (c) 2014 Sourcegraph, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------- Portions adapted from python-unidiff: Copyright (c) 2012 Matias Bordese Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -------------------------------------------------------------------------------- sqs/pbtypes Apache License 2.0 https://github.com/sqs/pbtypes/blob/master/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. -------------------------------------------------------------------------------- fvbommel/util MIT License https://github.com/fvbommel/util/blob/master/LICENSE -------------------------------------------------------------------------------- The MIT License (MIT) Copyright (c) 2015 Frits van Bommel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- bitbucket.org/bertimus9/systemstat MIT License https://bitbucket.org/bertimus9/systemstat/src/master/LICENSE -------------------------------------------------------------------------------- Bitbucket
-------------------------------------------------------------------------------- modernc.org/cc BSD 3-Clause "New" or "Revised" License https://gitlab.com/cznic/cc/blob/master/LICENSE -------------------------------------------------------------------------------- LICENSE · master · cznic / cc · GitLab -------------------------------------------------------------------------------- modernc.org/golex BSD 3-Clause "New" or "Revised" License https://gitlab.com/cznic/golex/blob/master/LICENSE -------------------------------------------------------------------------------- LICENSE · master · cznic / golex · GitLab -------------------------------------------------------------------------------- modernc.org/mathutil BSD 3-Clause "New" or "Revised" License https://gitlab.com/cznic/mathutil/blob/master/LICENSE -------------------------------------------------------------------------------- Sign in · GitLab
-------------------------------------------------------------------------------- modernc.org/strutil BSD 3-Clause "New" or "Revised" License https://gitlab.com/cznic/strutil/blob/master/LICENSE -------------------------------------------------------------------------------- LICENSE · master · cznic / strutil · GitLab -------------------------------------------------------------------------------- modernc.org/xc BSD 3-Clause "New" or "Revised" License https://gitlab.com/cznic/xc/blob/master/LICENSE -------------------------------------------------------------------------------- LICENSE · master · cznic / xc · GitLab -------------------------------------------------------------------------------- heketi/utils Apache License 2.0 https://github.com/heketi/heketi/blob/master/LICENSE -------------------------------------------------------------------------------- heketi/LICENSE at master · heketi/heketi · GitHub
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
7 lines (5 sloc) 260 Bytes
Heketi code is released under various licenses:
The REST API client code (in go and python) is released
under a dual license of Apache 2.0 or LGPLv3+.
The other parts of heketi (server, cli, tests, ...) are released
under a dual license of LGPLv3+ or GPLv2.
You can’t perform that action at this time.
-------------------------------------------------------------------------------- kr/logfmt MIT License https://github.com/kr/logfmt/blob/master/Readme -------------------------------------------------------------------------------- logfmt/Readme at master · kr/logfmt · GitHub
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
12 lines (7 sloc) 1.22 KB
Go package for parsing (and, eventually, generating)
log lines in the logfmt style.
See http://godoc.org/github.com/kr/logfmt for format, and other documentation and examples.
Copyright (C) 2013 Keith Rarick, Blake Mizerany
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
You can’t perform that action at this time.
================================================ FILE: third_party/license_info.csv ================================================ kubeflow/kfctl,https://github.com/kubeflow/kfctl/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubeflow/kfctl/master/LICENSE GoogleCloudPlatform/gcloud-golang,https://github.com/googleapis/google-cloud-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/googleapis/google-cloud-go/master/LICENSE Azure/azure-sdk-for-go,https://github.com/Azure/azure-sdk-for-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/Azure/azure-sdk-for-go/master/LICENSE Azure/go-ansiterm,https://github.com/Azure/go-ansiterm/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/Azure/go-ansiterm/master/LICENSE Azure/go-autorest,https://github.com/Azure/go-autorest/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/Azure/go-autorest/master/LICENSE BurntSushi/toml,https://github.com/BurntSushi/toml/blob/master/COPYING,MIT License,https://raw.githubusercontent.com/BurntSushi/toml/master/COPYING BurntSushi/xgb,https://github.com/BurntSushi/xgb/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/BurntSushi/xgb/master/LICENSE GoogleCloudPlatform/k8s-cloud-provider,https://github.com/GoogleCloudPlatform/k8s-cloud-provider/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-cloud-provider/master/LICENSE JeffAshton/win_pdh,https://github.com/JeffAshton/win_pdh/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/JeffAshton/win_pdh/master/LICENSE MakeNowJust/heredoc,https://github.com/MakeNowJust/heredoc/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/MakeNowJust/heredoc/master/LICENSE Microsoft/go-winio,https://github.com/microsoft/go-winio/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/microsoft/go-winio/master/LICENSE Microsoft/hcsshim,https://github.com/microsoft/hcsshim/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/microsoft/hcsshim/master/LICENSE NYTimes/gziphandler,https://github.com/nytimes/gziphandler/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/nytimes/gziphandler/master/LICENSE PuerkitoBio/purell,https://github.com/PuerkitoBio/purell/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/PuerkitoBio/purell/master/LICENSE PuerkitoBio/urlesc,https://github.com/PuerkitoBio/urlesc/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/PuerkitoBio/urlesc/master/LICENSE Rican7/retry,https://github.com/Rican7/retry/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/Rican7/retry/master/LICENSE Sirupsen/logrus,https://github.com/sirupsen/logrus/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/sirupsen/logrus/master/LICENSE alecthomas/template,https://github.com/alecthomas/template/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/alecthomas/template/master/LICENSE alecthomas/units,https://github.com/alecthomas/units/blob/master/COPYING,MIT License,https://raw.githubusercontent.com/alecthomas/units/master/COPYING appscode/jsonpatch,https://github.com/gomodules/jsonpatch/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/gomodules/jsonpatch/master/LICENSE armon/circbuf,https://github.com/armon/circbuf/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/armon/circbuf/master/LICENSE armon/consul-api,https://github.com/armon/consul-api/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/armon/consul-api/master/LICENSE asaskevich/govalidator,https://github.com/asaskevich/govalidator/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/asaskevich/govalidator/master/LICENSE auth0/go-jwt-middleware,https://github.com/auth0/go-jwt-middleware/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/auth0/go-jwt-middleware/master/LICENSE aws/aws-sdk-go,https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt,Apache License 2.0,https://raw.githubusercontent.com/aws/aws-sdk-go/master/LICENSE.txt bazelbuild/bazel-gazelle,https://github.com/bazelbuild/bazel-gazelle/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/bazelbuild/bazel-gazelle/master/LICENSE bazelbuild/buildtools,https://github.com/bazelbuild/buildtools/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/bazelbuild/buildtools/master/LICENSE beorn7/perks,https://github.com/beorn7/perks/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/beorn7/perks/master/LICENSE bgentry/go-netrc,https://github.com/bgentry/go-netrc/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/bgentry/go-netrc/master/LICENSE blang/semver,https://github.com/blang/semver/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/blang/semver/master/LICENSE boltdb/bolt,https://github.com/boltdb/bolt/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/boltdb/bolt/master/LICENSE cenkalti/backoff,https://github.com/cenkalti/backoff/blob/v4/LICENSE,MIT License,https://raw.githubusercontent.com/cenkalti/backoff/v4/LICENSE cespare/prettybench,https://github.com/cespare/prettybench/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/cespare/prettybench/master/LICENSE.txt chai2010/gettext-go,https://github.com/chai2010/gettext-go/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/chai2010/gettext-go/master/LICENSE cheggaaa/pb,https://github.com/cheggaaa/pb/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/cheggaaa/pb/master/LICENSE client9/misspell,https://github.com/client9/misspell/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/client9/misspell/master/LICENSE cloudflare/cfssl,https://github.com/cloudflare/cfssl/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/cloudflare/cfssl/master/LICENSE clusterhq/flocker-go,https://github.com/ClusterHQ/flocker-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/ClusterHQ/flocker-go/master/LICENSE codedellemc/goscaleio,https://github.com/thecodeteam/goscaleio/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/thecodeteam/goscaleio/master/LICENSE codegangsta/negroni,https://github.com/urfave/negroni/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/urfave/negroni/master/LICENSE container-storage-interface/spec,https://github.com/container-storage-interface/spec/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/container-storage-interface/spec/master/LICENSE containerd/console,https://github.com/containerd/console/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/containerd/console/master/LICENSE containerd/containerd,https://github.com/containerd/containerd/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/containerd/containerd/master/LICENSE containerd/typeurl,https://github.com/containerd/typeurl/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/containerd/typeurl/master/LICENSE containernetworking/cni,https://github.com/containernetworking/cni/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/containernetworking/cni/master/LICENSE coreos/bbolt,https://github.com/etcd-io/bbolt/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/etcd-io/bbolt/master/LICENSE coreos/etcd,https://github.com/etcd-io/etcd/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/etcd-io/etcd/master/LICENSE coreos/go-etcd,https://github.com/coreos/go-etcd/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/coreos/go-etcd/master/LICENSE coreos/go-oidc,https://github.com/coreos/go-oidc/blob/v2/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/coreos/go-oidc/v2/LICENSE coreos/go-semver,https://github.com/coreos/go-semver/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/coreos/go-semver/master/LICENSE coreos/go-systemd,https://github.com/coreos/go-systemd/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/coreos/go-systemd/master/LICENSE coreos/pkg,https://github.com/coreos/pkg/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/coreos/pkg/master/LICENSE coreos/rkt,https://github.com/rkt/rkt/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/rkt/rkt/master/LICENSE cpuguy83/go-md2man,https://github.com/cpuguy83/go-md2man/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/cpuguy83/go-md2man/master/LICENSE.md cyphar/filepath-securejoin,https://github.com/cyphar/filepath-securejoin/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/cyphar/filepath-securejoin/master/LICENSE d2g/dhcp4,https://github.com/d2g/dhcp4/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/d2g/dhcp4/master/LICENSE d2g/dhcp4client,https://github.com/d2g/dhcp4client/blob/v1/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/d2g/dhcp4client/v1/LICENSE davecgh/go-spew,https://github.com/davecgh/go-spew/blob/master/LICENSE,ISC License,https://raw.githubusercontent.com/davecgh/go-spew/master/LICENSE daviddengcn/go-colortext,https://github.com/daviddengcn/go-colortext/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/daviddengcn/go-colortext/master/LICENSE deckarep/golang-set,https://github.com/deckarep/golang-set/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/deckarep/golang-set/master/LICENSE dgrijalva/jwt-go,https://github.com/dgrijalva/jwt-go/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/dgrijalva/jwt-go/master/LICENSE dnaeon/go-vcr,https://github.com/dnaeon/go-vcr/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/dnaeon/go-vcr/master/LICENSE docker/distribution,https://github.com/docker/distribution/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/docker/distribution/master/LICENSE docker/docker,https://github.com/moby/moby/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/moby/moby/master/LICENSE docker/go-connections,https://github.com/docker/go-connections/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/docker/go-connections/master/LICENSE docker/go-units,https://github.com/docker/go-units/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/docker/go-units/master/LICENSE docker/libnetwork,https://github.com/docker/libnetwork/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/docker/libnetwork/master/LICENSE docker/spdystream,https://github.com/docker/spdystream/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/docker/spdystream/master/LICENSE elazarl/goproxy,https://github.com/elazarl/goproxy/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/elazarl/goproxy/master/LICENSE emicklei/go-restful,https://github.com/emicklei/go-restful/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/emicklei/go-restful/master/LICENSE euank/go-kmsg-parser,https://github.com/euank/go-kmsg-parser/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/euank/go-kmsg-parser/master/LICENSE exponent-io/jsonpath,https://github.com/exponent-io/jsonpath/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/exponent-io/jsonpath/master/LICENSE fatih/camelcase,https://github.com/fatih/camelcase/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/fatih/camelcase/master/LICENSE.md fatih/color,https://github.com/fatih/color/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/fatih/color/master/LICENSE.md fsnotify/fsnotify,https://github.com/fsnotify/fsnotify/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/fsnotify/fsnotify/master/LICENSE ghodss/yaml,https://github.com/ghodss/yaml/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/ghodss/yaml/master/LICENSE globalsign/mgo,https://github.com/globalsign/mgo/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/globalsign/mgo/master/LICENSE go-kit/kit,https://github.com/go-kit/kit/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/go-kit/kit/master/LICENSE go-logfmt/logfmt,https://github.com/go-logfmt/logfmt/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/go-logfmt/logfmt/master/LICENSE go-logr/logr,https://github.com/go-logr/logr/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-logr/logr/master/LICENSE go-logr/zapr,https://github.com/go-logr/zapr/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-logr/zapr/master/LICENSE go-openapi/analysis,https://github.com/go-openapi/analysis/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/analysis/master/LICENSE go-openapi/errors,https://github.com/go-openapi/errors/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE go-openapi/jsonpointer,https://github.com/go-openapi/jsonpointer/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE go-openapi/jsonreference,https://github.com/go-openapi/jsonreference/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE go-openapi/loads,https://github.com/go-openapi/loads/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/loads/master/LICENSE go-openapi/runtime,https://github.com/go-openapi/runtime/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/runtime/master/LICENSE go-openapi/spec,https://github.com/go-openapi/spec/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/spec/master/LICENSE go-openapi/strfmt,https://github.com/go-openapi/strfmt/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/strfmt/master/LICENSE go-openapi/swag,https://github.com/go-openapi/swag/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/swag/master/LICENSE go-openapi/validate,https://github.com/go-openapi/validate/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-openapi/validate/master/LICENSE go-ozzo/ozzo-validation,https://github.com/go-ozzo/ozzo-validation/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/go-ozzo/ozzo-validation/master/LICENSE go-stack/stack,https://github.com/go-stack/stack/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/go-stack/stack/master/LICENSE.md godbus/dbus,https://github.com/godbus/dbus/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/godbus/dbus/master/LICENSE gogo/protobuf,https://github.com/gogo/protobuf/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/gogo/protobuf/master/LICENSE golang/glog,https://github.com/golang/glog/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/golang/glog/master/LICENSE golang/groupcache,https://github.com/golang/groupcache/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/golang/groupcache/master/LICENSE golang/mock,https://github.com/golang/mock/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/golang/mock/master/LICENSE golang/protobuf,https://github.com/golang/protobuf/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/protobuf/master/LICENSE golangplus/bytes,https://github.com/golangplus/bytes/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golangplus/bytes/master/LICENSE golangplus/fmt,https://github.com/golangplus/fmt/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golangplus/fmt/master/LICENSE golangplus/testing,https://github.com/golangplus/testing/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golangplus/testing/master/LICENSE google/btree,https://github.com/google/btree/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/btree/master/LICENSE google/cadvisor,https://github.com/google/cadvisor/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/cadvisor/master/LICENSE google/certificate-transparency-go,https://github.com/google/certificate-transparency-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/certificate-transparency-go/master/LICENSE google/go-cmp,https://github.com/google/go-cmp/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/google/go-cmp/master/LICENSE google/gofuzz,https://github.com/google/gofuzz/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/gofuzz/master/LICENSE google/martian,https://github.com/google/martian/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/martian/master/LICENSE google/pprof,https://github.com/google/pprof/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/pprof/master/LICENSE google/renameio,https://github.com/google/renameio/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/google/renameio/master/LICENSE google/uuid,https://github.com/google/uuid/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/google/uuid/master/LICENSE googleapis/gnostic,https://github.com/googleapis/gnostic/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/googleapis/gnostic/master/LICENSE gophercloud/gophercloud,https://github.com/gophercloud/gophercloud/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/gophercloud/gophercloud/master/LICENSE gopherjs/gopherjs,https://github.com/gopherjs/gopherjs/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/gopherjs/gopherjs/master/LICENSE gorilla/context,https://github.com/gorilla/context/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/gorilla/context/master/LICENSE gorilla/mux,https://github.com/gorilla/mux/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/gorilla/mux/master/LICENSE gorilla/websocket,https://github.com/gorilla/websocket/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/gorilla/websocket/master/LICENSE gregjones/httpcache,https://github.com/gregjones/httpcache/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/gregjones/httpcache/master/LICENSE.txt grpc-ecosystem/go-grpc-middleware,https://github.com/grpc-ecosystem/go-grpc-middleware/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/grpc-ecosystem/go-grpc-middleware/master/LICENSE grpc-ecosystem/go-grpc-prometheus,https://github.com/grpc-ecosystem/go-grpc-prometheus/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/grpc-ecosystem/go-grpc-prometheus/master/LICENSE grpc-ecosystem/grpc-gateway,https://github.com/grpc-ecosystem/grpc-gateway/blob/master/LICENSE.txt,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/master/LICENSE.txt hashicorp/go-cleanhttp,https://github.com/hashicorp/go-cleanhttp/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/hashicorp/go-cleanhttp/master/LICENSE hashicorp/go-getter,https://github.com/hashicorp/go-getter/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/hashicorp/go-getter/master/LICENSE hashicorp/go-safetemp,https://github.com/hashicorp/go-safetemp/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/hashicorp/go-safetemp/master/LICENSE hashicorp/go-version,https://github.com/hashicorp/go-version/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/hashicorp/go-version/master/LICENSE hashicorp/golang-lru,https://github.com/hashicorp/golang-lru/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/hashicorp/golang-lru/master/LICENSE hashicorp/hcl,https://github.com/hashicorp/hcl/blob/master/LICENSE,Mozilla Public License 2.0,https://raw.githubusercontent.com/hashicorp/hcl/master/LICENSE heketi/heketi,https://github.com/heketi/heketi/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/heketi/heketi/master/LICENSE heketi/rest,https://github.com/heketi/rest/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/heketi/rest/master/LICENSE heketi/tests,https://github.com/heketi/tests/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/heketi/tests/master/LICENSE hpcloud/tail,https://github.com/hpcloud/tail/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/hpcloud/tail/master/LICENSE.txt imdario/mergo,https://github.com/imdario/mergo/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/imdario/mergo/master/LICENSE inconshreveable/mousetrap,https://github.com/inconshreveable/mousetrap/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/inconshreveable/mousetrap/master/LICENSE jmespath/go-jmespath,https://github.com/jmespath/go-jmespath/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/jmespath/go-jmespath/master/LICENSE jonboulle/clockwork,https://github.com/jonboulle/clockwork/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/jonboulle/clockwork/master/LICENSE json-iterator/go,https://github.com/json-iterator/go/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/json-iterator/go/master/LICENSE jstemmer/go-junit-report,https://github.com/jstemmer/go-junit-report/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/jstemmer/go-junit-report/master/LICENSE jteeuwen/go-bindata,https://github.com/jteeuwen/go-bindata/blob/master/LICENSE,Public Domain Dedication,https://raw.githubusercontent.com/jteeuwen/go-bindata/master/LICENSE jtolds/gls,https://github.com/jtolds/gls/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/jtolds/gls/master/LICENSE julienschmidt/httprouter,https://github.com/julienschmidt/httprouter/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/julienschmidt/httprouter/master/LICENSE kardianos/osext,https://github.com/kardianos/osext/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/kardianos/osext/master/LICENSE karrick/godirwalk,https://github.com/karrick/godirwalk/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/karrick/godirwalk/master/LICENSE kisielk/errcheck,https://github.com/kisielk/errcheck/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/kisielk/errcheck/master/LICENSE kisielk/gotool,https://github.com/kisielk/gotool/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/kisielk/gotool/master/LICENSE konsorten/go-windows-terminal-sequences,https://github.com/konsorten/go-windows-terminal-sequences/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/konsorten/go-windows-terminal-sequences/master/LICENSE kr/fs,https://github.com/kr/fs/blob/main/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/kr/fs/main/LICENSE kr/pretty,https://github.com/kr/pretty/blob/main/License,MIT License,https://raw.githubusercontent.com/kr/pretty/main/License kr/pty,https://github.com/kr/pty/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/kr/pty/master/LICENSE kr/text,https://github.com/kr/text/blob/main/License,MIT License,https://raw.githubusercontent.com/kr/text/main/License kubeflow/kubeflow,https://github.com/kubeflow/kubeflow/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubeflow/kubeflow/master/LICENSE kubernetes-sigs/application,https://github.com/kubernetes-sigs/application/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes-sigs/application/master/LICENSE libopenstorage/openstorage,https://github.com/libopenstorage/openstorage/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/libopenstorage/openstorage/master/LICENSE liggitt/tabwriter,https://github.com/liggitt/tabwriter/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/liggitt/tabwriter/master/LICENSE lithammer/dedent,https://github.com/lithammer/dedent/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/lithammer/dedent/master/LICENSE lpabon/godbc,https://github.com/lpabon/godbc/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/lpabon/godbc/master/LICENSE magiconair/properties,https://github.com/magiconair/properties/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/magiconair/properties/master/LICENSE mailru/easyjson,https://github.com/mailru/easyjson/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mailru/easyjson/master/LICENSE marstr/guid,https://github.com/marstr/guid/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/marstr/guid/master/LICENSE.txt mattn/go-colorable,https://github.com/mattn/go-colorable/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mattn/go-colorable/master/LICENSE mattn/go-isatty,https://github.com/mattn/go-isatty/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mattn/go-isatty/master/LICENSE mattn/go-runewidth,https://github.com/mattn/go-runewidth/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mattn/go-runewidth/master/LICENSE mattn/go-shellwords,https://github.com/mattn/go-shellwords/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mattn/go-shellwords/master/LICENSE matttproud/golang_protobuf_extensions,https://github.com/matttproud/golang_protobuf_extensions/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/matttproud/golang_protobuf_extensions/master/LICENSE mesos/mesos-go,https://github.com/mesos/mesos-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/mesos/mesos-go/master/LICENSE mholt/caddy,https://github.com/caddyserver/caddy/blob/master/LICENSE.txt,Apache License 2.0,https://raw.githubusercontent.com/caddyserver/caddy/master/LICENSE.txt miekg/dns,https://github.com/miekg/dns/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/miekg/dns/master/LICENSE mindprince/gonvml,https://github.com/mindprince/gonvml/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/mindprince/gonvml/master/LICENSE mistifyio/go-zfs,https://github.com/mistifyio/go-zfs/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/mistifyio/go-zfs/master/LICENSE mitchellh/go-homedir,https://github.com/mitchellh/go-homedir/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mitchellh/go-homedir/master/LICENSE mitchellh/go-testing-interface,https://github.com/mitchellh/go-testing-interface/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mitchellh/go-testing-interface/master/LICENSE mitchellh/go-wordwrap,https://github.com/mitchellh/go-wordwrap/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/mitchellh/go-wordwrap/master/LICENSE.md mitchellh/mapstructure,https://github.com/mitchellh/mapstructure/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mitchellh/mapstructure/master/LICENSE modern-go/concurrent,https://github.com/modern-go/concurrent/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE modern-go/reflect2,https://github.com/modern-go/reflect2/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/modern-go/reflect2/master/LICENSE mohae/deepcopy,https://github.com/mohae/deepcopy/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/mohae/deepcopy/master/LICENSE morikuni/aec,https://github.com/morikuni/aec/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/morikuni/aec/master/LICENSE mrunalp/fileutils,https://github.com/mrunalp/fileutils/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/mrunalp/fileutils/master/LICENSE munnerz/goautoneg,https://github.com/munnerz/goautoneg/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/munnerz/goautoneg/master/LICENSE mvdan/xurls,https://github.com/mvdan/xurls/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/mvdan/xurls/master/LICENSE mwitkow/go-conntrack,https://github.com/mwitkow/go-conntrack/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/mwitkow/go-conntrack/master/LICENSE mxk/go-flowrate,https://github.com/mxk/go-flowrate/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/mxk/go-flowrate/master/LICENSE natefinch/lumberjack,https://github.com/natefinch/lumberjack/blob/v2.0/LICENSE,MIT License,https://raw.githubusercontent.com/natefinch/lumberjack/v2.0/LICENSE onrik/logrus,https://github.com/onrik/logrus/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/onrik/logrus/master/LICENSE onsi/ginkgo,https://github.com/onsi/ginkgo/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/onsi/ginkgo/master/LICENSE onsi/gomega,https://github.com/onsi/gomega/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/onsi/gomega/master/LICENSE opencontainers/go-digest,https://github.com/opencontainers/go-digest/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/opencontainers/go-digest/master/LICENSE opencontainers/image-spec,https://github.com/opencontainers/image-spec/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/opencontainers/image-spec/master/LICENSE opencontainers/runc,https://github.com/opencontainers/runc/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/opencontainers/runc/master/LICENSE opencontainers/runtime-spec,https://github.com/opencontainers/runtime-spec/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/opencontainers/runtime-spec/master/LICENSE opencontainers/selinux,https://github.com/opencontainers/selinux/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/opencontainers/selinux/master/LICENSE otiai10/copy,https://github.com/otiai10/copy/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/otiai10/copy/master/LICENSE otiai10/curr,https://github.com/otiai10/curr/blob/master/LICENSE,Do What The Fuck You Want To Public License Version 2,https://raw.githubusercontent.com/otiai10/curr/master/LICENSE otiai10/mint,https://github.com/otiai10/mint/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/otiai10/mint/master/LICENSE pborman/uuid,https://github.com/pborman/uuid/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/pborman/uuid/master/LICENSE pelletier/go-toml,https://github.com/pelletier/go-toml/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/pelletier/go-toml/master/LICENSE peterbourgon/diskv,https://github.com/peterbourgon/diskv/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/peterbourgon/diskv/master/LICENSE pkg/errors,https://github.com/pkg/errors/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/pkg/errors/master/LICENSE pkg/sftp,https://github.com/pkg/sftp/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/pkg/sftp/master/LICENSE pmezard/go-difflib,https://github.com/pmezard/go-difflib/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/pmezard/go-difflib/master/LICENSE pquerna/cachecontrol,https://github.com/pquerna/cachecontrol/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/pquerna/cachecontrol/master/LICENSE pquerna/ffjson,https://github.com/pquerna/ffjson/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/pquerna/ffjson/master/LICENSE prometheus/client_golang,https://github.com/prometheus/client_golang/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/prometheus/client_golang/master/LICENSE prometheus/client_model,https://github.com/prometheus/client_model/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/prometheus/client_model/master/LICENSE prometheus/common,https://github.com/prometheus/common/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/prometheus/common/master/LICENSE prometheus/procfs,https://github.com/prometheus/procfs/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/prometheus/procfs/master/LICENSE quobyte/api,https://github.com/quobyte/api/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/quobyte/api/master/LICENSE remyoudompheng/bigfft,https://github.com/remyoudompheng/bigfft/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/remyoudompheng/bigfft/master/LICENSE robfig/cron,https://github.com/robfig/cron/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/robfig/cron/master/LICENSE rogpeppe/go-charset,https://github.com/rogpeppe/go-charset/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/rogpeppe/go-charset/master/LICENSE rogpeppe/go-internal,https://github.com/rogpeppe/go-internal/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/rogpeppe/go-internal/master/LICENSE rubiojr/go-vhd,https://github.com/rubiojr/go-vhd/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/rubiojr/go-vhd/master/LICENSE russross/blackfriday,https://github.com/russross/blackfriday/blob/master/LICENSE.txt,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/russross/blackfriday/master/LICENSE.txt satori/go.uuid,https://github.com/satori/go.uuid/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/satori/go.uuid/master/LICENSE seccomp/libseccomp-golang,https://github.com/seccomp/libseccomp-golang/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/seccomp/libseccomp-golang/master/LICENSE shurcooL/sanitized_anchor_name,https://github.com/shurcooL/sanitized_anchor_name/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/shurcooL/sanitized_anchor_name/master/LICENSE sigma/go-inotify,https://github.com/sigma/go-inotify/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/sigma/go-inotify/master/LICENSE sirupsen/logrus,https://github.com/sirupsen/logrus/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/sirupsen/logrus/master/LICENSE smartystreets/assertions,https://github.com/smartystreets/assertions/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/smartystreets/assertions/master/LICENSE.md smartystreets/goconvey,https://github.com/smartystreets/goconvey/blob/master/LICENSE.md,MIT License,https://raw.githubusercontent.com/smartystreets/goconvey/master/LICENSE.md soheilhy/cmux,https://github.com/soheilhy/cmux/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/soheilhy/cmux/master/LICENSE spf13/afero,https://github.com/spf13/afero/blob/master/LICENSE.txt,Apache License 2.0,https://raw.githubusercontent.com/spf13/afero/master/LICENSE.txt spf13/cast,https://github.com/spf13/cast/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/spf13/cast/master/LICENSE spf13/cobra,https://github.com/spf13/cobra/blob/master/LICENSE.txt,Apache License 2.0,https://raw.githubusercontent.com/spf13/cobra/master/LICENSE.txt spf13/jwalterweatherman,https://github.com/spf13/jwalterweatherman/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/spf13/jwalterweatherman/master/LICENSE spf13/pflag,https://github.com/spf13/pflag/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/spf13/pflag/master/LICENSE spf13/viper,https://github.com/spf13/viper/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/spf13/viper/master/LICENSE storageos/go-api,https://github.com/storageos/go-api/blob/master/LICENCE,MIT License,https://raw.githubusercontent.com/storageos/go-api/master/LICENCE stretchr/objx,https://github.com/stretchr/objx/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/stretchr/objx/master/LICENSE stretchr/testify,https://github.com/stretchr/testify/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/stretchr/testify/master/LICENSE syndtr/gocapability,https://github.com/syndtr/gocapability/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/syndtr/gocapability/master/LICENSE tmc/grpc-websocket-proxy,https://github.com/tmc/grpc-websocket-proxy/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/tmc/grpc-websocket-proxy/master/LICENSE ugorji/go,https://github.com/ugorji/go/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/ugorji/go/master/LICENSE ulikunitz/xz,https://github.com/ulikunitz/xz/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/ulikunitz/xz/master/LICENSE urfave/negroni,https://github.com/urfave/negroni/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/urfave/negroni/master/LICENSE vishvananda/netlink,https://github.com/vishvananda/netlink/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/vishvananda/netlink/master/LICENSE vishvananda/netns,https://github.com/vishvananda/netns/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/vishvananda/netns/master/LICENSE vmware/govmomi,https://github.com/vmware/govmomi/blob/master/LICENSE.txt,Apache License 2.0,https://raw.githubusercontent.com/vmware/govmomi/master/LICENSE.txt vmware/photon-controller-go-sdk,https://github.com/vmware/photon-controller-go-sdk/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/vmware/photon-controller-go-sdk/master/LICENSE xanzy/go-cloudstack,https://github.com/xanzy/go-cloudstack/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/xanzy/go-cloudstack/master/LICENSE xiang90/probing,https://github.com/xiang90/probing/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/xiang90/probing/master/LICENSE xlab/handysort,https://github.com/xlab/handysort/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/xlab/handysort/master/LICENSE xordataexchange/crypt,https://github.com/xordataexchange/crypt/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/xordataexchange/crypt/master/LICENSE census-instrumentation/opencensus-go,https://github.com/census-instrumentation/opencensus-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/census-instrumentation/opencensus-go/master/LICENSE uber-go/atomic,https://github.com/uber-go/atomic/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/uber-go/atomic/master/LICENSE.txt uber-go/multierr,https://github.com/uber-go/multierr/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/uber-go/multierr/master/LICENSE.txt uber-go/tools,https://github.com/uber-go/tools/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/uber-go/tools/master/LICENSE uber-go/zap,https://github.com/uber-go/zap/blob/master/LICENSE.txt,MIT License,https://raw.githubusercontent.com/uber-go/zap/master/LICENSE.txt golang/crypto,https://github.com/golang/crypto/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/crypto/master/LICENSE golang/exp,https://github.com/golang/exp/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/exp/master/LICENSE golang/image,https://github.com/golang/image/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/image/master/LICENSE golang/mobile,https://github.com/golang/mobile/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/mobile/master/LICENSE golang/mod,https://github.com/golang/mod/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/mod/master/LICENSE golang/net,https://github.com/golang/net/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/net/master/LICENSE golang/oauth2,https://github.com/golang/oauth2/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/oauth2/master/LICENSE golang/sync,https://github.com/golang/sync/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/sync/master/LICENSE golang/sys,https://github.com/golang/sys/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/sys/master/LICENSE golang/text,https://github.com/golang/text/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/text/master/LICENSE golang/time,https://github.com/golang/time/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/time/master/LICENSE golang/tools,https://github.com/golang/tools/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/tools/master/LICENSE golang/xerrors,https://github.com/golang/xerrors/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/golang/xerrors/master/LICENSE gomodules/jsonpatch,https://github.com/gomodules/jsonpatch/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/gomodules/jsonpatch/master/LICENSE gonum/gonum,https://github.com/gonum/gonum/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/gonum/gonum/master/LICENSE gonum/netlib,https://github.com/gonum/netlib/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/gonum/netlib/master/LICENSE google/google-api-go-client,https://github.com/googleapis/google-api-go-client/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/googleapis/google-api-go-client/master/LICENSE golang/appengine,https://github.com/golang/appengine/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/golang/appengine/master/LICENSE google/go-genproto,https://github.com/googleapis/go-genproto/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/googleapis/go-genproto/master/LICENSE grpc/grpc-go,https://github.com/grpc/grpc-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/grpc/grpc-go/master/LICENSE airbrake/gobrake,https://github.com/airbrake/gobrake/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/airbrake/gobrake/master/LICENSE alecthomas/kingpin,https://github.com/alecthomas/kingpin/blob/master/COPYING,MIT License,https://raw.githubusercontent.com/alecthomas/kingpin/master/COPYING go-check/check,https://github.com/go-check/check/blob/v1/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/go-check/check/v1/LICENSE go-errgo/errgo,https://github.com/go-errgo/errgo/blob/v1/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/go-errgo/errgo/v1/LICENSE go-gcfg/gcfg,https://github.com/go-gcfg/gcfg/blob/v1/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/go-gcfg/gcfg/v1/LICENSE gemnasium/logrus-airbrake-hook,https://github.com/gemnasium/logrus-airbrake-hook/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/gemnasium/logrus-airbrake-hook/master/LICENSE go-inf/inf,https://github.com/go-inf/inf/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/go-inf/inf/master/LICENSE square/go-jose,https://github.com/square/go-jose/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/square/go-jose/master/LICENSE src-d/go-billy,https://github.com/src-d/go-billy/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/src-d/go-billy/master/LICENSE src-d/go-git-fixtures,https://github.com/src-d/go-git-fixtures/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/src-d/go-git-fixtures/master/LICENSE src-d/go-git,https://github.com/src-d/go-git/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/src-d/go-git/master/LICENSE go-tomb/tomb,https://github.com/go-tomb/tomb/blob/v1/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/go-tomb/tomb/v1/LICENSE go-warnings/warnings,https://github.com/go-warnings/warnings/blob/master/LICENSE,BSD 2-Clause "Simplified" License,https://raw.githubusercontent.com/go-warnings/warnings/master/LICENSE go-yaml/yaml,https://github.com/go-yaml/yaml/blob/v2/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/go-yaml/yaml/v2/LICENSE gotestyourself/gotest.tools,https://github.com/gotestyourself/gotest.tools/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/gotestyourself/gotest.tools/master/LICENSE go4org/grpc,https://github.com/go4org/grpc/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://raw.githubusercontent.com/go4org/grpc/master/LICENSE dominikh/go-tools,https://github.com/dominikh/go-tools/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/dominikh/go-tools/master/LICENSE kubernetes/api,https://github.com/kubernetes/api/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/api/master/LICENSE kubernetes/apiextensions-apiserver,https://github.com/kubernetes/apiextensions-apiserver/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/apiextensions-apiserver/master/LICENSE kubernetes/apimachinery,https://github.com/kubernetes/apimachinery/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/apimachinery/master/LICENSE kubernetes/apiserver,https://github.com/kubernetes/apiserver/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/apiserver/master/LICENSE kubernetes/cli-runtime,https://github.com/kubernetes/cli-runtime/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/cli-runtime/master/LICENSE kubernetes/client-go,https://github.com/kubernetes/client-go/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/client-go/master/LICENSE kubernetes/cloud-provider,https://github.com/kubernetes/cloud-provider/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/cloud-provider/master/LICENSE kubernetes/cluster-bootstrap,https://github.com/kubernetes/cluster-bootstrap/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/cluster-bootstrap/master/LICENSE kubernetes/code-generator,https://github.com/kubernetes/code-generator/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/code-generator/master/LICENSE kubernetes/component-base,https://github.com/kubernetes/component-base/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/component-base/master/LICENSE kubernetes/cri-api,https://github.com/kubernetes/cri-api/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/cri-api/master/LICENSE kubernetes/csi-translation-lib,https://github.com/kubernetes/csi-translation-lib/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/csi-translation-lib/master/LICENSE kubernetes/gengo,https://github.com/kubernetes/gengo/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/gengo/master/LICENSE kubernetes/heapster,https://github.com/kubernetes-retired/heapster/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes-retired/heapster/master/LICENSE kubernetes/klog,https://github.com/kubernetes/klog/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/klog/master/LICENSE kubernetes/kube-aggregator,https://github.com/kubernetes/kube-aggregator/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kube-aggregator/master/LICENSE kubernetes/kube-controller-manager,https://github.com/kubernetes/kube-controller-manager/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kube-controller-manager/master/LICENSE kubernetes/kube-openapi,https://github.com/kubernetes/kube-openapi/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kube-openapi/master/LICENSE kubernetes/kube-proxy,https://github.com/kubernetes/kube-proxy/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kube-proxy/master/LICENSE kubernetes/kube-scheduler,https://github.com/kubernetes/kube-scheduler/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kube-scheduler/master/LICENSE kubernetes/kubelet,https://github.com/kubernetes/kubelet/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kubelet/master/LICENSE kubernetes/kubernetes,https://github.com/kubernetes/kubernetes/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/kubernetes/master/LICENSE kubernetes/legacy-cloud-providers,https://github.com/kubernetes/legacy-cloud-providers/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/legacy-cloud-providers/master/LICENSE kubernetes/metrics,https://github.com/kubernetes/metrics/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/metrics/master/LICENSE kubernetes/repo-infra,https://github.com/kubernetes/repo-infra/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/repo-infra/master/LICENSE kubernetes/sample-apiserver,https://github.com/kubernetes/sample-apiserver/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/sample-apiserver/master/LICENSE kubernetes/utils,https://github.com/kubernetes/utils/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes/utils/master/LICENSE kubernetes-sigs/controller-runtime,https://github.com/kubernetes-sigs/controller-runtime/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/master/LICENSE kubernetes-sigs/kustomize,https://github.com/kubernetes-sigs/kustomize/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/LICENSE kubernetes-sigs/structured-merge-diff,https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes-sigs/structured-merge-diff/master/LICENSE kubernetes-sigs/testing_frameworks,https://github.com/kubernetes-sigs/testing_frameworks/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/kubernetes-sigs/testing_frameworks/master/LICENSE kubernetes-sigs/yaml,https://github.com/kubernetes-sigs/yaml/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/kubernetes-sigs/yaml/master/LICENSE sourcegraph/go-diff,https://github.com/sourcegraph/go-diff/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/sourcegraph/go-diff/master/LICENSE sqs/pbtypes,https://github.com/sqs/pbtypes/blob/master/LICENSE,Apache License 2.0,https://raw.githubusercontent.com/sqs/pbtypes/master/LICENSE fvbommel/util,https://github.com/fvbommel/util/blob/master/LICENSE,MIT License,https://raw.githubusercontent.com/fvbommel/util/master/LICENSE bitbucket.org/bertimus9/systemstat,https://bitbucket.org/bertimus9/systemstat/src/master/LICENSE,MIT License,https://bitbucket.org/bertimus9/systemstat/src/master/LICENSE modernc.org/cc,https://gitlab.com/cznic/cc/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://gitlab.com/cznic/cc/blob/master/LICENSE modernc.org/golex,https://gitlab.com/cznic/golex/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://gitlab.com/cznic/golex/blob/master/LICENSE modernc.org/mathutil,https://gitlab.com/cznic/mathutil/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://gitlab.com/cznic/mathutl/blob/master/LICENSE modernc.org/strutil,https://gitlab.com/cznic/strutil/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://gitlab.com/cznic/strutil/blob/master/LICENSE modernc.org/xc,https://gitlab.com/cznic/xc/blob/master/LICENSE,BSD 3-Clause "New" or "Revised" License,https://gitlab.com/cznic/xc/blob/master/LICENSE heketi/utils,https://github.com/heketi/heketi/blob/master/LICENSE,Apache License 2.0,https://github.com/heketi/heketi/blob/master/LICENSE kr/logfmt,https://github.com/kr/logfmt/blob/master/Readme,MIT License,https://github.com/kr/logfmt/blob/master/Readme