mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-11 23:32:53 +00:00
Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2376b697af | ||
|
|
eff358e27e | ||
|
|
243ac62e3f | ||
|
|
a368370bef | ||
|
|
9366fab980 | ||
|
|
13e1eeabfe | ||
|
|
3239b3e9d5 | ||
|
|
dbd0aa4915 | ||
|
|
3d3b9e312a | ||
|
|
a0d2fc2f0e | ||
|
|
54aa75a4cd | ||
|
|
c8f4b60b5b | ||
|
|
695715ff6a | ||
|
|
841d64982a | ||
|
|
0a53aeebbc | ||
|
|
dae5230aae | ||
|
|
4c76fc9ffa | ||
|
|
c3cac0a9a7 | ||
|
|
b4465e92b8 | ||
|
|
2d48ac79c2 | ||
|
|
e61308908c | ||
|
|
94a9522f75 | ||
|
|
b968813058 | ||
|
|
4048c020a8 | ||
|
|
6e86a83cf3 | ||
|
|
0b8e2cbbe5 | ||
|
|
f4cc7cd4de | ||
|
|
fcf0f3e5c2 | ||
|
|
7b1126ff28 | ||
|
|
ae1f4e284f | ||
|
|
a191363ee6 | ||
|
|
e5e7c025dd | ||
|
|
7abd2c6db9 | ||
|
|
af79f96513 | ||
|
|
c58331d408 | ||
|
|
043c628fa5 | ||
|
|
e9820b985c | ||
|
|
c8c2e710b0 | ||
|
|
43305ec788 | ||
|
|
5ad7a55445 | ||
|
|
a7e9fbaf79 | ||
|
|
3c94b36be4 | ||
|
|
2af9d6a52a | ||
|
|
e7b413c7de | ||
|
|
6a8dca6b84 | ||
|
|
63f7690f44 | ||
|
|
0bdd6ef5a4 | ||
|
|
0daea437d6 | ||
|
|
6a895be415 | ||
|
|
b0fd3d35c1 | ||
|
|
b71173228a | ||
|
|
dd11b175ec | ||
|
|
8a2a852b87 | ||
|
|
f34aab251e | ||
|
|
69cceb0d7e | ||
|
|
c29a3a4ea0 | ||
|
|
d1b188421f | ||
|
|
a728ea8015 | ||
|
|
9518ac898a | ||
|
|
07da583e37 | ||
|
|
30051e679d | ||
|
|
a5346c1a87 | ||
|
|
13afbf39a1 | ||
|
|
e1eba6f4a6 | ||
|
|
5643b0f634 | ||
|
|
d9d9dc60da | ||
|
|
1c80ba903e | ||
|
|
2fd9d900ff | ||
|
|
305732b306 | ||
|
|
ac2905b479 | ||
|
|
7ca08730af | ||
|
|
0f934bc406 | ||
|
|
eaec20f2fe | ||
|
|
1de9556707 | ||
|
|
e7b668af2a | ||
|
|
be48119c50 | ||
|
|
6aecc0f6b1 | ||
|
|
86878063d9 | ||
|
|
ceae7a2fdc | ||
|
|
40d8511f64 | ||
|
|
93612087d3 | ||
|
|
941b804a06 | ||
|
|
5b52fd3efd | ||
|
|
d10eea3ba3 | ||
|
|
759da5b597 | ||
|
|
c283e62d32 | ||
|
|
cbd0ba5323 | ||
|
|
95e815f293 | ||
|
|
3384da1957 |
19
.github/ISSUE_TEMPLATE/bug_report.md
vendored
19
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -14,11 +14,11 @@ about: Tell us about a problem you are experiencing
|
||||
**The output of the following commands will help us better understand what's going on**:
|
||||
(Pasting long output into a [GitHub gist](https://gist.github.com) or other pastebin is fine.)
|
||||
|
||||
* `kubectl logs deployment/velero -n velero`
|
||||
* `velero backup describe <backupname>` or `kubectl get backup/<backupname> -n velero -o yaml`
|
||||
* `velero backup logs <backupname>`
|
||||
* `velero restore describe <restorename>` or `kubectl get restore/<restorename> -n velero -o yaml`
|
||||
* `velero restore logs <restorename>`
|
||||
- `kubectl logs deployment/velero -n velero`
|
||||
- `velero backup describe <backupname>` or `kubectl get backup/<backupname> -n velero -o yaml`
|
||||
- `velero backup logs <backupname>`
|
||||
- `velero restore describe <restorename>` or `kubectl get restore/<restorename> -n velero -o yaml`
|
||||
- `velero restore logs <restorename>`
|
||||
|
||||
|
||||
**Anything else you would like to add:**
|
||||
@@ -33,3 +33,12 @@ about: Tell us about a problem you are experiencing
|
||||
- Kubernetes installer & version:
|
||||
- Cloud provider or hardware configuration:
|
||||
- OS (e.g. from `/etc/os-release`):
|
||||
|
||||
|
||||
**Vote on this issue!**
|
||||
|
||||
This is an invitation to the Velero community to vote on issues, you can see the project's [top voted issues listed here](https://github.com/vmware-tanzu/velero/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||
Use the "reaction smiley face" up to the right of this comment to vote.
|
||||
|
||||
- :+1: for "I would like to see this bug fixed as soon as possible"
|
||||
- :-1: for "There are more important bugs to focus on right now"
|
||||
|
||||
@@ -23,3 +23,11 @@ about: Suggest an idea for this project
|
||||
- Kubernetes installer & version:
|
||||
- Cloud provider or hardware configuration:
|
||||
- OS (e.g. from `/etc/os-release`):
|
||||
|
||||
**Vote on this issue!**
|
||||
|
||||
This is an invitation to the Velero community to vote on issues, you can see the project's [top voted issues listed here](https://github.com/vmware-tanzu/velero/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||
Use the "reaction smiley face" up to the right of this comment to vote.
|
||||
|
||||
- :+1: for "The project would be better with this feature added"
|
||||
- :-1: for "This feature will not enhance the project in a meaningful way"
|
||||
|
||||
15
.github/workflows/pr-changelog-check.yml
vendored
Normal file
15
.github/workflows/pr-changelog-check.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Pull Request Changelog Check
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Run Changelog Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Changelog check
|
||||
if: ${{ !(contains(github.event.pull_request.labels.*.name, 'changelog-not-required') || contains(github.event.pull_request.labels.*.name, 'Design') || contains(github.event.pull_request.labels.*.name, 'Website') || contains(github.event.pull_request.labels.*.name, 'Documentation'))}}
|
||||
run: ./hack/changelog-check.sh
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Pull Request CI Check
|
||||
on: [push, pull_request]
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
14
.github/workflows/pr-linter-check.yml
vendored
Normal file
14
.github/workflows/pr-linter-check.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Pull Request Linter Check
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Run Linter Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Check out the code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Linter check
|
||||
run: make lint
|
||||
22
.github/workflows/push-builder.yml
vendored
Normal file
22
.github/workflows/push-builder.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: build-image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
- 'hack/build-image/Dockerfile'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Build
|
||||
run: make build-image
|
||||
|
||||
- name: Publish container image
|
||||
run: |
|
||||
docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
make push-build-image
|
||||
34
.github/workflows/push.yml
vendored
Normal file
34
.github/workflows/push.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Master CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.14
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.14
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build
|
||||
run: make local
|
||||
|
||||
- name: Test
|
||||
run: make test
|
||||
|
||||
- name: Publish container image
|
||||
run: |
|
||||
docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
./hack/docker-push.sh
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -43,6 +43,7 @@ site/_site
|
||||
site/.sass-cache
|
||||
site/.jekyll
|
||||
site/.jekyll-metadata
|
||||
site/.jekyll-cache
|
||||
site/.bundle
|
||||
site/vendor
|
||||
.ruby-version
|
||||
|
||||
24
.travis.yml
24
.travis.yml
@@ -1,24 +0,0 @@
|
||||
dist: xenial
|
||||
language: go
|
||||
go:
|
||||
- 1.14.x
|
||||
sudo: required
|
||||
services:
|
||||
- docker
|
||||
script:
|
||||
- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH;
|
||||
else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
|
||||
- echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$TRAVIS_PULL_REQUEST, BRANCH=$BRANCH"
|
||||
- hack/ci-check.sh
|
||||
deploy:
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: hack/docker-push.sh
|
||||
on:
|
||||
repo: vmware-tanzu/velero
|
||||
all_branches: true
|
||||
env:
|
||||
global:
|
||||
# generated using `travis encrypt`: https://docs.travis-ci.com/user/environment-variables#encrypting-environment-variables
|
||||
- secure: Sa0R7bhOvrybIWvURjEpOLQ3/v1IqiSM2uwYTSMhLtwHunkiYXpbXi/wVPkujM7kgnFeJzGfNTZI6blkl3Vnz6Ca48avxiv+KRk7bNlTn/e2LkJaqOh/NcwqrVyWG8cZpWTHAzwJkHrV6xcWRTWFqx/UhUHH4PdmXd0pj3/DDxHhUZXJkZfYDC2uI+kmhJd9x1yxxz6OTXrGeMw22R5RtgltcQYjYWjGhXjNJ96+0QhC6juCwwtuU3oz7vfV1dP6ea9yeiHKCdDR0xp/Ymtlt4DULgQv4vuVBCR7LuPjsdLI1QslKbCz+vk/XwEcckf3R+yJUaArGLSM0f3AwuAZnETwkfKu9gJCEz8Xvvwsy5QHj/DGeSr+JY4Ylb1YzJG48R5QMcNwOgQOpewamBggxkyyOlNanUGzMJ8F7zjDOZjOUsRSSG+cn01/oJEHNyFmNkxbugOGuxqpi8qIfyWrdPSb8AdnUVUi2GDR/unSm2uZLSJtjaeypqzxalFdL04pbkk6/vKZTi6VMIyewHeR0XIC/VKQ+av2CwjnfqTtTHQHMh2kVxVzy4SKPYgWvbUUg9SG0z2lmfBWzE1HS+ozUKruxBu/YnPHaFz3D/+w0AwtHSYp3FMkCC/2SZU1hiOzAKX+S8T5K1OKoBiIEEUVa90EnSslCIiNIUHXgdtG62U=
|
||||
- secure: MAHgHvxxPJKxcECwdjaTa/ZW2wlhfcpcprXZqPJKQVFS6S5Wc+xf0CBRggnZT/aEs52EpD2bZy505a4uy9EcTDeq7q5oaXbOBFdyKgB1leWiycup60p6BmVqre5//EzXe+CJpkSu46ajcVORJIEGjs0tS5p0HV70sqpsfd13L2pXpmZ54RIj+TOm7Tz6VVeSNUmQ7WymIrvKg4cQ50w+aS7ak+gy8b6oYKWX01oZPQZA3W1pvYcBgBKobiQN8dh7WvT6QmTu/38WykTjt+9CfEJOboitgEESMjf06ueaLrhQoKQafH3XzfkfEW7PWWGl1RZYMEf15Joj1edIW1i9eYZ1T3fvBaIwvgc7lLgNdzc5ZxG8eEtoDSfB0+gDJOPBLCo+5G3xvRCie7OkKvXdijkCKmc+FRMJlayHkEw75cgId9svDEJghtt2VlWAM4ba4S79Og+cyI0VROkzS0FEjabz74tU9haVaypVnLmzEC/BhilzCt/jhRuYInpsMBeasGQ6Rg8gjos4AQamdaXJRI520o7zFWXVYqctfPr+mrVOYCfUISnSS3uqb4UlvLBqXDPVWBBIgmPrSgvHXxbjsajFuyWTULm60nj/JUuh7BC9HF9pil3g4/2E9cpLZCFQxVYu6+30eEv4dCO7Ptq3XIINDWbbS6Pmw62/ZsE8ABU=
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
FROM ubuntu:focal
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
LABEL maintainer="Nolan Brubaker <brubakern@vmware.com>"
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates wget bzip2 && \
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
FROM ubuntu:focal
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
LABEL maintainer="Nolan Brubaker <brubakern@vmware.com>"
|
||||
|
||||
ADD /bin/linux/amd64/velero-restic-restore-helper .
|
||||
|
||||
|
||||
112
GOVERNANCE.md
Normal file
112
GOVERNANCE.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Velero Governance
|
||||
|
||||
This document defines the project governance for Velero.
|
||||
|
||||
## Overview
|
||||
|
||||
**Velero**, an open source project, is committed to building an open, inclusive, productive and self-governing open source community focused on building a high quality tool that enables users to safely backup and restore, perform disaster recovery, and migrate Kubernetes cluster resources and persistent volumes. The community is governed by this document with the goal of defining how community should work together to achieve this goal.
|
||||
|
||||
## Code Repositories
|
||||
|
||||
The following code repositories are governed by Velero community and maintained under the `vmware-tanzu\Velero` organization.
|
||||
|
||||
* **[Velero](https://github.com/vmware-tanzu/velero):** Main Velero codebase
|
||||
* **[Helm Chart](https://github.com/vmware-tanzu/helm-charts/tree/master/charts/velero):** The Helm chart for the Velero server component
|
||||
* **[Velero CSI Plugin](https://github.com/vmware-tanzu/velero-plugin-for-csi):** This repository contains Velero plugins for snapshotting CSI backed PVCs using the CSI beta snapshot APIs
|
||||
* **[Velero Plugin for vSphere](https://github.com/vmware-tanzu/velero-plugin-for-vsphere):** This repository contains the Velero Plugin for vSphere. This plugin is a volume snapshotter plugin that provides crash-consistent snapshots of vSphere block volumes and backup of volume data into S3 compatible storage.
|
||||
* **[Velero Plugin for AWS](https://github.com/vmware-tanzu/velero-plugin-for-aws):** This repository contains the plugins to support running Velero on AWS, including the object store plugin and the volume snapshotter plugin
|
||||
* **[Velero Plugin for GCP](https://github.com/vmware-tanzu/velero-plugin-for-gcp):** This repository contains the plugins to support running Velero on GCP, including the object store plugin and the volume snapshotter plugin
|
||||
* **[Velero Plugin for Azure](https://github.com/vmware-tanzu/velero-plugin-for-microsoft-azure):** This repository contains the plugins to support running Velero on Azure, including the object store plugin and the volume snapshotter plugin
|
||||
* **[Velero Plugin Example](https://github.com/vmware-tanzu/velero-plugin-example):** This repository contains example plugins for Velero
|
||||
|
||||
|
||||
## Community Roles
|
||||
|
||||
* **Users:** Members that engage with the Velero community via any medium (Slack, GitHub, mailing lists, etc.).
|
||||
* **Contributors:** Regular contributions to projects (documentation, code reviews, responding to issues, participation in proposal discussions, contributing code, etc.).
|
||||
* **Maintainers**: The Velero project leaders. They are responsible for the overall health and direction of the project; final reviewers of PRs and responsible for releases. Some Maintainers are responsible for one or more components within a project, acting as technical leads for that component. Maintainers are expected to contribute code and documentation, review PRs including ensuring quality of code, triage issues, proactively fix bugs, and perform maintenance tasks for these components.
|
||||
|
||||
### Maintainers
|
||||
|
||||
New maintainers must be nominated by an existing maintainer and must be elected by a supermajority of existing maintainers. Likewise, maintainers can be removed by a supermajority of the existing maintainers or can resign by notifying one of the maintainers.
|
||||
|
||||
### Supermajority
|
||||
|
||||
A supermajority is defined as two-thirds of members in the group.
|
||||
A supermajority of [Maintainers](#maintainers) is required for certain
|
||||
decisions as outlined above. A supermajority vote is equivalent to the number of votes in favor being at least twice the number of votes against. For example, if you have 5 maintainers, a supermajority vote is 4 votes. Voting on decisions can happen on the mailing list, GitHub, Slack, email, or via a voting service, when appropriate. Maintainers can either vote "agree, yes, +1", "disagree, no, -1", or "abstain". A vote passes when supermajority is met. An abstain vote equals not voting at all.
|
||||
|
||||
### Decision Making
|
||||
|
||||
Ideally, all project decisions are resolved by consensus. If impossible, any
|
||||
maintainer may call a vote. Unless otherwise specified in this document, any
|
||||
vote will be decided by a supermajority of maintainers.
|
||||
|
||||
Votes by maintainers belonging to the same company
|
||||
will count as one vote; e.g., 4 maintainers employed by fictional company **Valerium** will
|
||||
only have **one** combined vote. If voting members from a given company do not
|
||||
agree, the company's vote is determined by a supermajority of voters from that
|
||||
company. If no supermajority is achieved, the company is considered to have
|
||||
abstained.
|
||||
|
||||
## Proposal Process
|
||||
|
||||
One of the most important aspects in any open source community is the concept
|
||||
of proposals. Large changes to the codebase and / or new features should be
|
||||
preceded by a proposal in our community repo. This process allows for all
|
||||
members of the community to weigh in on the concept (including the technical
|
||||
details), share their comments and ideas, and offer to help. It also ensures
|
||||
that members are not duplicating work or inadvertently stepping on toes by
|
||||
making large conflicting changes.
|
||||
|
||||
The project roadmap is defined by accepted proposals.
|
||||
|
||||
Proposals should cover the high-level objectives, use cases, and technical
|
||||
recommendations on how to implement. In general, the community member(s)
|
||||
interested in implementing the proposal should be either deeply engaged in the
|
||||
proposal process or be an author of the proposal.
|
||||
|
||||
The proposal should be documented as a separated markdown file pushed to the root of the
|
||||
`design` folder in the [Velero](https://github.com/vmware-tanzu/velero/tree/master/design)
|
||||
repository via PR. The name of the file should follow the name pattern `<short
|
||||
meaningful words joined by '-'>_design.md`, e.g:
|
||||
`restore-hooks-design.md`.
|
||||
|
||||
Use the [Proposal Template](https://github.com/vmware-tanzu/velero/blob/master/design/_template.md) as a starting point.
|
||||
|
||||
### Proposal Lifecycle
|
||||
|
||||
The proposal PR can follow the GitHub lifecycle of the PR to indicate its status:
|
||||
|
||||
* **Open**: Proposal is created and under review and discussion.
|
||||
* **Merged**: Proposal has been reviewed and is accepted (either by consensus or through a vote).
|
||||
* **Closed**: Proposal has been reviewed and was rejected (either by consensus or through a vote).
|
||||
|
||||
## Lazy Consensus
|
||||
|
||||
To maintain velocity in a project as busy as Velero, the concept of [Lazy
|
||||
Consensus](http://en.osswiki.info/concepts/lazy_consensus) is practiced. Ideas
|
||||
and / or proposals should be shared by maintainers via
|
||||
GitHub with the appropriate maintainer groups (e.g.,
|
||||
`@vmware-tanzu/velero-maintainers`) tagged. Out of respect for other contributors,
|
||||
major changes should also be accompanied by a ping on Slack or a note on the
|
||||
Velero mailing list as appropriate. Author(s) of proposal, Pull Requests,
|
||||
issues, etc. will give a time period of no less than five (5) working days for
|
||||
comment and remain cognizant of popular observed world holidays.
|
||||
|
||||
Other maintainers may chime in and request additional time for review, but
|
||||
should remain cognizant of blocking progress and abstain from delaying
|
||||
progress unless absolutely needed. The expectation is that blocking progress
|
||||
is accompanied by a guarantee to review and respond to the relevant action(s)
|
||||
(proposals, PRs, issues, etc.) in short order.
|
||||
|
||||
Lazy Consensus is practiced for all projects in the `Velero` org, including
|
||||
the main project repository and the additional repositories.
|
||||
|
||||
Lazy consensus does _not_ apply to the process of:
|
||||
|
||||
* Removal of maintainers from Velero
|
||||
|
||||
## Updating Governance
|
||||
|
||||
All substantive changes in Governance require a supermajority agreement by all maintainers.
|
||||
27
MAINTAINERS.md
Normal file
27
MAINTAINERS.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Velero Maintainers
|
||||
|
||||
[GOVERNANCE.md](https://github.com/vmware-tanzu/velero/blob/master/GOVERNANCE.md) describes governance guidelines and maintainer responsibilities.
|
||||
|
||||
## Maintainers
|
||||
|
||||
| Maintainer | GitHub ID | Affiliation |
|
||||
| --------------- | --------- | ----------- |
|
||||
| Carlisia Campos | [carlisia](https://github.com/carlisia) | [VMware](https://www.github.com/vmware/) |
|
||||
| Nolan Brubaker | [nrb](https://github.com/nrb) | [VMware](https://www.github.com/vmware/) |
|
||||
| Ashish Amarnath | [ashish-amarnath](https://github.com/ashish-amarnath) | [VMware](https://www.github.com/vmware/) |
|
||||
| Stephanie Bauman | [stephbman](https://github.com/stephbman) | [VMware](https://www.github.com/vmware/) |
|
||||
|
||||
## Emeritus Maintainers
|
||||
* Adnan Abdulhussein ([prydonius](https://github.com/prydonius))
|
||||
* Andy Goldstein ([ncdc](https://github.com/ncdc))
|
||||
* Steve Kriss ([skriss](https://github.com/skriss))
|
||||
|
||||
## Velero Contributors & Stakeholders
|
||||
|
||||
| Feature Area | Lead |
|
||||
| ----------------------------- | :---------------------: |
|
||||
| Technical Lead | Nolan Brubaker (nrb) |
|
||||
| Kubernetes CSI Liaison | Nolan Brubaker (nrb), Ashish Amarnath (ashish-amarnath) |
|
||||
| Deployment | Carlisia Campos (carlisia), Carlos Tadeu Panato Junior (cpanato) |
|
||||
| Community Management | Jonas Rosland (jonasrosland) |
|
||||
| Product Management | Stephanie Bauman (stephbman) |
|
||||
89
Makefile
89
Makefile
@@ -1,6 +1,6 @@
|
||||
# Copyright 2016 The Kubernetes Authors.
|
||||
#
|
||||
# Modifications Copyright 2017 the Velero contributors.
|
||||
# Modifications Copyright 2020 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,16 @@ PKG := github.com/vmware-tanzu/velero
|
||||
# Where to push the docker image.
|
||||
REGISTRY ?= velero
|
||||
|
||||
# Build image handling. We push a build image for every changed version of
|
||||
# /hack/build-image/Dockerfile. We tag the dockerfile with the short commit hash
|
||||
# of the commit that changed it. When determining if there is a build image in
|
||||
# the registry to use we look for one that matches the current "commit" for the
|
||||
# Dockerfile else we make one.
|
||||
|
||||
BUILDER_IMAGE_TAG := $(shell git log -1 --pretty=%h hack/build-image/Dockerfile)
|
||||
BUILDER_IMAGE := $(REGISTRY)/build-image:$(BUILDER_IMAGE_TAG)
|
||||
BUILDER_IMAGE_CACHED := $(shell docker images -q ${BUILDER_IMAGE} 2>/dev/null )
|
||||
|
||||
# Which architecture to build - see $(ALL_ARCH) for options.
|
||||
# if the 'local' rule is being run, detect the ARCH from 'go env'
|
||||
# if it wasn't specified by the caller.
|
||||
@@ -40,6 +50,13 @@ CLI_PLATFORMS ?= linux-amd64 linux-arm linux-arm64 darwin-amd64 windows-amd64 li
|
||||
CONTAINER_PLATFORMS ?= linux-amd64 linux-ppc64le linux-arm linux-arm64
|
||||
MANIFEST_PLATFORMS ?= amd64 ppc64le arm arm64
|
||||
|
||||
# set git sha and tree state
|
||||
GIT_SHA = $(shell git rev-parse HEAD)
|
||||
GIT_DIRTY = $(shell git status --porcelain 2> /dev/null)
|
||||
|
||||
# The default linters used by lint and local-lint
|
||||
LINTERS ?= "gosec,goconst,gofmt,goimports,unparam"
|
||||
|
||||
###
|
||||
### These variables should not need tweaking.
|
||||
###
|
||||
@@ -113,6 +130,8 @@ local: build-dirs
|
||||
VERSION=$(VERSION) \
|
||||
PKG=$(PKG) \
|
||||
BIN=$(BIN) \
|
||||
GIT_SHA=$(GIT_SHA) \
|
||||
GIT_DIRTY="$(GIT_DIRTY)" \
|
||||
OUTPUT_DIR=$$(pwd)/_output/bin/$(GOOS)/$(GOARCH) \
|
||||
./hack/build.sh
|
||||
|
||||
@@ -126,15 +145,16 @@ _output/bin/$(GOOS)/$(GOARCH)/$(BIN): build-dirs
|
||||
VERSION=$(VERSION) \
|
||||
PKG=$(PKG) \
|
||||
BIN=$(BIN) \
|
||||
GIT_SHA=$(GIT_SHA) \
|
||||
GIT_DIRTY=\"$(GIT_DIRTY)\" \
|
||||
OUTPUT_DIR=/output/$(GOOS)/$(GOARCH) \
|
||||
./hack/build.sh'"
|
||||
|
||||
TTY := $(shell tty -s && echo "-t")
|
||||
|
||||
BUILDER_IMAGE := velero-builder
|
||||
|
||||
# Example: make shell CMD="date > datefile"
|
||||
shell: build-dirs build-image
|
||||
shell: build-dirs build-env
|
||||
@# bind-mount the Velero root dir in at /github.com/vmware-tanzu/velero
|
||||
@# because the Kubernetes code-generator tools require the project to
|
||||
@# exist in a directory hierarchy ending like this (but *NOT* necessarily
|
||||
@@ -150,6 +170,7 @@ shell: build-dirs build-image
|
||||
-v "$$(pwd)/.go/std:/go/std:delegated" \
|
||||
-v "$$(pwd)/.go/std/$(GOOS)/$(GOARCH):/usr/local/go/pkg/$(GOOS)_$(GOARCH)_static:delegated" \
|
||||
-v "$$(pwd)/.go/go-build:/.cache/go-build:delegated" \
|
||||
-v "$$(pwd)/.go/golangci-lint:/.cache/golangci-lint:delegated" \
|
||||
-w /github.com/vmware-tanzu/velero \
|
||||
$(BUILDER_IMAGE) \
|
||||
/bin/sh $(CMD)
|
||||
@@ -211,33 +232,89 @@ ifneq ($(SKIP_TESTS), 1)
|
||||
@$(MAKE) shell CMD="-c 'hack/verify-all.sh'"
|
||||
endif
|
||||
|
||||
lint:
|
||||
ifneq ($(SKIP_TESTS), 1)
|
||||
@$(MAKE) shell CMD="-c 'hack/lint.sh $(LINTERS)'"
|
||||
endif
|
||||
|
||||
local-lint:
|
||||
ifneq ($(SKIP_TESTS), 1)
|
||||
@hack/lint.sh $(LINTERS)
|
||||
endif
|
||||
|
||||
lint-all:
|
||||
ifneq ($(SKIP_TESTS), 1)
|
||||
@$(MAKE) shell CMD="-c 'hack/lint.sh $(LINTERS) true'"
|
||||
endif
|
||||
|
||||
local-lint-all:
|
||||
ifneq ($(SKIP_TESTS), 1)
|
||||
@hack/lint.sh $(LINTERS) true
|
||||
endif
|
||||
|
||||
update:
|
||||
@$(MAKE) shell CMD="-c 'hack/update-all.sh'"
|
||||
|
||||
build-dirs:
|
||||
@mkdir -p _output/bin/$(GOOS)/$(GOARCH)
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build .go/golangci-lint
|
||||
|
||||
build-env:
|
||||
@# if we detect changes in dockerfile force a new build-image
|
||||
@# else if we dont have a cached image make one
|
||||
@# finally use the cached image
|
||||
ifneq ($(shell git diff --quiet HEAD -- hack/build-image/Dockerfile; echo $$?), 0)
|
||||
@echo "Local changes detected in hack/build-image/Dockerfile"
|
||||
@echo "Preparing a new builder-image"
|
||||
@make build-image
|
||||
else ifneq ($(BUILDER_IMAGE_CACHED),)
|
||||
@echo "Using Cached Image: $(BUILDER_IMAGE)"
|
||||
else
|
||||
@echo "Trying to pull build-image: $(BUILDER_IMAGE)"
|
||||
docker pull -q $(BUILDER_IMAGE) || make build-image
|
||||
endif
|
||||
|
||||
build-image:
|
||||
cd hack/build-image && docker build --pull -t $(BUILDER_IMAGE) .
|
||||
@# When we build a new image we just untag the old one.
|
||||
@# This makes sure we don't leave the orphaned image behind.
|
||||
@id=$$(docker image inspect --format '{{ .ID }}' ${BUILDER_IMAGE} 2>/dev/null); \
|
||||
cd hack/build-image && docker build --pull -t $(BUILDER_IMAGE) . ; \
|
||||
new_id=$$(docker image inspect --format '{{ .ID }}' ${BUILDER_IMAGE} 2>/dev/null); \
|
||||
if [ "$$id" != "" ] && [ "$$id" != "$$new_id" ]; then \
|
||||
docker rmi -f $$id || true; \
|
||||
fi
|
||||
|
||||
push-build-image:
|
||||
@# this target will push the build-image it assumes you already have docker
|
||||
@# credentials needed to accomplish this.
|
||||
docker push $(BUILDER_IMAGE)
|
||||
|
||||
clean:
|
||||
# if we have a cached image then use it to run go clean --modcache
|
||||
# this test checks if we there is an image id in the BUILDER_IMAGE_CACHED variable.
|
||||
ifneq ($(strip $(BUILDER_IMAGE_CACHED)),)
|
||||
$(MAKE) shell CMD="-c 'go clean --modcache'"
|
||||
docker rmi -f $(BUILDER_IMAGE) || true
|
||||
endif
|
||||
rm -rf .container-* _output/.dockerfile-* .push-*
|
||||
rm -rf .go _output
|
||||
docker rmi $(BUILDER_IMAGE)
|
||||
|
||||
|
||||
.PHONY: modules
|
||||
modules:
|
||||
go mod tidy
|
||||
|
||||
|
||||
.PHONY: verify-modules
|
||||
verify-modules: modules
|
||||
@if !(git diff --quiet HEAD -- go.sum go.mod); then \
|
||||
echo "go module files are out of date, please commit the changes to go.mod and go.sum"; exit 1; \
|
||||
fi
|
||||
|
||||
|
||||
ci: verify-modules verify all test
|
||||
|
||||
|
||||
changelog:
|
||||
hack/changelog.sh
|
||||
|
||||
|
||||
7
PROJECT
Normal file
7
PROJECT
Normal file
@@ -0,0 +1,7 @@
|
||||
domain: io
|
||||
repo: github.com/vmware-tanzu/velero
|
||||
resources:
|
||||
- group: velero
|
||||
kind: BackupStorageLocation
|
||||
version: v1
|
||||
version: "2"
|
||||
@@ -33,8 +33,8 @@ If you are ready to jump in and test, add code, or help with documentation, foll
|
||||
|
||||
See [the list of releases][6] to find out about feature changes.
|
||||
|
||||
[1]: https://travis-ci.org/vmware-tanzu/velero.svg?branch=master
|
||||
[2]: https://travis-ci.org/vmware-tanzu/velero
|
||||
[1]: https://github.com/vmware-tanzu/velero/workflows/Master%20CI/badge.svg
|
||||
[2]: https://github.com/vmware-tanzu/velero/actions?query=workflow%3A"Master+CI"
|
||||
[4]: https://github.com/vmware-tanzu/velero/issues
|
||||
[6]: https://github.com/vmware-tanzu/velero/releases
|
||||
[9]: https://kubernetes.io/docs/setup/
|
||||
|
||||
36
ROADMAP.md
Normal file
36
ROADMAP.md
Normal file
@@ -0,0 +1,36 @@
|
||||
## Velero Roadmap
|
||||
|
||||
### About this document
|
||||
This document provides a link to the [Velero Project board](https://app.zenhub.com/workspaces/velero-5c59c15e39d47b774b5864e3/board?repos=99143276,112385197,190224441,214524700,214524630,213946861) that serves as the up to date description of items that are in the release pipeline. The board has separate swim lanes based on prioritization. Most items are gathered from the community or include a feedback loop with the community. This should serve as a reference point for Velero users and contributors to understand where the project is heading, and help determine if a contribution could be conflicting with a longer term plan. You will need the ZenHub plugin to view the board.
|
||||
|
||||
### How to help?
|
||||
Discussion on the roadmap can take place in threads under [Issues](https://github.com/vmware-tanzu/velero/issues) or in [community meetings](https://velero.io/community/). Please open and comment on an issue if you want to provide suggestions, use cases, and feedback to an item in the roadmap. Please review the roadmap to avoid potential duplicated effort.
|
||||
|
||||
### How to add an item to the roadmap?
|
||||
One of the most important aspects in any open source community is the concept of proposals. Large changes to the codebase and / or new features should be preceded by a [proposal](https://github.com/vmware-tanzu/velero/blob/master/GOVERNANCE.md#proposal-process) in our repo.
|
||||
For smaller enhancements, you can open an issue to track that initiative or feature request.
|
||||
We work with and rely on community feedback to focus our efforts to improve Velero and maintain a healthy roadmap.
|
||||
|
||||
### Current Roadmap
|
||||
The following table includes the current roadmap for Velero. If you have any questions or would like to contribute to Velero, please attend a [community meeting](https://velero.io/community/) to discuss with our team. If you don't know where to start, we are always looking for contributors that will help us reduce technical, automation, and documentation debt.
|
||||
Please take the timelines & dates as proposals and goals. Priorities and requirements change based on community feedback, roadblocks encountered, community contributions, etc. If you depend on a specific item, we encourage you to attend community meetings to get updated status information, or help us deliver that feature by contributing to Velero.
|
||||
|
||||
`Last Updated: May 2020`
|
||||
|
||||
|Theme|Description|Timeline|
|
||||
|--|--|--|
|
||||
|Restic Improvements|Introduce improvements in annotating resources for Restic backup|August 2020|
|
||||
|Extensibility|Add restore hooks for enhanced recovery scenarios|August 2020|
|
||||
|CSI|Continue improving the CSI snapshot capabilities and participate in the upstream K8s CSI community|Long running (dependent on CSI working group)|
|
||||
|Backup/Restore|Improvements to long-running copy operations from a performance and reliability standpoint|August 2020|
|
||||
|UX|Improvements to install and configuration user experience|August 2020|
|
||||
|Restic Improvements|Improve the use of Restic in Velero and offer stable support|Dec 2020|
|
||||
|Perf & Scale|Introduce a scalable model by using a worker pod for each backup/restore operation and improve operations|Dec 2020|
|
||||
|Backup/Restore|Better backup and restore semantics for certain Kubernetes resources like stateful sets, operators|Dec 2020|
|
||||
|Security|Enable the use of custom credential providers|Dec 2020|
|
||||
|Self-Service & Multitenancy|Reduce friction by enabling developers to backup their namespaces via self-service. Introduce a Velero multi-tenancy model, enabling owners of namespaces to backup and restore within their access scope|Mar 2021|
|
||||
|Backup/Restore|Cross availability zone or region backup and restore|Mar 2021|
|
||||
|Application Consistency|Offer blueprints for backing up and restoring popular applications|May 2021|
|
||||
|Backup/Restore|Data only backup and restore|May 2021|
|
||||
|Backup/Restore|Introduce the ability to overwrite existing objects during a restore|May 2021|
|
||||
|Backup/Restore|What-if dry run for backup and restore|May 2021|
|
||||
1
changelogs/unreleased/2550-skriss
Normal file
1
changelogs/unreleased/2550-skriss
Normal file
@@ -0,0 +1 @@
|
||||
backup/restore: reinstantiate backup store just before uploading artifacts to ensure credentials are up-to-date
|
||||
1
changelogs/unreleased/2561-carlisia
Normal file
1
changelogs/unreleased/2561-carlisia
Normal file
@@ -0,0 +1 @@
|
||||
Convert manifests + BSL api client to kubebuilder
|
||||
1
changelogs/unreleased/2569-cblecker
Normal file
1
changelogs/unreleased/2569-cblecker
Normal file
@@ -0,0 +1 @@
|
||||
when creating new backup from schedule from cli, allow backup name to be automatically generated
|
||||
1
changelogs/unreleased/2595-skriss
Normal file
1
changelogs/unreleased/2595-skriss
Normal file
@@ -0,0 +1 @@
|
||||
log a warning instead of erroring if an additional item returned from a plugin can't be found in the Kubernetes API
|
||||
1
changelogs/unreleased/2602-skriss
Normal file
1
changelogs/unreleased/2602-skriss
Normal file
@@ -0,0 +1 @@
|
||||
Azure: support using `aad-pod-identity` auth when using restic
|
||||
1
changelogs/unreleased/2610-nrb
Normal file
1
changelogs/unreleased/2610-nrb
Normal file
@@ -0,0 +1 @@
|
||||
When a timeout string can't be parsed, log the error as a warning instead of silently consuming the error.
|
||||
1
changelogs/unreleased/2611-ashish-amarnath
Normal file
1
changelogs/unreleased/2611-ashish-amarnath
Normal file
@@ -0,0 +1 @@
|
||||
implement option to back up all volumes by default with restic
|
||||
1
changelogs/unreleased/2613-ashish-amarnath
Normal file
1
changelogs/unreleased/2613-ashish-amarnath
Normal file
@@ -0,0 +1 @@
|
||||
add a CI check for a changelog file
|
||||
1
changelogs/unreleased/2615-tbatard
Normal file
1
changelogs/unreleased/2615-tbatard
Normal file
@@ -0,0 +1 @@
|
||||
Add linter checks to Makefile
|
||||
6
changelogs/unreleased/2620-mauilion
Normal file
6
changelogs/unreleased/2620-mauilion
Normal file
@@ -0,0 +1,6 @@
|
||||
improve builder image handling so that we don't rebuild each `make shell`
|
||||
first check if there are pending changed on the build-image dockerfile if so build it.
|
||||
then check if there is an image in the registry if so pull it.
|
||||
then build an image cause we don't have a cached image. (this handles the backward compat case.)
|
||||
fix make clean to clear go mod cache before removing dirs (for containerized builds)
|
||||
|
||||
3
changelogs/unreleased/2625-tbatard
Normal file
3
changelogs/unreleased/2625-tbatard
Normal file
@@ -0,0 +1,3 @@
|
||||
Documentation: Update Jekyll to 4.1.0
|
||||
|
||||
Switch from redcarpet to kramdown for Markdown renderer
|
||||
1
changelogs/unreleased/2629-adamrushuk
Normal file
1
changelogs/unreleased/2629-adamrushuk
Normal file
@@ -0,0 +1 @@
|
||||
Update basic-install.md documentation: Add windows cli installation option via chocolatey
|
||||
1
changelogs/unreleased/2635-jessicagreben
Normal file
1
changelogs/unreleased/2635-jessicagreben
Normal file
@@ -0,0 +1 @@
|
||||
Add a new supported provider for an object storage plugin for Storj
|
||||
1
changelogs/unreleased/2636-ashish-amarnath
Normal file
1
changelogs/unreleased/2636-ashish-amarnath
Normal file
@@ -0,0 +1 @@
|
||||
move CSI plugin out of prototype into beta
|
||||
1
changelogs/unreleased/2638-adamrushuk
Normal file
1
changelogs/unreleased/2638-adamrushuk
Normal file
@@ -0,0 +1 @@
|
||||
Update basic-install and release-instructions documentation for Windows Chocolatey package
|
||||
1
changelogs/unreleased/2651-laverya
Normal file
1
changelogs/unreleased/2651-laverya
Normal file
@@ -0,0 +1 @@
|
||||
bump Kubernetes module dependencies to v0.18.4 to fix https://github.com/vmware-tanzu/velero/issues/2540 by adding code compatibility with kubernetes v1.18
|
||||
1
changelogs/unreleased/2660-carlisia
Normal file
1
changelogs/unreleased/2660-carlisia
Normal file
@@ -0,0 +1 @@
|
||||
Improve velero download doc
|
||||
1
changelogs/unreleased/2674-carlisia
Normal file
1
changelogs/unreleased/2674-carlisia
Normal file
@@ -0,0 +1 @@
|
||||
Add a BSL controller to handle validation + update BSL status phase (validation removed from the server and no longer blocks when there's any invalid BSL)
|
||||
1
changelogs/unreleased/2676-dthrasher
Normal file
1
changelogs/unreleased/2676-dthrasher
Normal file
@@ -0,0 +1 @@
|
||||
updated acceptable values on cron schedule from 0-7 to 0-6
|
||||
1
changelogs/unreleased/2683-ashish-amarnath
Normal file
1
changelogs/unreleased/2683-ashish-amarnath
Normal file
@@ -0,0 +1 @@
|
||||
capture version of the CRD prior before invoking the remap_crd_version backup item action
|
||||
1
changelogs/unreleased/2696-nrb
Normal file
1
changelogs/unreleased/2696-nrb
Normal file
@@ -0,0 +1 @@
|
||||
Adjust restic default time out to 4 hours and base pod resource requests to 500m CPU/512Mi memory.
|
||||
1
changelogs/unreleased/2714-kathpeony
Normal file
1
changelogs/unreleased/2714-kathpeony
Normal file
@@ -0,0 +1 @@
|
||||
Add backupValidationFailureTotal to metrics
|
||||
423
config/crd/bases/velero.io_backups.yaml
Normal file
423
config/crd/bases/velero.io_backups.yaml
Normal file
@@ -0,0 +1,423 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: backups.velero.io
|
||||
spec:
|
||||
group: velero.io
|
||||
names:
|
||||
kind: Backup
|
||||
listKind: BackupList
|
||||
plural: backups
|
||||
singular: backup
|
||||
preserveUnknownFields: false
|
||||
scope: Namespaced
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Backup is a Velero resource that respresents the capture of Kubernetes
|
||||
cluster state at a point in time (API objects and associated volume state).
|
||||
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/sig-architecture/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/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: BackupSpec defines the specification for a Velero backup.
|
||||
properties:
|
||||
defaultVolumesToRestic:
|
||||
description: DefaultVolumesToRestic specifies whether restic should
|
||||
be used to take a backup of all pod volumes by default.
|
||||
type: boolean
|
||||
excludedNamespaces:
|
||||
description: ExcludedNamespaces contains a list of namespaces that are
|
||||
not included in the backup.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
excludedResources:
|
||||
description: ExcludedResources is a slice of resource names that are
|
||||
not included in the backup.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
hooks:
|
||||
description: Hooks represent custom behaviors that should be executed
|
||||
at different phases of the backup.
|
||||
properties:
|
||||
resources:
|
||||
description: Resources are hooks that should be executed when backing
|
||||
up individual instances of a resource.
|
||||
items:
|
||||
description: BackupResourceHookSpec defines one or more BackupResourceHooks
|
||||
that should be executed based on the rules defined for namespaces,
|
||||
resources, and label selector.
|
||||
properties:
|
||||
excludedNamespaces:
|
||||
description: ExcludedNamespaces specifies the namespaces to
|
||||
which this hook spec does not apply.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
excludedResources:
|
||||
description: ExcludedResources specifies the resources to
|
||||
which this hook spec does not apply.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
includedNamespaces:
|
||||
description: IncludedNamespaces specifies the namespaces to
|
||||
which this hook spec applies. If empty, it applies to all
|
||||
namespaces.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
includedResources:
|
||||
description: IncludedResources specifies the resources to
|
||||
which this hook spec applies. If empty, it applies to all
|
||||
resources.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
labelSelector:
|
||||
description: LabelSelector, if specified, filters the resources
|
||||
to which this hook spec applies.
|
||||
nullable: true
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn,
|
||||
Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values array
|
||||
must be non-empty. If the operator is Exists or
|
||||
DoesNotExist, the values array must be empty.
|
||||
This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field is
|
||||
"key", the operator is "In", and the values array contains
|
||||
only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
name:
|
||||
description: Name is the name of this hook.
|
||||
type: string
|
||||
post:
|
||||
description: PostHooks is a list of BackupResourceHooks to
|
||||
execute after storing the item in the backup. These are
|
||||
executed after all "additional items" from item actions
|
||||
are processed.
|
||||
items:
|
||||
description: BackupResourceHook defines a hook for a resource.
|
||||
properties:
|
||||
exec:
|
||||
description: Exec defines an exec hook.
|
||||
properties:
|
||||
command:
|
||||
description: Command is the command and arguments
|
||||
to execute.
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
container:
|
||||
description: Container is the container in the pod
|
||||
where the command should be executed. If not specified,
|
||||
the pod's first container is used.
|
||||
type: string
|
||||
onError:
|
||||
description: OnError specifies how Velero should
|
||||
behave if it encounters an error executing this
|
||||
hook.
|
||||
enum:
|
||||
- Continue
|
||||
- Fail
|
||||
type: string
|
||||
timeout:
|
||||
description: Timeout defines the maximum amount
|
||||
of time Velero should wait for the hook to complete
|
||||
before considering the execution a failure.
|
||||
type: string
|
||||
required:
|
||||
- command
|
||||
type: object
|
||||
required:
|
||||
- exec
|
||||
type: object
|
||||
type: array
|
||||
pre:
|
||||
description: PreHooks is a list of BackupResourceHooks to
|
||||
execute prior to storing the item in the backup. These are
|
||||
executed before any "additional items" from item actions
|
||||
are processed.
|
||||
items:
|
||||
description: BackupResourceHook defines a hook for a resource.
|
||||
properties:
|
||||
exec:
|
||||
description: Exec defines an exec hook.
|
||||
properties:
|
||||
command:
|
||||
description: Command is the command and arguments
|
||||
to execute.
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
container:
|
||||
description: Container is the container in the pod
|
||||
where the command should be executed. If not specified,
|
||||
the pod's first container is used.
|
||||
type: string
|
||||
onError:
|
||||
description: OnError specifies how Velero should
|
||||
behave if it encounters an error executing this
|
||||
hook.
|
||||
enum:
|
||||
- Continue
|
||||
- Fail
|
||||
type: string
|
||||
timeout:
|
||||
description: Timeout defines the maximum amount
|
||||
of time Velero should wait for the hook to complete
|
||||
before considering the execution a failure.
|
||||
type: string
|
||||
required:
|
||||
- command
|
||||
type: object
|
||||
required:
|
||||
- exec
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
nullable: true
|
||||
type: array
|
||||
type: object
|
||||
includeClusterResources:
|
||||
description: IncludeClusterResources specifies whether cluster-scoped
|
||||
resources should be included for consideration in the backup.
|
||||
nullable: true
|
||||
type: boolean
|
||||
includedNamespaces:
|
||||
description: IncludedNamespaces is a slice of namespace names to include
|
||||
objects from. If empty, all namespaces are included.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
includedResources:
|
||||
description: IncludedResources is a slice of resource names to include
|
||||
in the backup. If empty, all resources are included.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
labelSelector:
|
||||
description: LabelSelector is a metav1.LabelSelector to filter with
|
||||
when adding individual objects to the backup. If empty or nil, all
|
||||
objects are included. Optional.
|
||||
nullable: true
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that contains
|
||||
values, a key, and an operator that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship to a
|
||||
set of values. Valid operators are In, NotIn, Exists and
|
||||
DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the operator
|
||||
is In or NotIn, the values array must be non-empty. If the
|
||||
operator is Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a strategic merge
|
||||
patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator is
|
||||
"In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
snapshotVolumes:
|
||||
description: SnapshotVolumes specifies whether to take cloud snapshots
|
||||
of any PV's referenced in the set of objects included in the Backup.
|
||||
nullable: true
|
||||
type: boolean
|
||||
storageLocation:
|
||||
description: StorageLocation is a string containing the name of a BackupStorageLocation
|
||||
where the backup should be stored.
|
||||
type: string
|
||||
ttl:
|
||||
description: TTL is a time.Duration-parseable string describing how
|
||||
long the Backup should be retained for.
|
||||
type: string
|
||||
volumeSnapshotLocations:
|
||||
description: VolumeSnapshotLocations is a list containing names of VolumeSnapshotLocations
|
||||
associated with this backup.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
status:
|
||||
description: BackupStatus captures the current status of a Velero backup.
|
||||
properties:
|
||||
completionTimestamp:
|
||||
description: CompletionTimestamp records the time a backup was completed.
|
||||
Completion time is recorded even on failed backups. Completion time
|
||||
is recorded before uploading the backup object. The server's time
|
||||
is used for CompletionTimestamps
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
errors:
|
||||
description: Errors is a count of all error messages that were generated
|
||||
during execution of the backup. The actual errors are in the backup's
|
||||
log file in object storage.
|
||||
type: integer
|
||||
expiration:
|
||||
description: Expiration is when this Backup is eligible for garbage-collection.
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
formatVersion:
|
||||
description: FormatVersion is the backup format version, including major,
|
||||
minor, and patch version.
|
||||
type: string
|
||||
phase:
|
||||
description: Phase is the current state of the Backup.
|
||||
enum:
|
||||
- New
|
||||
- FailedValidation
|
||||
- InProgress
|
||||
- Completed
|
||||
- PartiallyFailed
|
||||
- Failed
|
||||
- Deleting
|
||||
type: string
|
||||
progress:
|
||||
description: Progress contains information about the backup's execution
|
||||
progress. Note that this information is best-effort only -- if Velero
|
||||
fails to update it during a backup for any reason, it may be inaccurate/stale.
|
||||
nullable: true
|
||||
properties:
|
||||
itemsBackedUp:
|
||||
description: ItemsBackedUp is the number of items that have actually
|
||||
been written to the backup tarball so far.
|
||||
type: integer
|
||||
totalItems:
|
||||
description: TotalItems is the total number of items to be backed
|
||||
up. This number may change throughout the execution of the backup
|
||||
due to plugins that return additional related items to back up,
|
||||
the velero.io/exclude-from-backup label, and various other filters
|
||||
that happen as items are processed.
|
||||
type: integer
|
||||
type: object
|
||||
startTimestamp:
|
||||
description: StartTimestamp records the time a backup was started. Separate
|
||||
from CreationTimestamp, since that value changes on restores. The
|
||||
server's time is used for StartTimestamps
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
validationErrors:
|
||||
description: ValidationErrors is a slice of all validation errors (if
|
||||
applicable).
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
version:
|
||||
description: 'Version is the backup format major version. Deprecated:
|
||||
Please see FormatVersion'
|
||||
type: integer
|
||||
volumeSnapshotsAttempted:
|
||||
description: VolumeSnapshotsAttempted is the total number of attempted
|
||||
volume snapshots for this backup.
|
||||
type: integer
|
||||
volumeSnapshotsCompleted:
|
||||
description: VolumeSnapshotsCompleted is the total number of successfully
|
||||
completed volume snapshots for this backup.
|
||||
type: integer
|
||||
warnings:
|
||||
description: Warnings is a count of all warning messages that were generated
|
||||
during execution of the backup. The actual warnings are in the backup's
|
||||
log file in object storage.
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
version: v1
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -4,10 +4,23 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: backupstoragelocations.velero.io
|
||||
spec:
|
||||
additionalPrinterColumns:
|
||||
- JSONPath: .status.phase
|
||||
description: Backup Storage Location status such as Available/Unavailable
|
||||
name: Phase
|
||||
type: string
|
||||
- JSONPath: .status.lastValidationTime
|
||||
description: LastValidationTime is the last time the backup store location was
|
||||
validated
|
||||
name: Last Validated
|
||||
type: date
|
||||
- JSONPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
group: velero.io
|
||||
names:
|
||||
kind: BackupStorageLocation
|
||||
@@ -16,10 +29,12 @@ spec:
|
||||
singular: backupstoragelocation
|
||||
preserveUnknownFields: false
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: BackupStorageLocation is a location where Velero stores backup
|
||||
objects.
|
||||
objects
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation
|
||||
@@ -34,8 +49,8 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: BackupStorageLocationSpec defines the specification for a Velero
|
||||
BackupStorageLocation.
|
||||
description: BackupStorageLocationSpec defines the desired state of a Velero
|
||||
BackupStorageLocation
|
||||
properties:
|
||||
accessMode:
|
||||
description: AccessMode defines the permissions for the backup storage
|
||||
@@ -76,13 +91,17 @@ spec:
|
||||
provider:
|
||||
description: Provider is the provider of the backup storage.
|
||||
type: string
|
||||
validationFrequency:
|
||||
description: ValidationFrequency defines how frequently to validate
|
||||
the corresponding object storage. A value of 0 disables validation.
|
||||
nullable: true
|
||||
type: string
|
||||
required:
|
||||
- objectStorage
|
||||
- provider
|
||||
type: object
|
||||
status:
|
||||
description: BackupStorageLocationStatus describes the current status of
|
||||
a Velero BackupStorageLocation.
|
||||
description: BackupStorageLocationStatus defines the observed state of BackupStorageLocation
|
||||
properties:
|
||||
accessMode:
|
||||
description: "AccessMode is an unused field. \n Deprecated: there is
|
||||
@@ -105,6 +124,12 @@ spec:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
lastValidationTime:
|
||||
description: LastValidationTime is the last time the backup store location
|
||||
was validated the cluster.
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
phase:
|
||||
description: Phase is the current state of the BackupStorageLocation.
|
||||
enum:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: deletebackuprequests.velero.io
|
||||
spec:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: downloadrequests.velero.io
|
||||
spec:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: podvolumebackups.velero.io
|
||||
spec:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: podvolumerestores.velero.io
|
||||
spec:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: resticrepositories.velero.io
|
||||
spec:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: restores.velero.io
|
||||
spec:
|
||||
379
config/crd/bases/velero.io_schedules.yaml
Normal file
379
config/crd/bases/velero.io_schedules.yaml
Normal file
@@ -0,0 +1,379 @@
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: schedules.velero.io
|
||||
spec:
|
||||
group: velero.io
|
||||
names:
|
||||
kind: Schedule
|
||||
listKind: ScheduleList
|
||||
plural: schedules
|
||||
singular: schedule
|
||||
preserveUnknownFields: false
|
||||
scope: Namespaced
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schedule is a Velero resource that represents a pre-scheduled or
|
||||
periodic Backup that should be run.
|
||||
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/sig-architecture/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/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ScheduleSpec defines the specification for a Velero schedule
|
||||
properties:
|
||||
schedule:
|
||||
description: Schedule is a Cron expression defining when to run the
|
||||
Backup.
|
||||
type: string
|
||||
template:
|
||||
description: Template is the definition of the Backup to be run on the
|
||||
provided schedule
|
||||
properties:
|
||||
defaultVolumesToRestic:
|
||||
description: DefaultVolumesToRestic specifies whether restic should
|
||||
be used to take a backup of all pod volumes by default.
|
||||
type: boolean
|
||||
excludedNamespaces:
|
||||
description: ExcludedNamespaces contains a list of namespaces that
|
||||
are not included in the backup.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
excludedResources:
|
||||
description: ExcludedResources is a slice of resource names that
|
||||
are not included in the backup.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
hooks:
|
||||
description: Hooks represent custom behaviors that should be executed
|
||||
at different phases of the backup.
|
||||
properties:
|
||||
resources:
|
||||
description: Resources are hooks that should be executed when
|
||||
backing up individual instances of a resource.
|
||||
items:
|
||||
description: BackupResourceHookSpec defines one or more BackupResourceHooks
|
||||
that should be executed based on the rules defined for namespaces,
|
||||
resources, and label selector.
|
||||
properties:
|
||||
excludedNamespaces:
|
||||
description: ExcludedNamespaces specifies the namespaces
|
||||
to which this hook spec does not apply.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
excludedResources:
|
||||
description: ExcludedResources specifies the resources
|
||||
to which this hook spec does not apply.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
includedNamespaces:
|
||||
description: IncludedNamespaces specifies the namespaces
|
||||
to which this hook spec applies. If empty, it applies
|
||||
to all namespaces.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
includedResources:
|
||||
description: IncludedResources specifies the resources
|
||||
to which this hook spec applies. If empty, it applies
|
||||
to all resources.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
labelSelector:
|
||||
description: LabelSelector, if specified, filters the
|
||||
resources to which this hook spec applies.
|
||||
nullable: true
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector
|
||||
that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In,
|
||||
NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values.
|
||||
If the operator is In or NotIn, the values
|
||||
array must be non-empty. If the operator is
|
||||
Exists or DoesNotExist, the values array must
|
||||
be empty. This array is replaced during a
|
||||
strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs.
|
||||
A single {key,value} in the matchLabels map is equivalent
|
||||
to an element of matchExpressions, whose key field
|
||||
is "key", the operator is "In", and the values array
|
||||
contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
name:
|
||||
description: Name is the name of this hook.
|
||||
type: string
|
||||
post:
|
||||
description: PostHooks is a list of BackupResourceHooks
|
||||
to execute after storing the item in the backup. These
|
||||
are executed after all "additional items" from item
|
||||
actions are processed.
|
||||
items:
|
||||
description: BackupResourceHook defines a hook for a
|
||||
resource.
|
||||
properties:
|
||||
exec:
|
||||
description: Exec defines an exec hook.
|
||||
properties:
|
||||
command:
|
||||
description: Command is the command and arguments
|
||||
to execute.
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
container:
|
||||
description: Container is the container in the
|
||||
pod where the command should be executed.
|
||||
If not specified, the pod's first container
|
||||
is used.
|
||||
type: string
|
||||
onError:
|
||||
description: OnError specifies how Velero should
|
||||
behave if it encounters an error executing
|
||||
this hook.
|
||||
enum:
|
||||
- Continue
|
||||
- Fail
|
||||
type: string
|
||||
timeout:
|
||||
description: Timeout defines the maximum amount
|
||||
of time Velero should wait for the hook to
|
||||
complete before considering the execution
|
||||
a failure.
|
||||
type: string
|
||||
required:
|
||||
- command
|
||||
type: object
|
||||
required:
|
||||
- exec
|
||||
type: object
|
||||
type: array
|
||||
pre:
|
||||
description: PreHooks is a list of BackupResourceHooks
|
||||
to execute prior to storing the item in the backup.
|
||||
These are executed before any "additional items" from
|
||||
item actions are processed.
|
||||
items:
|
||||
description: BackupResourceHook defines a hook for a
|
||||
resource.
|
||||
properties:
|
||||
exec:
|
||||
description: Exec defines an exec hook.
|
||||
properties:
|
||||
command:
|
||||
description: Command is the command and arguments
|
||||
to execute.
|
||||
items:
|
||||
type: string
|
||||
minItems: 1
|
||||
type: array
|
||||
container:
|
||||
description: Container is the container in the
|
||||
pod where the command should be executed.
|
||||
If not specified, the pod's first container
|
||||
is used.
|
||||
type: string
|
||||
onError:
|
||||
description: OnError specifies how Velero should
|
||||
behave if it encounters an error executing
|
||||
this hook.
|
||||
enum:
|
||||
- Continue
|
||||
- Fail
|
||||
type: string
|
||||
timeout:
|
||||
description: Timeout defines the maximum amount
|
||||
of time Velero should wait for the hook to
|
||||
complete before considering the execution
|
||||
a failure.
|
||||
type: string
|
||||
required:
|
||||
- command
|
||||
type: object
|
||||
required:
|
||||
- exec
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
nullable: true
|
||||
type: array
|
||||
type: object
|
||||
includeClusterResources:
|
||||
description: IncludeClusterResources specifies whether cluster-scoped
|
||||
resources should be included for consideration in the backup.
|
||||
nullable: true
|
||||
type: boolean
|
||||
includedNamespaces:
|
||||
description: IncludedNamespaces is a slice of namespace names to
|
||||
include objects from. If empty, all namespaces are included.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
includedResources:
|
||||
description: IncludedResources is a slice of resource names to include
|
||||
in the backup. If empty, all resources are included.
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
labelSelector:
|
||||
description: LabelSelector is a metav1.LabelSelector to filter with
|
||||
when adding individual objects to the backup. If empty or nil,
|
||||
all objects are included. Optional.
|
||||
nullable: true
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector requirements.
|
||||
The requirements are ANDed.
|
||||
items:
|
||||
description: A label selector requirement is a selector that
|
||||
contains values, a key, and an operator that relates the
|
||||
key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: operator represents a key's relationship
|
||||
to a set of values. Valid operators are In, NotIn, Exists
|
||||
and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: values is an array of string values. If the
|
||||
operator is In or NotIn, the values array must be non-empty.
|
||||
If the operator is Exists or DoesNotExist, the values
|
||||
array must be empty. This array is replaced during a
|
||||
strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: matchLabels is a map of {key,value} pairs. A single
|
||||
{key,value} in the matchLabels map is equivalent to an element
|
||||
of matchExpressions, whose key field is "key", the operator
|
||||
is "In", and the values array contains only "value". The requirements
|
||||
are ANDed.
|
||||
type: object
|
||||
type: object
|
||||
snapshotVolumes:
|
||||
description: SnapshotVolumes specifies whether to take cloud snapshots
|
||||
of any PV's referenced in the set of objects included in the Backup.
|
||||
nullable: true
|
||||
type: boolean
|
||||
storageLocation:
|
||||
description: StorageLocation is a string containing the name of
|
||||
a BackupStorageLocation where the backup should be stored.
|
||||
type: string
|
||||
ttl:
|
||||
description: TTL is a time.Duration-parseable string describing
|
||||
how long the Backup should be retained for.
|
||||
type: string
|
||||
volumeSnapshotLocations:
|
||||
description: VolumeSnapshotLocations is a list containing names
|
||||
of VolumeSnapshotLocations associated with this backup.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
required:
|
||||
- schedule
|
||||
- template
|
||||
type: object
|
||||
status:
|
||||
description: ScheduleStatus captures the current state of a Velero schedule
|
||||
properties:
|
||||
lastBackup:
|
||||
description: LastBackup is the last time a Backup was run for this Schedule
|
||||
schedule
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
phase:
|
||||
description: Phase is the current phase of the Schedule
|
||||
enum:
|
||||
- New
|
||||
- Enabled
|
||||
- FailedValidation
|
||||
type: string
|
||||
validationErrors:
|
||||
description: ValidationErrors is a slice of all validation errors (if
|
||||
applicable)
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
version: v1
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: serverstatusrequests.velero.io
|
||||
spec:
|
||||
@@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.2.4
|
||||
controller-gen.kubebuilder.io/version: v0.3.0
|
||||
creationTimestamp: null
|
||||
name: volumesnapshotlocations.velero.io
|
||||
spec:
|
||||
69
config/crd/crds/crds.go
Normal file
69
config/crd/crds/crds.go
Normal file
File diff suppressed because one or more lines are too long
28
config/rbac/role.yaml
Normal file
28
config/rbac/role.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: manager-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
- backupstoragelocations
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- velero.io
|
||||
resources:
|
||||
- backupstoragelocations/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
16
config/samples/velero_v1_backupstoragelocation.yaml
Normal file
16
config/samples/velero_v1_backupstoragelocation.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: velero.io/v1
|
||||
kind: BackupStorageLocation
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
component: velero
|
||||
name: default
|
||||
namespace: velero
|
||||
spec:
|
||||
config:
|
||||
region: minio
|
||||
s3ForcePathStyle: "true"
|
||||
s3Url: http://minio.velero.svc:9000
|
||||
objectStorage:
|
||||
bucket: velero
|
||||
provider: aws
|
||||
@@ -1,35 +1,35 @@
|
||||
# Design proposal template (replace with your proposal's title)
|
||||
|
||||
One to two sentences that describes the goal of this proposal.
|
||||
The reader should be able to tell by the title, and the opening paragraph, if this document is relevant to them.
|
||||
# Design proposal template `<replace with your proposal's title>`
|
||||
|
||||
_Note_: The preferred style for design documents is one sentence per line.
|
||||
*Do not wrap lines*.
|
||||
This aids in review of the document as changes to a line are not obscured by the reflowing those changes caused and has a side effect of avoiding debate about one or two space after a period.
|
||||
|
||||
## Goals
|
||||
_Note_: The name of the file should follow the name pattern `<short meaningful words joined by '-'>_design.md`, e.g:
|
||||
`listener-design.md`.
|
||||
|
||||
## Abstract
|
||||
One to two sentences that describes the goal of this proposal and the problem being solved by the proposed change.
|
||||
The reader should be able to tell by the title, and the opening paragraph, if this document is relevant to them.
|
||||
|
||||
## Background
|
||||
One to two paragraphs of exposition to set the context for this proposal.
|
||||
|
||||
## Goals
|
||||
- A short list of things which will be accomplished by implementing this proposal.
|
||||
- Two things is ok.
|
||||
- Three is pushing it.
|
||||
- More than three goals suggests that the proposal's scope is too large.
|
||||
|
||||
## Non Goals
|
||||
|
||||
- A short list of items which are:
|
||||
- a. out of scope
|
||||
- b. follow on items which are deliberately excluded from this proposal.
|
||||
|
||||
## Background
|
||||
|
||||
One to two paragraphs of exposition to set the context for this proposal.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
One to two paragraphs that describe the high level changes that will be made to implement this proposal.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
A detailed design describing how the changes to the product should be made.
|
||||
|
||||
The names of types, fields, interfaces, and methods should be agreed on here, not debated in code review.
|
||||
@@ -38,9 +38,16 @@ The same applies to changes in CRDs, YAML examples, and so on.
|
||||
Ideally the changes should be made in sequence so that the work required to implement this design can be done incrementally, possibly in parallel.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
If there are alternative high level or detailed designs that were not pursued they should be called out here with a brief explanation of why they were not pursued.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
If this proposal has an impact to the security of the product, its users, or data stored or transmitted via the product, they must be addressed here.
|
||||
|
||||
## Compatibility
|
||||
A discussion of any compatibility issues that need to be considered
|
||||
|
||||
## Implementation
|
||||
A description of the implementation, timelines, and any resources that have agreed to contribute.
|
||||
|
||||
## Open Issues
|
||||
A discussion of issues relating to this proposal for which the author does not know the solution. This section may be omitted if there are none.
|
||||
|
||||
40
design/backup-resources-order.md
Normal file
40
design/backup-resources-order.md
Normal file
@@ -0,0 +1,40 @@
|
||||
## Backup Resources Order
|
||||
This document proposes a solution that allows user to specify a backup order for resources of specific resource type.
|
||||
|
||||
## Background
|
||||
During backup process, user may need to back up resources of specific type in some specific order to ensure the resources were backup properly because these resources are related and ordering might be required to preserve the consistency for the apps to recover itself <20>from the backup image
|
||||
(Ex: primary-secondary database pods in a cluster).
|
||||
|
||||
## Goals
|
||||
- Enable user to specify an order of back up resources belong to specific resource type
|
||||
|
||||
## Alternatives Considered
|
||||
- Use a plugin to backup an resources and all the sub resources. For example use a plugin for StatefulSet and backup pods belong to the StatefulSet in specific order. This plugin solution is not generic and requires plugin for each resource type.
|
||||
|
||||
## High-Level Design
|
||||
User will specify a map of resource type to list resource names (separate by semicolons). Each name will be in the format "namespaceName/resourceName" to enable ordering accross namespaces. Based on this map, the resources of each resource type will be sorted by the order specified in the list of resources. If a resource instance belong to that specific type but its name is not in the order list, then it will be put behind other resources that are in the list.
|
||||
|
||||
### Changes to BackupSpec
|
||||
Add new field to BackupSpec
|
||||
|
||||
type BackupSpec struct {
|
||||
...
|
||||
// OrderedResources contains a list of key-value pairs that represent the order
|
||||
// of backup of resources that belong to specific resource type
|
||||
// +optional
|
||||
// +nullable
|
||||
OrderedResources map[string]string
|
||||
}
|
||||
|
||||
### Changes to itemCollector
|
||||
Function getResourceItems collects all items belong to a specific resource type. This function will be enhanced to check with the map to see whether the OrderedResources has specified the order for this resource type. If such order exists, then sort the items by such order being process before return.
|
||||
|
||||
### Changes to velero CLI
|
||||
Add new flag "--ordered-resources" to Velero backup create command which takes a string of key-values pairs which represents the map between resource type and the order of the items of such resource type. Key-value pairs are separated by semicolon, items in the value are separated by commas.
|
||||
|
||||
Example:
|
||||
>velero backup create mybackup --ordered-resources "pod=ns1/pod1,ns1/pod2;persistentvolumeclaim=n2/slavepod,ns2/primarypod"
|
||||
|
||||
## Open Issues
|
||||
- In the CLI, the design proposes to use commas to separate items of a resource type and semicolon to separate key-value pairs. This follows the convention of using commas to separate items in a list (For example: --include-namespaces ns1,ns2). However, the syntax for map in labels and annotations use commas to seperate key-value pairs. So it introduces some inconsistency.
|
||||
- For pods that managed by Deployment or DaemonSet, this design may not work because the pods' name is randomly generated and if pods are restarted, they would have different names so the Backup operation may not consider the restarted pods in the sorting algorithm. This problem will be addressed when we enhance the design to use regular expression to specify the OrderResources instead of exact match.
|
||||
448
design/plugin-backup-and-restore-progress-design.md
Normal file
448
design/plugin-backup-and-restore-progress-design.md
Normal file
@@ -0,0 +1,448 @@
|
||||
# Progress reporting for backups and restores handled by volume snapshotters
|
||||
|
||||
Users face difficulty in knowing the progress of backup/restore operations of volume snapshotters. This is very similar to the issues faced by users to know progress for restic backup/restore, like, estimation of operation, operation in-progress/hung etc.
|
||||
|
||||
Each plugin might be providing a way to know the progress, but, it need not uniform across the plugins.
|
||||
|
||||
Even though plugins provide the way to know the progress of backup operation, this information won't be available to user during restore time on the destination cluster.
|
||||
|
||||
So, apart from the issues like progress, status of operation, volume snapshotters have unique problems like
|
||||
- not being uniform across plugins
|
||||
- not knowing the backup information during restore operation
|
||||
- need to be optional as few plugins may not have a way to provide the progress information
|
||||
|
||||
This document proposes an approach for plugins to follow to provide backup/restore progress, which can be used by users to know the progress.
|
||||
|
||||
## Goals
|
||||
|
||||
- Provide uniform way of visibility into backup/restore operations performed by volume snapshotters
|
||||
|
||||
## Non Goals
|
||||
- Plugin implementation for this approach
|
||||
|
||||
## Background
|
||||
|
||||
(Omitted, see introduction)
|
||||
|
||||
## High-Level Design
|
||||
|
||||
### Progress of backup operation handled by volume snapshotter
|
||||
|
||||
Progress will be updated by volume snapshotter in VolumePluginBackup CR which is specific to that backup operation.
|
||||
|
||||
### Progress of restore operation handled by volume snapshotter
|
||||
|
||||
Progress will be updated by volume snapshotter in VolumePluginRestore CR which is specific to that restore operation.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
### Approach 1
|
||||
|
||||
Existing `Snapshot` Go struct from `volume` package have most of the details related to backup operation performed by volumesnapshotters.
|
||||
This struct also gets backed up to backup location. But, this struct doesn't get synced on other clusters at regular intervals.
|
||||
It is currently synced only during restore operation, and velero CLI shows few of its contents.
|
||||
|
||||
At a high level, in this approach, this struct will be converted to a CR by adding new fields (related to Progress tracking) to it, and gets rid of `volume.Snapshot` struct.
|
||||
|
||||
Instead of backing up of Go struct, proposal is: to backup CRs to backup location, and sync them into other cluster by backupSyncController running in that cluster.
|
||||
|
||||
#### VolumePluginBackup CR
|
||||
|
||||
There is one addition to volume.SnapshotSpec, i.e., ProviderName to convert it to CR's spec. Below is the updated VolumePluginBackup CR's Spec:
|
||||
|
||||
```
|
||||
type VolumePluginBackupSpec struct {
|
||||
// BackupName is the name of the Velero backup this snapshot
|
||||
// is associated with.
|
||||
BackupName string `json:"backupName"`
|
||||
|
||||
// BackupUID is the UID of the Velero backup this snapshot
|
||||
// is associated with.
|
||||
BackupUID string `json:"backupUID"`
|
||||
|
||||
// Location is the name of the VolumeSnapshotLocation where this snapshot is stored.
|
||||
Location string `json:"location"`
|
||||
|
||||
// PersistentVolumeName is the Kubernetes name for the volume.
|
||||
PersistentVolumeName string `json:"persistentVolumeName"`
|
||||
|
||||
// ProviderVolumeID is the provider's ID for the volume.
|
||||
ProviderVolumeID string `json:"providerVolumeID"`
|
||||
|
||||
// Provider is the Provider field given in VolumeSnapshotLocation
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// VolumeType is the type of the disk/volume in the cloud provider
|
||||
// API.
|
||||
VolumeType string `json:"volumeType"`
|
||||
|
||||
// VolumeAZ is the where the volume is provisioned
|
||||
// in the cloud provider.
|
||||
VolumeAZ string `json:"volumeAZ,omitempty"`
|
||||
|
||||
// VolumeIOPS is the optional value of provisioned IOPS for the
|
||||
// disk/volume in the cloud provider API.
|
||||
VolumeIOPS *int64 `json:"volumeIOPS,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
Few fields (except first two) are added to volume.SnapshotStatus to convert it to CR's status. Below is the updated VolumePluginBackup CR's status:
|
||||
```
|
||||
type VolumePluginBackupStatus struct {
|
||||
// ProviderSnapshotID is the ID of the snapshot taken in the cloud
|
||||
// provider API of this volume.
|
||||
ProviderSnapshotID string `json:"providerSnapshotID,omitempty"`
|
||||
|
||||
// Phase is the current state of the VolumeSnapshot.
|
||||
Phase SnapshotPhase `json:"phase,omitempty"`
|
||||
|
||||
// PluginSpecific are a map of key-value pairs that plugin want to provide
|
||||
// to user to identify plugin properties related to this backup
|
||||
// +optional
|
||||
PluginSpecific map[string]string `json:"pluginSpecific,omitempty"`
|
||||
|
||||
// Message is a message about the volume plugin's backup's status.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// StartTimestamp records the time a backup was started.
|
||||
// Separate from CreationTimestamp, since that value changes
|
||||
// on restores.
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
// Completion time is recorded before uploading the backup object.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
|
||||
// Progress holds the total number of bytes of the volume and the current
|
||||
// number of backed up bytes. This can be used to display progress information
|
||||
// about the backup operation.
|
||||
// +optional
|
||||
Progress VolumeOperationProgress `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
type VolumeOperationProgress struct {
|
||||
TotalBytes int64
|
||||
BytesDone int64
|
||||
}
|
||||
|
||||
type VolumePluginBackup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec VolumePluginBackupSpec `json:"spec,omitempty"`
|
||||
|
||||
// +optional
|
||||
Status VolumePluginBackupStatus `json:"status,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
For every backup operation of volume, Velero creates VolumePluginBackup CR before calling volumesnapshotter's CreateSnapshot API.
|
||||
|
||||
In order to know the CR created for the particular backup of a volume, Velero adds following labels to CR:
|
||||
- `velero.io/backup-name` with value as Backup Name, and,
|
||||
- `velero.io/pv-name` with value as volume that is undergoing backup
|
||||
|
||||
Backup name being unique won't cause issues like duplicates in identifying the CR.
|
||||
Labels will be set with the value returned from `GetValidName` function. (https://github.com/vmware-tanzu/velero/blob/master/pkg/label/label.go#L35).
|
||||
|
||||
If Plugin supports showing progress of the operation it is performing, it does following:
|
||||
- finds the VolumePluginBackup CR related to this backup operation by using `tags` passed in CreateSnapshot call
|
||||
- updates the CR with the progress regularly.
|
||||
|
||||
After return from `CreateSnapshot` in `takePVSnapshot`, currently Velero adds `volume.Snapshot` to `backupRequest`. Instead of this, CR will be added to `backupRequest`.
|
||||
During persistBackup call, this CR also will be backed up to backup location.
|
||||
|
||||
In backupSyncController, it checks for any VolumePluginBackup CRs that need to be synced from backup location, and syncs them to cluster if needed.
|
||||
|
||||
VolumePluginBackup will be useful as long as backed up data is available at backup location. When the Backup is deleted either by manually or due to expiry, VolumePluginBackup also can be deleted.
|
||||
|
||||
`processRequest` of `backupDeletionController` will perform deletion of VolumePluginBackup before volumesnapshotter's DeleteSnapshot is called.
|
||||
|
||||
#### Backward compatibility:
|
||||
|
||||
Currently `volume.Snapshot` is backed up as `<backupname>-volumesnapshots.json.gz` file in the backup location.
|
||||
|
||||
As the VolumePluginBackup CR is backed up instead of `volume.Snapshot`, to provide backward compatibility, CR will be backed as the same file i.e., `<backupname>-volumesnapshots.json.gz` file in the backup location.
|
||||
|
||||
For backward compatibility on restore side, consider below possible cases wrt Velero version on restore side and format of json.gz file at object location:
|
||||
|
||||
- older version of Velero, older json.gz file (backupname-volumesnapshots.json.gz)
|
||||
|
||||
- older version of Velero, newer json.gz file
|
||||
|
||||
- newer version of Velero, older json.gz file
|
||||
|
||||
- newer version of Velero, newer json.gz file
|
||||
|
||||
First and last should be fine.
|
||||
|
||||
For second case, decode in `GetBackupVolumeSnapshots` on the restore side should fill only required fields of older version and should work.
|
||||
|
||||
For third case, after decode, metadata.name will be empty. `GetBackupVolumeSnapshots` decodes older json.gz into the CR which goes fine.
|
||||
It will be modified to return []VolumePluginBackupSpec, and the changes are done accordingly in its caller.
|
||||
|
||||
If decode fails in second case during implementation, this CR need to be backed up to different file. And, for backward compatibility, newer code should check for old file existence, and follow older code if exists. If it doesn't exists, check for newer file and follow the newer code.
|
||||
|
||||
`backupSyncController` on restore clusters gets the `<backupname>-volumesnapshots.json.gz` object from backup location and decodes it to in-memory VolumePluginBackup CR. If its `metadata.name` is populated, controller creates CR. Otherwise, it will not create the CR on the cluster. It can be even considered to create CR on the cluster.
|
||||
|
||||
#### VolumePluginRestore CR
|
||||
|
||||
```
|
||||
// VolumePluginRestoreSpec is the specification for a VolumePluginRestore CR.
|
||||
type VolumePluginRestoreSpec struct {
|
||||
// SnapshotID is the identifier for the snapshot of the volume.
|
||||
// This will be used to relate with output in 'velero describe backup'
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
|
||||
// BackupName is the name of the Velero backup from which PV will be
|
||||
// created.
|
||||
BackupName string `json:"backupName"`
|
||||
|
||||
// Provider is the Provider field given in VolumeSnapshotLocation
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// VolumeType is the type of the disk/volume in the cloud provider
|
||||
// API.
|
||||
VolumeType string `json:"volumeType"`
|
||||
|
||||
// VolumeAZ is the where the volume is provisioned
|
||||
// in the cloud provider.
|
||||
VolumeAZ string `json:"volumeAZ,omitempty"`
|
||||
}
|
||||
|
||||
// VolumePluginRestoreStatus is the current status of a VolumePluginRestore CR.
|
||||
type VolumePluginRestoreStatus struct {
|
||||
// Phase is the current state of the VolumePluginRestore.
|
||||
Phase string `json:"phase"`
|
||||
|
||||
// VolumeID is the PV name to which restore done
|
||||
VolumeID string `json:"volumeID"`
|
||||
|
||||
// Message is a message about the volume plugin's restore's status.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// StartTimestamp records the time a restore was started.
|
||||
// Separate from CreationTimestamp, since that value changes
|
||||
// on restores.
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a restore was completed.
|
||||
// Completion time is recorded even on failed restores.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
|
||||
// Progress holds the total number of bytes of the snapshot and the current
|
||||
// number of restored bytes. This can be used to display progress information
|
||||
// about the restore operation.
|
||||
// +optional
|
||||
Progress VolumeOperationProgress `json:"progress,omitempty"`
|
||||
|
||||
// PluginSpecific are a map of key-value pairs that plugin want to provide
|
||||
// to user to identify plugin properties related to this restore
|
||||
// +optional
|
||||
PluginSpecific map[string]string `json:"pluginSpecific,omitempty"`
|
||||
}
|
||||
|
||||
type VolumePluginRestore struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec VolumePluginRestoreSpec `json:"spec,omitempty"`
|
||||
|
||||
// +optional
|
||||
Status VolumePluginRestoreStatus `json:"status,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
For every restore operation, Velero creates VolumePluginRestore CR before calling volumesnapshotter's CreateVolumeFromSnapshot API.
|
||||
|
||||
In order to know the CR created for the particular restore of a volume, Velero adds following labels to CR:
|
||||
- `velero.io/backup-name` with value as Backup Name, and,
|
||||
- `velero.io/snapshot-id` with value as snapshot id that need to be restored
|
||||
- `velero.io/provider` with value as `Provider` in `VolumeSnapshotLocation`
|
||||
|
||||
Labels will be set with the value returned from `GetValidName` function. (https://github.com/vmware-tanzu/velero/blob/master/pkg/label/label.go#L35).
|
||||
|
||||
Plugin will be able to identify CR by using snapshotID that it received as parameter of CreateVolumeFromSnapshot API, and plugin's Provider name.
|
||||
It updates the progress of restore operation regularly if plugin supports feature of showing progress.
|
||||
|
||||
Velero deletes VolumePluginRestore CR when it handles deletion of Restore CR.
|
||||
|
||||
### Approach 2
|
||||
|
||||
This approach is different to approach 1 only with respect to Backup.
|
||||
|
||||
#### VolumePluginBackup CR
|
||||
|
||||
```
|
||||
// VolumePluginBackupSpec is the specification for a VolumePluginBackup CR.
|
||||
type VolumePluginBackupSpec struct {
|
||||
// Volume is the PV name to be backed up.
|
||||
Volume string `json:"volume"`
|
||||
|
||||
// Backup name
|
||||
Backup string `json:"backup"`
|
||||
|
||||
// Provider is the Provider field given in VolumeSnapshotLocation
|
||||
Provider string `json:"provider"`
|
||||
}
|
||||
|
||||
// VolumePluginBackupStatus is the current status of a VolumePluginBackup CR.
|
||||
type VolumePluginBackupStatus struct {
|
||||
// Phase is the current state of the VolumePluginBackup.
|
||||
Phase string `json:"phase"`
|
||||
|
||||
// SnapshotID is the identifier for the snapshot of the volume.
|
||||
// This will be used to relate with output in 'velero describe backup'
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
|
||||
// Message is a message about the volume plugin's backup's status.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
|
||||
// StartTimestamp records the time a backup was started.
|
||||
// Separate from CreationTimestamp, since that value changes
|
||||
// on restores.
|
||||
// The server's time is used for StartTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
StartTimestamp *metav1.Time `json:"startTimestamp,omitempty"`
|
||||
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
// Completion time is recorded before uploading the backup object.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
// +optional
|
||||
// +nullable
|
||||
CompletionTimestamp *metav1.Time `json:"completionTimestamp,omitempty"`
|
||||
|
||||
// PluginSpecific are a map of key-value pairs that plugin want to provide
|
||||
// to user to identify plugin properties related to this backup
|
||||
// +optional
|
||||
PluginSpecific map[string]string `json:"pluginSpecific,omitempty"`
|
||||
|
||||
// Progress holds the total number of bytes of the volume and the current
|
||||
// number of backed up bytes. This can be used to display progress information
|
||||
// about the backup operation.
|
||||
// +optional
|
||||
Progress VolumeOperationProgress `json:"progress,omitempty"`
|
||||
}
|
||||
|
||||
type VolumeOperationProgress struct {
|
||||
TotalBytes int64
|
||||
BytesDone int64
|
||||
}
|
||||
|
||||
type VolumePluginBackup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec VolumePluginBackupSpec `json:"spec,omitempty"`
|
||||
|
||||
// +optional
|
||||
Status VolumePluginBackupStatus `json:"status,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
For every backup operation of volume, volume snapshotter creates VolumePluginBackup CR in Velero namespace.
|
||||
It keep updating the progress of operation along with other details like Volume name, Backup Name, SnapshotID etc as mentioned in the CR.
|
||||
|
||||
In order to know the CR created for the particular backup of a volume, volume snapshotters adds following labels to CR:
|
||||
- `velero.io/backup-name` with value as Backup Name, and,
|
||||
- `velero.io/volume-name` with value as volume that is undergoing backup
|
||||
|
||||
Backup name being unique won't cause issues like duplicates in identifying the CR.
|
||||
|
||||
Plugin need to sanitize the value that can be set for above labels. Label need to be set with the value returned from `GetValidName` function. (https://github.com/vmware-tanzu/velero/blob/master/pkg/label/label.go#L35).
|
||||
|
||||
Though no restrictions are required on the name of CR, as a general practice, volume snapshotter can name this CR with the value same as return value of CreateSnapshot.
|
||||
|
||||
After return from `CreateSnapshot` in `takePVSnapshot`, if VolumePluginBackup CR exists for particular backup of the volume, velero adds this CR to `backupRequest`.
|
||||
During persistBackup call, this CR also will be backed up to backup location.
|
||||
|
||||
In backupSyncController, it checks for any VolumePluginBackup CRs that need to be synced from backup location, and syncs them to cluster if needed.
|
||||
|
||||
`processRequest` of `backupDeletionController` will perform deletion of VolumePluginBackup before volumesnapshotter's DeleteSnapshot is called.
|
||||
|
||||
Another alternative is:
|
||||
Deletion of `VolumePluginBackup` CR can be delegated to plugin. Plugin can perform deletion of VolumePluginBackup using the `snapshotID` passed in volumesnapshotter's DeleteSnapshot request.
|
||||
|
||||
### 'core' Velero client/server required changes
|
||||
|
||||
- Creation of the VolumePluginBackup/VolumePluginRestore CRDs at installation time
|
||||
- Persistence of VolumePluginBackup CRs towards the end of the back up operation
|
||||
- As part of backup synchronization, VolumePluginBackup CRs related to the backup will be synced.
|
||||
- Deletion of VolumePluginBackup when volumeshapshotter's DeleteSnapshot is called
|
||||
- Deletion of VolumePluginRestore as part of handling deletion of Restore CR
|
||||
- In case of approach 1,
|
||||
- converting `volume.Snapshot` struct as CR and its related changes
|
||||
- creation of VolumePlugin(Backup|Restore) CRs before calling volumesnapshotter's API
|
||||
- `GetBackupVolumeSnapshots` and its callers related changes for change in return type from []volume.Snapshot to []VolumePluginBackupSpec.
|
||||
|
||||
### Velero CLI required changes
|
||||
|
||||
In 'velero describe' CLI, required CRs will be fetched from API server and its contents like backupName, PVName (if changed due to label size limitation), size of PV snapshot will be shown in the output.
|
||||
|
||||
### API Upgrade
|
||||
When CRs gets upgraded, velero can support older API versions also (till they get deprecated) to identify the CRs that need to be persisted to backup location.
|
||||
However, it can provide preference over latest supported API.
|
||||
|
||||
If new fields are added without changing API version, it won't cause any problem as these resources are intended to provide information, and, there is no reconciliation on these resources.
|
||||
|
||||
### Compatibility of latest plugin with older version of Velero
|
||||
Plugin that supports this CR should handle the situation gracefully when CRDs are not installed. It can handle the errors occured during creation/updation of the CRs.
|
||||
|
||||
## Limitations:
|
||||
|
||||
Non K8s native plugins will not be able to implement this as they can not create the CRs.
|
||||
|
||||
## Open Questions
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Add another method to VolumeSnapshotter interface
|
||||
Above proposed approach have limitation that plugin need to be K8s native in order to create, update CRs.
|
||||
Instead, a new method for 'Progress' will be added to interface. Velero server regularly polls this 'Progress' method and updates VolumePluginBackup CR on behalf of plugin.
|
||||
|
||||
But, this involves good amount of changes and needs a way for backward compatibility.
|
||||
|
||||
As volume plugins are mostly K8s native, its fine to go ahead with current limiation.
|
||||
|
||||
### Update Backup CR
|
||||
Instead of creating new CRs, plugins can directly update the status of Backup CR. But, this deviates from current approach of having seperate CRs like PodVolumeBackup/PodVolumeRestore to know operations progress.
|
||||
|
||||
### Restricting on name rather than using labels
|
||||
Instead of using labels to identify the CR related to particular backup on a volume, restrictions can be placed on the name of VolumePluginBackup CR to be same as the value returned from CreateSnapshot.
|
||||
But, this can cause issue when volume snapshotter just crashed without returning snapshot id to velero.
|
||||
|
||||
### Backing up VolumePluginBackup CR to different object
|
||||
If CR is backed up to different object other than `#backup-volumesnapshots.json.gz` in backup location, restore controller need to follow 'fall-back model'.
|
||||
It first need to check for new kind of object, and, if it doesn't exists, follow the old model. To avoid 'fall-back' model which prone to errors, VolumePluginBackup CR is backed to same location as that of `volume.Snapshot` location.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
Currently everything runs under the same `velero` service account so all plugins have broad access, which would include being able to modify CRs created by another plugin.
|
||||
|
||||
77
go.mod
77
go.mod
@@ -4,39 +4,80 @@ go 1.14
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.46.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.9.0
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0
|
||||
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.9.6
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.13.12
|
||||
github.com/aws/aws-sdk-go v1.28.2
|
||||
github.com/docker/spdystream v0.0.0-20170912183627-bc6354cbbc29 // indirect
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible
|
||||
github.com/go-ini/ini v1.28.2 // indirect
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/gofrs/uuid v3.2.0+incompatible
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd
|
||||
github.com/hashicorp/go-plugin v0.0.0-20190610192547-a1bc61569a26
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 // indirect
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.1.0
|
||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.2.0-rc1
|
||||
github.com/onsi/ginkgo v1.13.0
|
||||
github.com/onsi/gomega v1.10.1
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/prometheus/client_golang v1.0.0
|
||||
github.com/robfig/cron v0.0.0-20170309132418-df38d32658d8
|
||||
github.com/robfig/cron v1.1.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/spf13/afero v1.2.2
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
|
||||
google.golang.org/grpc v1.26.0
|
||||
k8s.io/api v0.17.4
|
||||
k8s.io/apiextensions-apiserver v0.17.4
|
||||
k8s.io/apimachinery v0.17.4
|
||||
k8s.io/cli-runtime v0.17.4
|
||||
k8s.io/client-go v0.17.4
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7
|
||||
google.golang.org/grpc v1.28.0
|
||||
k8s.io/api v0.18.4
|
||||
k8s.io/apiextensions-apiserver v0.18.4
|
||||
k8s.io/apimachinery v0.18.4
|
||||
k8s.io/cli-runtime v0.18.4
|
||||
k8s.io/client-go v0.18.4
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/utils v0.0.0-20191218082557-f07c713de883 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.6.1
|
||||
)
|
||||
|
||||
replace k8s.io/api => k8s.io/api v0.18.4
|
||||
|
||||
replace k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.18.4
|
||||
|
||||
replace k8s.io/apimachinery => k8s.io/apimachinery v0.18.4
|
||||
|
||||
replace k8s.io/apiserver => k8s.io/apiserver v0.18.4
|
||||
|
||||
replace k8s.io/cli-runtime => k8s.io/cli-runtime v0.18.4
|
||||
|
||||
replace k8s.io/client-go => k8s.io/client-go v0.18.4
|
||||
|
||||
replace k8s.io/cloud-provider => k8s.io/cloud-provider v0.18.4
|
||||
|
||||
replace k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.18.4
|
||||
|
||||
replace k8s.io/code-generator => k8s.io/code-generator v0.18.4
|
||||
|
||||
replace k8s.io/component-base => k8s.io/component-base v0.18.4
|
||||
|
||||
replace k8s.io/cri-api => k8s.io/cri-api v0.18.4
|
||||
|
||||
replace k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.18.4
|
||||
|
||||
replace k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.18.4
|
||||
|
||||
replace k8s.io/kube-proxy => k8s.io/kube-proxy v0.18.4
|
||||
|
||||
replace k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.18.4
|
||||
|
||||
replace k8s.io/kubectl => k8s.io/kubectl v0.18.4
|
||||
|
||||
replace k8s.io/kubelet => k8s.io/kubelet v0.18.4
|
||||
|
||||
replace k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.18.4
|
||||
|
||||
replace k8s.io/metrics => k8s.io/metrics v0.18.4
|
||||
|
||||
replace k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.18.4
|
||||
|
||||
replace k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.18.4
|
||||
|
||||
502
go.sum
502
go.sum
@@ -1,3 +1,4 @@
|
||||
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.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
@@ -9,20 +10,40 @@ cloud.google.com/go v0.46.2/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible h1:PkmdmQUmeSdQQ5258f4SyCf2Zcz0w67qztEg37cOR7U=
|
||||
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible h1:yz6sFf5bHZ+gEOQVuK5JhPqTTAmv+OvSLSaqgzqaCwY=
|
||||
github.com/Azure/azure-sdk-for-go v42.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
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 v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0=
|
||||
github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
|
||||
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/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
|
||||
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 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
|
||||
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.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8=
|
||||
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 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4=
|
||||
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=
|
||||
@@ -31,8 +52,15 @@ github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VY
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
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/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/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/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
|
||||
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
@@ -40,73 +68,127 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
|
||||
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/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
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/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.13.12 h1:+L7aikwNnPSzdbgbbcAc0M9spXpvD64Kug3w6CnJxnw=
|
||||
github.com/aws/aws-sdk-go v1.13.12/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
|
||||
github.com/auth0/go-jwt-middleware v0.0.0-20170425171159-5493cabe49f7/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
|
||||
github.com/aws/aws-sdk-go v1.28.2 h1:j5IXG9CdyLfcVfICqo1PXVv+rua+QQHbkXuvuU/JF+8=
|
||||
github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/bazelbuild/bazel-gazelle v0.18.2/go.mod h1:D0ehMSbS+vesFsLGiD6JXu3mVEzOlfUl8wNnq+x/9p0=
|
||||
github.com/bazelbuild/bazel-gazelle v0.19.1-0.20191105222053-70208cbdc798/go.mod h1:rPwzNHUqEzngx1iVBfO/2X2npKaT3tqPqqHW6rVsn/A=
|
||||
github.com/bazelbuild/buildtools v0.0.0-20190731111112-f720930ceb60/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU=
|
||||
github.com/bazelbuild/buildtools v0.0.0-20190917191645-69366ca98f89/go.mod h1:5JP0TXzWDHXv8qvxRC4InIazwdyDseBDbzESUMKk1yU=
|
||||
github.com/bazelbuild/rules_go v0.0.0-20190719190356-6dae44dc5cab/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
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/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
|
||||
github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
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/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||
github.com/checkpoint-restore/go-criu v0.0.0-20181120144056-17b0214f6c48/go.mod h1:TrMrLQfeENAPYPRsJuq3jsqdlRh3lvi6trTZJG8+tho=
|
||||
github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/cilium/ebpf v0.0.0-20191025125908-95b36a581eed/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
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/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
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/container-storage-interface/spec v1.2.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/typeurl v0.0.0-20190228175220-2a93cfde8c20/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
|
||||
github.com/coredns/corefile-migration v1.0.6/go.mod h1:OFwBp/Wc9dJt5cAZzHWMNhK1r5L0p0jDwIBc6j8NC8E=
|
||||
github.com/coreos/etcd v3.3.10+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 v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
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-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
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/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/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.3.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.8.0-dev.2.0.20190925143933-c8a5fca4a652/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-20170912183627-bc6354cbbc29 h1:llBx5m8Gk0lrAaiLud2wktkX/e8haX7Ru0oVfQqtZQ4=
|
||||
github.com/docker/spdystream v0.0.0-20170912183627-bc6354cbbc29/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
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 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/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||
github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/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-ini/ini v1.28.2 h1:drmmYv7psRpoGZkPtPKKTB+ZFSnvmwCMfNj5o1nLh2Y=
|
||||
github.com/go-ini/ini v1.28.2/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-acme/lego v2.5.0+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M=
|
||||
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||
github.com/go-critic/go-critic v0.3.5-0.20190526074819-1df300866540/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
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 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=
|
||||
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
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.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||
@@ -150,37 +232,86 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
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.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
|
||||
github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
|
||||
github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
|
||||
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
|
||||
github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg=
|
||||
github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
|
||||
github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
|
||||
github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk=
|
||||
github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
|
||||
github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks=
|
||||
github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
|
||||
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
|
||||
github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/godbus/dbus v0.0.0-20181101234600-2ff6f7ffd60f/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/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.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
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-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.0.0/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.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/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
|
||||
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
|
||||
github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0=
|
||||
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
|
||||
github.com/golangci/go-tools v0.0.0-20190318055746-e32c54105b7c/go.mod h1:unzUULGw35sjyOYjUt0jMTXqHlZPpPc6e+xfO4cd6mM=
|
||||
github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o=
|
||||
github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU=
|
||||
github.com/golangci/gofmt v0.0.0-20181222123516-0b8337e80d98/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
|
||||
github.com/golangci/golangci-lint v1.18.0/go.mod h1:kaqo8l0OZKYPtjNmG4z4HrWLgcYNIJ9B9q3LWri9uLg=
|
||||
github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547/go.mod h1:0qUabqiIQgfmlAmulqxyiGkkyF6/tOGSnY2cnPVwrzU=
|
||||
github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
|
||||
github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
|
||||
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
|
||||
github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
|
||||
github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI=
|
||||
github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4=
|
||||
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
|
||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||
github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
|
||||
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/cadvisor v0.35.0/go.mod h1:1nql6U13uTHaLYB8rLS5x9IJc2qT6Xd/Tr1sTX6NE48=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
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/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
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-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
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=
|
||||
@@ -191,13 +322,18 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.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.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
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.7.0/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/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
|
||||
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
@@ -206,155 +342,258 @@ github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd h1:rNuUHR+CvK1I
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-plugin v0.0.0-20190610192547-a1bc61569a26 h1:sADP8l/FAtMyWJ9GIcQT/04Ae80ZZ75ogOrtW0DIZhc=
|
||||
github.com/hashicorp/go-plugin v0.0.0-20190610192547-a1bc61569a26/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
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.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o=
|
||||
github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/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.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
|
||||
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/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
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 v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
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/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
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 v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
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.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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/kubernetes-csi/csi-lib-utils v0.7.0/go.mod h1:bze+2G9+cmoHxN6+WyG1qT4MDxgZJMLGwc7V4acPNm0=
|
||||
github.com/kubernetes-csi/csi-test v2.0.0+incompatible/go.mod h1:YxJ4UiuPWIhMBkxUKY5c267DyA0uDZ/MtAimhx/2TA0=
|
||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.1.0 h1:a1cpbNAdOTHO7Lk5UO5tjcbYPEEamIxmzATt+pKoDhc=
|
||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.1.0/go.mod h1:dV5oB3U62KBdlf9ADWkMmjGd3USauqQtwIm2OZb5mqI=
|
||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.2.0-rc1 h1:/71hejlH+46ySQJf7iZMOnuYaZNVNXq1lx6vIPqgUFE=
|
||||
github.com/kubernetes-csi/external-snapshotter/v2 v2.2.0-rc1/go.mod h1:ArR2bKKq4dEfoRwRH69kt/xYOliLUlaqCZ+LM1teU8Q=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
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/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA=
|
||||
github.com/lucas-clemente/aes12 v0.0.0-20171027163421-cd47fb39b79f/go.mod h1:JpH9J1c9oX6otFSgdUHwUBUizmKlrMjxWnIAjff4m04=
|
||||
github.com/lucas-clemente/quic-clients v0.1.0/go.mod h1:y5xVIEoObKqULIKivu+gD/LU90pL73bTdtQjPBvtCBk=
|
||||
github.com/lucas-clemente/quic-go v0.10.2/go.mod h1:hvaRS9IHjFLMq76puFJeWNfmn+H70QZ/CXoxqw9bzao=
|
||||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
|
||||
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/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-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
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/mesos/mesos-go v0.0.9/go.mod h1:kPYCMQ9gsOXVAle1OsoY4I1+9kPu8GHkf88aV59fDr4=
|
||||
github.com/mholt/certmagic v0.6.2-0.20190624175158-6a42ef9fe8c2/go.mod h1:g4cOPxcjV0oFq3qwpjSA30LReKD8AoIfwAY9VvG35NY=
|
||||
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY=
|
||||
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
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/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mozilla/tls-observatory v0.0.0-20180409132520-8791a200eb40/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
||||
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/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-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
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.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
|
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
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/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
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/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.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
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/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
|
||||
github.com/quobyte/api v0.1.2/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI=
|
||||
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 h1:b904/jbnmYuSPd5ojGzVTLjKPVTSj3t/e1vEPiPGjEg=
|
||||
github.com/robfig/cron v0.0.0-20170309132418-df38d32658d8/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY=
|
||||
github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
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/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
|
||||
github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
|
||||
github.com/spf13/afero v1.1.0/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 v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.3/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/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
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.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 v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/storageos/go-api v0.0.0-20180912212459-343b3eff91fc/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
|
||||
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 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
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.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-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
|
||||
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
|
||||
github.com/valyala/quicktemplate v1.1.1/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/vishvananda/netlink v1.0.0/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.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
@@ -364,26 +603,40 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
golang.org/x/build v0.0.0-20190927031335-2835ba2e683f/go.mod h1:fYw7AShPAhGMdXqA9gRadk/CcMsvLlClpE5oBwnS3dM=
|
||||
golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
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-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
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=
|
||||
@@ -397,18 +650,24 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
|
||||
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/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20170915142106-8351a756f30f/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-20180911220305-26e67e76b6c3/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-20181102091132-c10e9556a7bc/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-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-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-20190328230028-74de082e2cca/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
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=
|
||||
@@ -416,62 +675,91 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/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-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/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
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/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-20171026204733-164713f0dfce/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-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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190122071731-054c452bb702/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/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-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220220014-0732a990476f h1:72l8qCJ1nGxMGH26QVBVIxKd/D34cfGt0OvrPtpemyY=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220220014-0732a990476f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/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.0.0-20170915090833-1cbadb444a80/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.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
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/tools v0.0.0-20170915040203-e531a2a1c15f/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-20180525024113-a5b4c53f6e8b/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-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/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-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190122202912-9c309ee22fab/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-20190311215038-5c2858a9cfe5/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-20190322203728-c1a832b0ad89/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-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/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-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
@@ -479,13 +767,22 @@ golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/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-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/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-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
||||
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=
|
||||
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
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=
|
||||
@@ -510,74 +807,119 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
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.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
|
||||
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.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
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/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/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/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/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.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
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/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
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/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.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
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/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI=
|
||||
k8s.io/api v0.17.4 h1:HbwOhDapkguO8lTAE8OX3hdF2qp8GtpC9CW/MQATXXo=
|
||||
k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA=
|
||||
k8s.io/apiextensions-apiserver v0.17.4 h1:ZKFnw3cJrGZ/9s6y+DerTF4FL+dmK0a04A++7JkmMho=
|
||||
k8s.io/apiextensions-apiserver v0.17.4/go.mod h1:rCbbbaFS/s3Qau3/1HbPlHblrWpFivoaLYccCffvQGI=
|
||||
k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
|
||||
k8s.io/apimachinery v0.17.1-beta.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
|
||||
k8s.io/apimachinery v0.17.4 h1:UzM+38cPUJnzqSQ+E1PY4YxMHIzQyCg29LOoGfo79Zw=
|
||||
k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
|
||||
k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I=
|
||||
k8s.io/cli-runtime v0.17.4 h1:ZIJdxpBEszZqUhydrCoiI5rLXS2J/1AF5xFok2QJ9bc=
|
||||
k8s.io/cli-runtime v0.17.4/go.mod h1:IVW4zrKKx/8gBgNNkhiUIc7nZbVVNhc1+HcQh+PiNHc=
|
||||
k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k=
|
||||
k8s.io/client-go v0.17.4 h1:VVdVbpTY70jiNHS1eiFkUt7ZIJX3txd29nDxxXH4en8=
|
||||
k8s.io/client-go v0.17.4/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc=
|
||||
k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
|
||||
k8s.io/code-generator v0.17.4/go.mod h1:l8BLVwASXQZTo2xamW5mQNFCe1XPiAesVq7Y1t7PiQQ=
|
||||
k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc=
|
||||
k8s.io/component-base v0.17.4/go.mod h1:5BRqHMbbQPm2kKu35v3G+CpVq4K0RJKC7TRioF0I9lE=
|
||||
k8s.io/api v0.18.4 h1:8x49nBRxuXGUlDlwlWd3RMY1SayZrzFfxea3UZSkFw4=
|
||||
k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4=
|
||||
k8s.io/apiextensions-apiserver v0.18.4 h1:Y3HGERmS8t9u12YNUFoOISqefaoGRuTc43AYCLzWmWE=
|
||||
k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
|
||||
k8s.io/apimachinery v0.18.4 h1:ST2beySjhqwJoIFk6p7Hp5v5O0hYY6Gngq/gUYXTPIA=
|
||||
k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
|
||||
k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
|
||||
k8s.io/cli-runtime v0.18.4 h1:IUx7quIOb4gbQ4M+B1ksF/PTBovQuL5tXWzplX3t+FM=
|
||||
k8s.io/cli-runtime v0.18.4/go.mod h1:9/hS/Cuf7NVzWR5F/5tyS6xsnclxoPLVtwhnkJG1Y4g=
|
||||
k8s.io/client-go v0.18.4 h1:un55V1Q/B3JO3A76eS0kUSywgGK/WR3BQ8fHQjNa6Zc=
|
||||
k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g=
|
||||
k8s.io/cloud-provider v0.18.4/go.mod h1:JdI6cuSFPSPANEciv0v5qfwztkeyFCVc1S3krLYrw0E=
|
||||
k8s.io/cluster-bootstrap v0.18.4/go.mod h1:hNG705ec9SMN2BGlJ81R2CnyJjNKfROtAxvI9JXZdiM=
|
||||
k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk=
|
||||
k8s.io/cri-api v0.18.4/go.mod h1:OJtpjDvfsKoLGhvcc0qfygved0S0dGX56IJzPbqTG1s=
|
||||
k8s.io/csi-translation-lib v0.18.4/go.mod h1:FTci2m8/3oN8E+8OyblBXei8w4mwbiH4boNPeob4piE=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/heapster v1.2.0-beta.1/go.mod h1:h1uhptVXMwC8xtZBYsPXKVi8fpdlYkTs6k949KozGrM=
|
||||
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 v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
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/kubernetes v1.14.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20191218082557-f07c713de883 h1:TA8t8OLS8m3/0dtTckekO0pCQ7qMnD19fsZTQEgCSKQ=
|
||||
k8s.io/utils v0.0.0-20191218082557-f07c713de883/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
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.18.4/go.mod h1:xOVy4wqhpivXCt07Diwdms2gonG+SONVx+1e7O+GfC0=
|
||||
k8s.io/kube-controller-manager v0.18.4/go.mod h1:GrY1S0F7zA0LQlt0ApOLt4iMpphKTk3mFrQl1+usrfs=
|
||||
k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/kube-proxy v0.18.4/go.mod h1:h2c+ckQC1XpybDs53mWhLCvvM6txduWVLPQwwvGqR9M=
|
||||
k8s.io/kube-scheduler v0.18.4/go.mod h1:vRFb/8Yi7hh670beaPrXttMpjt7H8EooDkgwFm8ts4k=
|
||||
k8s.io/kubectl v0.18.4/go.mod h1:EzB+nfeUWk6fm6giXQ8P4Fayw3dsN+M7Wjy23mTRtB0=
|
||||
k8s.io/kubelet v0.18.4/go.mod h1:D0V9JYaTJRF+ry+9JfnM4uyg3ySRLQ02XjfQ5f2u4CM=
|
||||
k8s.io/kubernetes v1.18.0/go.mod h1:z8xjOOO1Ljz+TaHpOxVGC7cxtF32TesIamoQ+BZrVS0=
|
||||
k8s.io/legacy-cloud-providers v0.18.4/go.mod h1:Mnxtra7DxVrODfGZHPsrkLi22lwmZOlWkjyyO3vW+WM=
|
||||
k8s.io/metrics v0.18.4/go.mod h1:luze4fyI9JG4eLDZy0kFdYEebqNfi0QrG4xNEbPkHOs=
|
||||
k8s.io/repo-infra v0.0.1-alpha.1/go.mod h1:wO1t9WaB99V80ljbeENTnayuEEwNZt7gECYh/CEyOJ8=
|
||||
k8s.io/sample-apiserver v0.18.4/go.mod h1:j5XH5FUmMd/ztoz+9ch0+hL+lsvWdgxnTV7l3P3Ijoo=
|
||||
k8s.io/system-validators v1.0.4/go.mod h1:HgSgTg4NAGNoYYjKsUyk52gdNi2PVDswQ9Iyn66R7NI=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
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=
|
||||
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||
mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
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/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
|
||||
sigs.k8s.io/controller-runtime v0.6.1 h1:LcK2+nk0kmaOnKGN+vBcWHqY5WDJNJNB/c5pW+sU8fc=
|
||||
sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
|
||||
|
||||
415
golangci.yaml
Normal file
415
golangci.yaml
Normal file
@@ -0,0 +1,415 @@
|
||||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
|
||||
# options for analysis running
|
||||
run:
|
||||
# default concurrency is a available CPU number
|
||||
concurrency: 4
|
||||
|
||||
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||
timeout: 5m
|
||||
|
||||
# exit code when at least one issue was found, default is 1
|
||||
issues-exit-code: 1
|
||||
|
||||
# include test files or not, default is true
|
||||
tests: true
|
||||
|
||||
# list of build tags, all linters use it. Default is empty list.
|
||||
#build-tags:
|
||||
# - mytag
|
||||
|
||||
# which dirs to skip: issues from them won't be reported;
|
||||
# can use regexp here: generated.*, regexp is applied on full path;
|
||||
# default value is empty list, but default dirs are skipped independently
|
||||
# from this option's value (see skip-dirs-use-default).
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
#skip-dirs:
|
||||
# - src/external_libs
|
||||
# - autogenerated_by_my_lib
|
||||
|
||||
# default is true. Enables skipping of directories:
|
||||
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
|
||||
skip-dirs-use-default: true
|
||||
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
# no need to include all autogenerated files, we confidently recognize
|
||||
# autogenerated files. If it's not please let us know.
|
||||
# "/" will be replaced by current OS file path separator to properly work
|
||||
# on Windows.
|
||||
# skip-files:
|
||||
# - ".*\\.my\\.go$"
|
||||
# - lib/bad.go
|
||||
|
||||
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
# modules-download-mode: readonly|release|vendor
|
||||
modules-download-mode: readonly
|
||||
|
||||
# Allow multiple parallel golangci-lint instances running.
|
||||
# If false (default) - golangci-lint acquires file lock on start.
|
||||
allow-parallel-runners: false
|
||||
|
||||
|
||||
# output configuration options
|
||||
output:
|
||||
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||
format: colored-line-number
|
||||
|
||||
# print lines of code with issue, default is true
|
||||
print-issued-lines: true
|
||||
|
||||
# print linter name in the end of issue text, default is true
|
||||
print-linter-name: true
|
||||
|
||||
# make issues output unique by line, default is true
|
||||
uniq-by-line: true
|
||||
|
||||
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
dogsled:
|
||||
# checks assignments with too many blank identifiers; default is 2
|
||||
max-blank-identifiers: 2
|
||||
dupl:
|
||||
# tokens count to trigger issue, 150 by default
|
||||
threshold: 100
|
||||
errcheck:
|
||||
# report about not checking of errors in type assertions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
# [deprecated] comma-separated list of pairs of the form pkg:regex
|
||||
# the regex is used to ignore names within pkg. (default "fmt:.*").
|
||||
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
|
||||
# ignore: fmt:.*,io/ioutil:^Read.*
|
||||
|
||||
# path to a file containing a list of functions to exclude from checking
|
||||
# see https://github.com/kisielk/errcheck#excluding-functions for details
|
||||
# exclude: /path/to/file.txt
|
||||
exhaustive:
|
||||
# indicates that switch statements are to be considered exhaustive if a
|
||||
# 'default' case is present, even if all enum members aren't listed in the
|
||||
# switch
|
||||
default-signifies-exhaustive: false
|
||||
funlen:
|
||||
lines: 60
|
||||
statements: 40
|
||||
gocognit:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
nestif:
|
||||
# minimal complexity of if statements to report, 5 by default
|
||||
min-complexity: 4
|
||||
goconst:
|
||||
# minimal length of string constant, 3 by default
|
||||
min-len: 3
|
||||
# minimal occurrences count to trigger, 3 by default
|
||||
min-occurrences: 3
|
||||
gocritic:
|
||||
# Which checks should be enabled; can't be combined with 'disabled-checks';
|
||||
# See https://go-critic.github.io/overview#checks-overview
|
||||
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
|
||||
# By default list of stable checks is used.
|
||||
# enabled-checks:
|
||||
# - rangeValCopy
|
||||
|
||||
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
|
||||
# disabled-checks:
|
||||
# - regexpMust
|
||||
|
||||
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
|
||||
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
|
||||
# enabled-tags:
|
||||
# - performance
|
||||
# disabled-tags:
|
||||
# - experimental
|
||||
|
||||
settings: # settings passed to gocritic
|
||||
captLocal: # must be valid enabled check name
|
||||
paramsOnly: true
|
||||
# rangeValCopy:
|
||||
# sizeThreshold: 32
|
||||
gocyclo:
|
||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||
min-complexity: 10
|
||||
godot:
|
||||
# check all top-level comments, not only declarations
|
||||
check-all: false
|
||||
godox:
|
||||
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
|
||||
# might be left in the code accidentally and should be resolved before merging
|
||||
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
|
||||
- NOTE
|
||||
- OPTIMIZE # marks code that should be optimized before merging
|
||||
- HACK # marks hack-arounds that should be removed before merging
|
||||
gofmt:
|
||||
# simplify code: gofmt with `-s` option, true by default
|
||||
simplify: true
|
||||
goimports:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# it's a comma-separated list of prefixes
|
||||
local-prefixes: github.com/org/project
|
||||
golint:
|
||||
# minimal confidence for issues, default is 0.8
|
||||
min-confidence: 0.8
|
||||
gomnd:
|
||||
settings:
|
||||
mnd:
|
||||
# the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
|
||||
checks: argument,case,condition,operation,return,assign
|
||||
gomodguard:
|
||||
allowed:
|
||||
modules: # List of allowed modules
|
||||
# - gopkg.in/yaml.v2
|
||||
domains: # List of allowed module domains
|
||||
# - golang.org
|
||||
blocked:
|
||||
modules: # List of blocked modules
|
||||
# - github.com/uudashr/go-module: # Blocked module
|
||||
# recommendations: # Recommended modules that should be used instead (Optional)
|
||||
# - golang.org/x/mod
|
||||
# reason: "`mod` is the official go.mod parser library." # Reason why the recommended module should be used (Optional)
|
||||
versions: # List of blocked module version constraints
|
||||
# - github.com/mitchellh/go-homedir: # Blocked module with version constraint
|
||||
# version: "< 1.1.0" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
|
||||
# reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional)
|
||||
govet:
|
||||
# report about shadowed variables
|
||||
check-shadowing: true
|
||||
|
||||
# settings per analyzer
|
||||
settings:
|
||||
printf: # analyzer name, run `go tool vet help` to see all analyzers
|
||||
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
|
||||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
|
||||
|
||||
# enable or disable analyzers by name
|
||||
enable:
|
||||
- atomicalign
|
||||
enable-all: false
|
||||
disable:
|
||||
- shadow
|
||||
disable-all: false
|
||||
depguard:
|
||||
list-type: blacklist
|
||||
include-go-root: false
|
||||
packages:
|
||||
- github.com/sirupsen/logrus
|
||||
packages-with-error-message:
|
||||
# specify an error message to output when a blacklisted package is used
|
||||
- github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
|
||||
lll:
|
||||
# max line length, lines longer will be reported. Default is 120.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
|
||||
line-length: 120
|
||||
# tab width in spaces. Default to 1.
|
||||
tab-width: 1
|
||||
maligned:
|
||||
# print struct with more effective memory layout or not, false by default
|
||||
suggest-new: true
|
||||
misspell:
|
||||
# Correct spellings using locale preferences for US or UK.
|
||||
# Default is to use a neutral variety of English.
|
||||
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
|
||||
locale: US
|
||||
ignore-words:
|
||||
- someword
|
||||
nakedret:
|
||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||
max-func-lines: 30
|
||||
prealloc:
|
||||
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||
# For most programs usage of prealloc will be a premature optimization.
|
||||
|
||||
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
|
||||
# True by default.
|
||||
simple: true
|
||||
range-loops: true # Report preallocation suggestions on range loops, true by default
|
||||
for-loops: false # Report preallocation suggestions on for loops, false by default
|
||||
nolintlint:
|
||||
# Enable to ensure that nolint directives are all used. Default is true.
|
||||
allow-unused: false
|
||||
# Disable to ensure that nolint directives don't have a leading space. Default is true.
|
||||
allow-leading-space: true
|
||||
# Exclude following linters from requiring an explanation. Default is [].
|
||||
allow-no-explanation: []
|
||||
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
|
||||
require-explanation: true
|
||||
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
|
||||
require-specific: true
|
||||
rowserrcheck:
|
||||
packages:
|
||||
- github.com/jmoiron/sqlx
|
||||
testpackage:
|
||||
# regexp pattern to skip files
|
||||
skip-regexp: (export|internal)_test\.go
|
||||
unparam:
|
||||
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
|
||||
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
unused:
|
||||
# treat code as a program (not a library) and report unused exported identifiers; default is false.
|
||||
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
|
||||
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
|
||||
# with golangci-lint call it on a directory with the changed file.
|
||||
check-exported: false
|
||||
whitespace:
|
||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||
wsl:
|
||||
# If true append is only allowed to be cuddled if appending value is
|
||||
# matching variables, fields or types on line above. Default is true.
|
||||
strict-append: true
|
||||
# Allow calls and assignments to be cuddled as long as the lines have any
|
||||
# matching variables, fields or types. Default is true.
|
||||
allow-assign-and-call: true
|
||||
# Allow multiline assignments to be cuddled. Default is true.
|
||||
allow-multiline-assign: true
|
||||
# Allow declarations (var) to be cuddled.
|
||||
allow-cuddle-declarations: false
|
||||
# Allow trailing comments in ending of blocks
|
||||
allow-trailing-comment: false
|
||||
# Force newlines in end of case at this limit (0 = never).
|
||||
force-case-trailing-whitespace: 0
|
||||
# Force cuddling of err checks with err var assignment
|
||||
force-err-cuddling: false
|
||||
# Allow leading comments to be separated with empty liens
|
||||
allow-separated-leading-comment: false
|
||||
|
||||
# The custom section can be used to define linter plugins to be loaded at runtime. See README doc
|
||||
# for more info.
|
||||
# custom:
|
||||
# Each custom linter should have a unique name.
|
||||
# example:
|
||||
# The path to the plugin *.so. Can be absolute or local. Required for each custom linter
|
||||
# path: /path/to/example.so
|
||||
# The description of the linter. Optional, just for documentation purposes.
|
||||
# description: This is an example usage of a plugin linter.
|
||||
# Intended to point to the repo location of the linter. Optional, just for documentation purposes.
|
||||
# original-url: github.com/golangci/example-linter
|
||||
|
||||
linters:
|
||||
# enable:
|
||||
# - megacheck
|
||||
# - govet
|
||||
# disable:
|
||||
# - maligned
|
||||
# - prealloc
|
||||
disable-all: true
|
||||
presets:
|
||||
# - bugs
|
||||
# - unused
|
||||
fast: false
|
||||
|
||||
|
||||
#issues:
|
||||
# # List of regexps of issue texts to exclude, empty list by default.
|
||||
# # But independently from this option we use default exclude patterns,
|
||||
# # it can be disabled by `exclude-use-default: false`. To list all
|
||||
# # excluded by default patterns execute `golangci-lint run --help`
|
||||
# exclude:
|
||||
# - abcdef
|
||||
#
|
||||
# # Excluding configuration per-path, per-linter, per-text and per-source
|
||||
# exclude-rules:
|
||||
# # Exclude some linters from running on tests files.
|
||||
# - path: _test\.go
|
||||
# linters:
|
||||
# - gocyclo
|
||||
# - errcheck
|
||||
# - dupl
|
||||
# - gosec
|
||||
#
|
||||
# # Exclude known linters from partially hard-vendored code,
|
||||
# # which is impossible to exclude via "nolint" comments.
|
||||
# - path: internal/hmac/
|
||||
# text: "weak cryptographic primitive"
|
||||
# linters:
|
||||
# - gosec
|
||||
#
|
||||
# # Exclude some staticcheck messages
|
||||
# - linters:
|
||||
# - staticcheck
|
||||
# text: "SA9003:"
|
||||
#
|
||||
# # Exclude lll issues for long lines with go:generate
|
||||
# - linters:
|
||||
# - lll
|
||||
# source: "^//go:generate "
|
||||
|
||||
# Independently from option `exclude` we use default exclude patterns,
|
||||
# it can be disabled by this option. To list all
|
||||
# excluded by default patterns execute `golangci-lint run --help`.
|
||||
# Default value for this option is true.
|
||||
exclude-use-default: false
|
||||
|
||||
# The default value is false. If set to true exclude and exclude-rules
|
||||
# regular expressions become case sensitive.
|
||||
exclude-case-sensitive: false
|
||||
|
||||
# The list of ids of default excludes to include or disable. By default it's empty.
|
||||
include:
|
||||
- EXC0002 # disable excluding of issues about comments from golint
|
||||
|
||||
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
|
||||
max-issues-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
|
||||
max-same-issues: 0
|
||||
|
||||
# Show only new issues: if there are unstaged changes or untracked files,
|
||||
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
|
||||
# It's a super-useful option for integration of golangci-lint into existing
|
||||
# large codebase. It's not practical to fix all existing issues at the moment
|
||||
# of integration: much better don't allow issues in new code.
|
||||
# Default is false.
|
||||
new: false
|
||||
|
||||
# Show only new issues created after git revision `REV`
|
||||
new-from-rev: REV
|
||||
|
||||
# Show only new issues created in git patch with set file path.
|
||||
new-from-patch: path/to/patch/file
|
||||
|
||||
severity:
|
||||
# Default value is empty string.
|
||||
# Set the default severity for issues. If severity rules are defined and the issues
|
||||
# do not match or no severity is provided to the rule this will be the default
|
||||
# severity applied. Severities should match the supported severity names of the
|
||||
# selected out format.
|
||||
# - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
|
||||
# - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity
|
||||
# - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
||||
default-severity: error
|
||||
|
||||
# The default value is false.
|
||||
# If set to true severity-rules regular expressions become case sensitive.
|
||||
case-sensitive: false
|
||||
|
||||
# Default value is empty list.
|
||||
# When a list of severity rules are provided, severity information will be added to lint
|
||||
# issues. Severity rules have the same filtering capability as exclude rules except you
|
||||
# are allowed to specify one matcher per severity rule.
|
||||
# Only affects out formats that support setting severity information.
|
||||
rules:
|
||||
- linters:
|
||||
- dupl
|
||||
severity: info
|
||||
22
hack/brew-update.sh
Executable file
22
hack/brew-update.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script assumes that 2 environment variables are defined outside of it:
|
||||
# VELERO_VERSION - a full version version string, starting with v. example: v1.4.2
|
||||
# HOMEBREW_GITHUB_API_TOKEN - the GitHub API token that the brew command will use to create a PR on the user's behalf.
|
||||
|
||||
|
||||
# Check if brew is found on the user's $PATH; exit if not.
|
||||
if [ -z $(which brew) ];
|
||||
then
|
||||
echo "Homebrew must first be installed to use this script!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# GitHub URL which contains the source code archive for the tagged release
|
||||
URL=https://github.com/vmware-tanzu/velero/archive/$VELERO_VERSION.tar.gz
|
||||
|
||||
# Update brew so we're sure we have the latest Velero formula
|
||||
brew update
|
||||
|
||||
# Invoke brew's helper function, which will run all their tests and end up opening a browser with the resulting PR.
|
||||
brew bump-formula-pr velero --url=$URL
|
||||
@@ -22,10 +22,17 @@ ENV GOPROXY=https://proxy.golang.org
|
||||
RUN mkdir -p /go/src/k8s.io
|
||||
WORKDIR /go/src/k8s.io
|
||||
RUN git config --global advice.detachedHead false
|
||||
RUN git clone -b kubernetes-1.17.0 https://github.com/kubernetes/code-generator
|
||||
RUN git clone -b v0.18.4 https://github.com/kubernetes/code-generator
|
||||
|
||||
RUN wget --quiet https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.1/kubebuilder_2.3.1_linux_amd64.tar.gz && \
|
||||
tar -zxvf kubebuilder_2.3.1_linux_amd64.tar.gz && \
|
||||
mv kubebuilder_2.3.1_linux_amd64 /usr/local/kubebuilder && \
|
||||
chmod +x /usr/local/kubebuilder && \
|
||||
export PATH=$PATH:/usr/local/kubebuilder/bin && \
|
||||
rm kubebuilder_2.3.1_linux_amd64.tar.gz
|
||||
|
||||
# get controller-tools
|
||||
RUN go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.4
|
||||
RUN go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.3.0
|
||||
|
||||
# get goimports (the revision is pinned so we don't indiscriminately update, but the particular commit
|
||||
# is not important)
|
||||
@@ -45,3 +52,6 @@ RUN wget --quiet https://github.com/goreleaser/goreleaser/releases/download/v0.1
|
||||
tar xvf goreleaser_Linux_x86_64.tar.gz && \
|
||||
mv goreleaser /usr/bin/goreleaser && \
|
||||
chmod +x /usr/bin/goreleaser
|
||||
|
||||
# get golangci-lint
|
||||
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.27.0
|
||||
@@ -39,10 +39,13 @@ if [ -z "${VERSION}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${GIT_SHA}" ]; then
|
||||
echo "GIT_SHA must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export CGO_ENABLED=0
|
||||
|
||||
GIT_SHA=$(git rev-parse HEAD)
|
||||
GIT_DIRTY=$(git status --porcelain 2> /dev/null)
|
||||
if [[ -z "${GIT_DIRTY}" ]]; then
|
||||
GIT_TREE_STATE=clean
|
||||
else
|
||||
|
||||
43
hack/changelog-check.sh
Executable file
43
hack/changelog-check.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2020 the Velero contributors.
|
||||
#
|
||||
# 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-push is invoked by the CI/CD system to deploy docker images to Docker Hub.
|
||||
# It will build images for all commits to master and all git tags.
|
||||
# The highest, non-prerelease semantic version will also be given the `latest` tag.
|
||||
|
||||
set +x
|
||||
|
||||
if [[ -z "$CI" ]]; then
|
||||
echo "This script is intended to be run only on Github Actions." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CHANGELOG_PATH='changelogs/unreleased'
|
||||
|
||||
# https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request
|
||||
# GITHUB_REF is something like "refs/pull/:prNumber/merge"
|
||||
pr_number=$(echo $GITHUB_REF | cut -d / -f 3)
|
||||
|
||||
change_log_file="${CHANGELOG_PATH}/${pr_number}-*"
|
||||
|
||||
if ls ${change_log_file} 1> /dev/null 2>&1; then
|
||||
echo "changelog for PR ${pr_number} exists"
|
||||
exit 0
|
||||
else
|
||||
echo "PR ${pr_number} is missing a changelog. Please refer https://velero.io/docs/master/code-standards/#adding-a-changelog and add a changelog."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This code embeds the CRD manifests in pkg/generated/crds/manifests in
|
||||
// pkg/generated/crds/crds.go.
|
||||
// This code embeds the CRD manifests in config/crd/bases in
|
||||
// config/crd/crds/crds.go.
|
||||
|
||||
package main
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// This is relative to pkg/generated/crds
|
||||
// This is relative to config/crd/crds
|
||||
const goHeaderFile = "../../../hack/boilerplate.go.txt"
|
||||
|
||||
const tpl = `{{.GoHeader}}
|
||||
@@ -96,14 +96,14 @@ func main() {
|
||||
GoHeader: string(headerBytes),
|
||||
}
|
||||
|
||||
// This is relative to pkg/generated/crds
|
||||
manifests, err := ioutil.ReadDir("manifests")
|
||||
// This is relative to config/crd/crds
|
||||
manifests, err := ioutil.ReadDir("../bases")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
for _, crd := range manifests {
|
||||
file, err := os.Open("manifests/" + crd.Name())
|
||||
file, err := os.Open("../bases/" + crd.Name())
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func main() {
|
||||
data.RawCRDs = append(data.RawCRDs, fmt.Sprintf("%q", buf.Bytes()))
|
||||
}
|
||||
|
||||
t, err := template.New("crds").Parse(tpl)
|
||||
t, err := template.New("crd").Parse(tpl)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
set +x
|
||||
|
||||
if [[ -z "$TRAVIS" ]]; then
|
||||
echo "This script is intended to be run only on Travis." >&2
|
||||
if [[ -z "$CI" ]]; then
|
||||
echo "This script is intended to be run only on Github Actions." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -47,37 +47,43 @@ function highest_release() {
|
||||
done
|
||||
}
|
||||
|
||||
triggeredBy=$(echo $GITHUB_REF | cut -d / -f 2)
|
||||
if [[ "$triggeredBy" == "heads" ]]; then
|
||||
BRANCH=$(echo $GITHUB_REF | cut -d / -f 3)
|
||||
TAG=
|
||||
elif [[ "$triggeredBy" == "tags" ]]; then
|
||||
BRANCH=
|
||||
TAG=$(echo $GITHUB_REF | cut -d / -f 3)
|
||||
fi
|
||||
|
||||
if [[ "$BRANCH" == "master" ]]; then
|
||||
VERSION="$BRANCH"
|
||||
elif [[ ! -z "$TRAVIS_TAG" ]]; then
|
||||
# Tags aren't fetched by Travis on checkout, and we don't need them for master
|
||||
elif [[ ! -z "$TAG" ]]; then
|
||||
# Explicitly checkout tags when building from a git tag.
|
||||
# This is not needed when building from master
|
||||
git fetch --tags
|
||||
# Calculate the latest release if there's a tag.
|
||||
highest_release
|
||||
VERSION="$TRAVIS_TAG"
|
||||
VERSION="$TAG"
|
||||
else
|
||||
# If we're not on master and we're not building a tag, exit early.
|
||||
echo "We're not on master and we're not building a tag, exit early."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
# Assume we're not tagging `latest` by default, and never on master.
|
||||
TAG_LATEST=false
|
||||
if [[ "$BRANCH" == "master" ]]; then
|
||||
echo "Building master, not tagging latest."
|
||||
elif [[ "$TRAVIS_TAG" == "$HIGHEST" ]]; then
|
||||
elif [[ "$TAG" == "$HIGHEST" ]]; then
|
||||
TAG_LATEST=true
|
||||
fi
|
||||
|
||||
# Debugging info
|
||||
echo "Highest tag found: $HIGHEST"
|
||||
echo "BRANCH: $BRANCH"
|
||||
echo "TRAVIS_TAG: $TRAVIS_TAG"
|
||||
echo "TAG: $TAG"
|
||||
echo "TAG_LATEST: $TAG_LATEST"
|
||||
|
||||
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
|
||||
unset GIT_HTTP_USER_AGENT
|
||||
|
||||
echo "Building and pushing container images."
|
||||
|
||||
VERSION="$VERSION" TAG_LATEST="$TAG_LATEST" make all-containers all-push all-manifests
|
||||
|
||||
36
hack/lint.sh
Executable file
36
hack/lint.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2020 the Velero contributors.
|
||||
#
|
||||
# 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.
|
||||
|
||||
LINTERS=${1:-"gosec,goconst,gofmt,goimports,unparam"}
|
||||
ALL=${2:-false}
|
||||
|
||||
HACK_DIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
# Printing out cache status
|
||||
golangci-lint cache status
|
||||
|
||||
if [[ $ALL == true ]] ; then
|
||||
action=""
|
||||
else
|
||||
action="-n"
|
||||
fi
|
||||
|
||||
# Enable GL_DEBUG line below for debug messages for golangci-lint
|
||||
# export GL_DEBUG=loader,gocritic,env
|
||||
CMD="golangci-lint run -E ${LINTERS} $action -c $HACK_DIR/../golangci.yaml"
|
||||
echo "Running $CMD"
|
||||
|
||||
eval $CMD
|
||||
75
hack/release-tools/chk_version.go
Normal file
75
hack/release-tools/chk_version.go
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
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 (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// This regex should match both our GA format (example: v1.4.3) and pre-release format (v1.2.4-beta.2)
|
||||
// The following sub-capture groups are defined:
|
||||
// major
|
||||
// minor
|
||||
// patch
|
||||
// prerelease (this will be alpha/beta followed by a ".", followed by 1 or more digits (alpha.5)
|
||||
var release_regex *regexp.Regexp = regexp.MustCompile("^v(?P<major>[[:digit:]]+)\\.(?P<minor>[[:digit:]]+)\\.(?P<patch>[[:digit:]]+)(-{1}(?P<prerelease>(alpha|beta)\\.[[:digit:]]+))*")
|
||||
|
||||
// This small program exists because checking the VELERO_VERSION rules in bash is difficult, and difficult to test for correctness.
|
||||
// Calling it with --verify will verify whether or not the VELERO_VERSION environment variable is a valid version string, without parsing for its components.
|
||||
// Calling it without --verify will try to parse the version into its component pieces.
|
||||
func main() {
|
||||
|
||||
velero_version := os.Getenv("VELERO_VERSION")
|
||||
|
||||
submatches := reSubMatchMap(release_regex, velero_version)
|
||||
|
||||
// Didn't match the regex, exit.
|
||||
if len(submatches) == 0 {
|
||||
fmt.Printf("VELERO_VERSION of %s was not valid. Please correct the value and retry.", velero_version)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if len(os.Args) > 1 && os.Args[1] == "--verify" {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Send these in a bash variable format to stdout, so that they can be consumed by bash scripts that call the go program.
|
||||
fmt.Printf("VELERO_MAJOR=%s\n", submatches["major"])
|
||||
fmt.Printf("VELERO_MINOR=%s\n", submatches["minor"])
|
||||
fmt.Printf("VELERO_PATCH=%s\n", submatches["patch"])
|
||||
fmt.Printf("VELERO_PRERELEASE=%s\n", submatches["prerelease"])
|
||||
}
|
||||
|
||||
// reSubMatchMap returns a map with the named submatches within a regular expression populated as keys, and their matched values within a given string as values.
|
||||
// If no matches are found, a nil map is returned
|
||||
func reSubMatchMap(r *regexp.Regexp, s string) map[string]string {
|
||||
match := r.FindStringSubmatch(s)
|
||||
submatches := make(map[string]string)
|
||||
if len(match) == 0 {
|
||||
return submatches
|
||||
}
|
||||
for i, name := range r.SubexpNames() {
|
||||
// 0 will always be empty from the return values of SubexpNames's documentation, so skip it.
|
||||
if i != 0 {
|
||||
submatches[name] = match[i]
|
||||
}
|
||||
}
|
||||
|
||||
return submatches
|
||||
}
|
||||
71
hack/release-tools/chk_version_test.go
Normal file
71
hack/release-tools/chk_version_test.go
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
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 (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegexMatching(t *testing.T) {
|
||||
tests := []struct {
|
||||
version string
|
||||
expectMatch bool
|
||||
}{
|
||||
{
|
||||
version: "v1.4.0",
|
||||
expectMatch: true,
|
||||
},
|
||||
{
|
||||
version: "v2.0.0",
|
||||
expectMatch: true,
|
||||
},
|
||||
{
|
||||
version: "v1.5.0-alpha.1",
|
||||
expectMatch: true,
|
||||
},
|
||||
{
|
||||
version: "v1.16.1320-beta.14",
|
||||
expectMatch: true,
|
||||
},
|
||||
{
|
||||
version: "1.0.0",
|
||||
expectMatch: false,
|
||||
},
|
||||
{
|
||||
// this is true because while the "--" is invalid, v1.0.0 is a valid part of the regex
|
||||
version: "v1.0.0--beta.1",
|
||||
expectMatch: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
name := fmt.Sprintf("Testing version string %s", test.version)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
results := reSubMatchMap(release_regex, test.version)
|
||||
|
||||
if len(results) == 0 && test.expectMatch {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
if len(results) > 0 && !test.expectMatch {
|
||||
fmt.Printf("%v", results)
|
||||
t.Fail()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
118
hack/release-tools/tag-release.sh
Executable file
118
hack/release-tools/tag-release.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2020 the Velero contributors.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
# This script will do the necessary checks and actions to create a release of Velero.
|
||||
# It will first validate that all prerequisites are met, then verify the version string is what the user expects.
|
||||
# A git tag will be created and pushed to GitHub, and GoReleaser will be invoked.
|
||||
|
||||
# This script is meant to be a combination of documentation and executable.
|
||||
# If you have questions at any point, please stop and ask!
|
||||
|
||||
# Directory in which the script itself resides, so we can use it for calling programs that are in the same directory.
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
function tag_and_push() {
|
||||
echo "Tagging and pushing $VELERO_VERSION"
|
||||
git tag $VELERO_VERSION
|
||||
git push $VELERO_VERSION
|
||||
}
|
||||
|
||||
# For now, have the person doing the release pass in the VELERO_VERSION variable as an environment variable.
|
||||
# In the future, we might be able to inspect git via `git describe --abbrev=0` to get a hint for it.
|
||||
if [[ -z "$VELERO_VERSION" ]]; then
|
||||
printf "The \$VELERO_VERSION environment variable is not set. Please set it with\n\texport VELERO_VERSION=v<version.to.release>\nthen try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make sure the user's provided their github token, so we can give it to goreleaser.
|
||||
if [[ -z "$GITHUB_TOKEN" ]]; then
|
||||
printf "The GITHUB_TOKEN environment variable is not set. Please set it with\n\t export GITHUB_TOKEN=<your github token>\n then try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Ensure that we have a clean working tree before we let any changes happen, especially important for cutting release branches.
|
||||
if [[ -n $(git status --short) ]]; then
|
||||
echo "Your git working directory is dirty! Please clean up untracked files and stash any changes before proceeding."
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Make sure that there's no issue with the environment variable's format before trying to eval the parsed version.
|
||||
if ! go run $DIR/chk_version.go --verify; then
|
||||
exit 2
|
||||
fi
|
||||
# Since we're past the validation of the VELERO_VERSION, parse the version's individual components.
|
||||
eval $(go run $DIR/chk_version.go)
|
||||
|
||||
|
||||
printf "To clarify, you've provided a version string of $VELERO_VERSION.\n"
|
||||
printf "Based on this, the following assumptions have been made: \n"
|
||||
|
||||
[[ "$VELERO_PATCH" != 0 ]] && printf "*\t This is a patch release.\n"
|
||||
|
||||
# -n is "string is non-empty"
|
||||
[[ -n $VELERO_PRERELEASE ]] && printf "*\t This is a pre-release.\n"
|
||||
|
||||
# -z is "string is empty"
|
||||
[[ -z $VELERO_PRERELEASE ]] && printf "*\t This is a GA release.\n"
|
||||
|
||||
echo "If this is all correct, press enter/return to proceed to TAG THE RELEASE and UPLOAD THE TAG TO GITHUB."
|
||||
echo "Otherwise, press ctrl-c to CANCEL the process without making any changes."
|
||||
|
||||
read -p "Ready to continue? "
|
||||
|
||||
echo "Alright, let's go."
|
||||
|
||||
echo "Pulling down all git tags and branches before doing any work."
|
||||
git fetch upstream --all --tags
|
||||
|
||||
# If we've got a patch release, we'll need to create a release branch for it.
|
||||
if [[ "$VELERO_PATCH" > 0 ]]; then
|
||||
release_branch_name=release-$VELERO_MAJOR.$VELERO_MINOR
|
||||
|
||||
# Check if the branch exists, creating it if not.
|
||||
# The fetch command above should have gotten all the upstream branches, so we can safely assume this check is local & upstream branches.
|
||||
if [[ -z $(git branch | grep $release_branch_name) ]]; then
|
||||
git checkout -b $release_branch_name
|
||||
echo "Release branch made."
|
||||
else
|
||||
echo "Release branch $release_branch_name exists already."
|
||||
git checkout $release_branch_name
|
||||
fi
|
||||
|
||||
echo "Now you'll need to cherry-pick any relevant git commits into this release branch."
|
||||
echo "Either pause this script with ctrl-z, or open a new terminal window and do the cherry-picking."
|
||||
read -p "Press enter when you're done cherry-picking. THIS WILL MAKE A TAG PUSH THE BRANCH TO UPSTREAM"
|
||||
|
||||
# TODO can/should we add a way to review the cherry-picked commits before the push?
|
||||
|
||||
echo "Pushing $release_branch_name to upstream remote"
|
||||
git push --set-upstream upstream/$release_branch_name $release_branch_name
|
||||
|
||||
tag_and_push
|
||||
else
|
||||
echo "Checking out upstream/master."
|
||||
git checkout upstream/master
|
||||
|
||||
tag_and_push
|
||||
fi
|
||||
|
||||
|
||||
|
||||
echo "Invoking Goreleaser to create the GitHub release."
|
||||
RELEASE_NOTES_FILE=changelogs/CHANGELOG-$VELERO_MAJOR.$VELERO_MINOR.md \
|
||||
PUBLISH=TRUE \
|
||||
make release
|
||||
@@ -44,9 +44,12 @@ ${GOPATH}/src/k8s.io/code-generator/generate-groups.sh \
|
||||
--output-base ../../.. \
|
||||
$@
|
||||
|
||||
# Generate manifests e.g. CRD, RBAC etc.
|
||||
controller-gen \
|
||||
crd:crdVersions=v1beta1,preserveUnknownFields=false \
|
||||
output:dir=./pkg/generated/crds/manifests \
|
||||
paths=./pkg/apis/velero/v1/...
|
||||
crd:crdVersions=v1beta1,preserveUnknownFields=false,trivialVersions=true \
|
||||
rbac:roleName=manager-role \
|
||||
paths=./pkg/apis/velero/v1/... \
|
||||
paths=./pkg/controller/... \
|
||||
output:crd:artifacts:config=config/crd/bases
|
||||
|
||||
go generate ./pkg/generated/crds
|
||||
go generate ./config/crd/crds
|
||||
|
||||
@@ -19,11 +19,11 @@ HACK_DIR=$(dirname "${BASH_SOURCE}")
|
||||
${HACK_DIR}/update-generated-crd-code.sh --verify-only
|
||||
|
||||
# ensure no changes to generated CRDs
|
||||
if ! git diff --exit-code pkg/generated/crds/crds.go >/dev/null; then
|
||||
if ! git diff --exit-code config/crd/crds/crds.go >/dev/null; then
|
||||
# revert changes to state before running CRD generation to stay consistent
|
||||
# with code-generator `--verify-only` option which discards generated changes
|
||||
git checkout pkg/generated/crds
|
||||
git checkout config/crd/bases
|
||||
|
||||
echo "CRD verification - failed! Generated CRDs are out-of-date, please run 'make update'."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
54
internal/util/managercontroller/managercontroller.go
Normal file
54
internal/util/managercontroller/managercontroller.go
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// TODO(2.0) After converting all controllers to runttime-controller,
|
||||
// the functions in this file will no longer be needed and should be removed.
|
||||
package managercontroller
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/controller"
|
||||
)
|
||||
|
||||
// Runnable will turn a "regular" runnable component (such as a controller)
|
||||
// into a controller-runtime Runnable
|
||||
func Runnable(p controller.Interface, numWorkers int) manager.Runnable {
|
||||
f := func(stop <-chan struct{}) error {
|
||||
|
||||
// Create a cancel context for handling the stop signal.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// If a signal is received on the stop channel, cancel the
|
||||
// context. This will propagate the cancel into the p.Run
|
||||
// function below.
|
||||
go func() {
|
||||
select {
|
||||
case <-stop:
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
// This is a blocking call that either completes
|
||||
// or is cancellable on receiving a stop signal.
|
||||
return p.Run(ctx, numWorkers)
|
||||
}
|
||||
return manager.RunnableFunc(f)
|
||||
}
|
||||
132
internal/velero/storagelocation.go
Normal file
132
internal/velero/storagelocation.go
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
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 velero
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/persistence"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||
)
|
||||
|
||||
// StorageLocation holds information for connecting with storage
|
||||
// for a backup storage location.
|
||||
type StorageLocation struct {
|
||||
Client client.Client
|
||||
Ctx context.Context
|
||||
|
||||
DefaultStorageLocation string
|
||||
DefaultStoreValidationFrequency time.Duration
|
||||
|
||||
// use variables to refer to these functions so they can be
|
||||
// replaced with fakes for testing.
|
||||
NewPluginManager func(logrus.FieldLogger) clientmgmt.Manager
|
||||
NewBackupStore func(*velerov1api.BackupStorageLocation, persistence.ObjectStoreGetter, logrus.FieldLogger) (persistence.BackupStore, error)
|
||||
}
|
||||
|
||||
// IsReadyToValidate calculates if a given backup storage location is ready to be validated.
|
||||
//
|
||||
// Rules:
|
||||
// Users can choose a validation frequency per location. This will overrite the server's default value
|
||||
// To skip/stop validation, set the frequency to zero
|
||||
// This will always return "true" for the first attempt at validating a location, regardless of its validation frequency setting
|
||||
// Otherwise, it returns "ready" only when NOW is equal to or after the next validation time
|
||||
// (next validation time: last validation time + validation frequency)
|
||||
func (p *StorageLocation) IsReadyToValidate(location *velerov1api.BackupStorageLocation, log logrus.FieldLogger) bool {
|
||||
validationFrequency := p.DefaultStoreValidationFrequency
|
||||
// If the bsl validation frequency is not specifically set, skip this block and continue, using the server's default
|
||||
if location.Spec.ValidationFrequency != nil {
|
||||
validationFrequency = location.Spec.ValidationFrequency.Duration
|
||||
}
|
||||
|
||||
if validationFrequency == 0 {
|
||||
log.Debug("Validation period for this backup location is set to 0, skipping validation")
|
||||
return false
|
||||
}
|
||||
|
||||
if validationFrequency < 0 {
|
||||
log.Debugf("Validation period must be non-negative, changing from %d to %d", validationFrequency, p.DefaultStoreValidationFrequency)
|
||||
validationFrequency = p.DefaultStoreValidationFrequency
|
||||
}
|
||||
|
||||
lastValidation := location.Status.LastValidationTime
|
||||
if lastValidation != nil { // always ready to validate the first time around, so only even do this check if this has happened before
|
||||
nextValidation := lastValidation.Add(validationFrequency) // next validation time: last validation time + validation frequency
|
||||
if time.Now().UTC().Before(nextValidation) { // ready only when NOW is equal to or after the next validation time
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IsValidFor verifies if a storage is valid for a given backup storage location.
|
||||
func (p *StorageLocation) IsValid(location *velerov1api.BackupStorageLocation, log logrus.FieldLogger) error {
|
||||
pluginManager := p.NewPluginManager(log)
|
||||
defer pluginManager.CleanupClients()
|
||||
|
||||
backupStore, err := p.NewBackupStore(location, pluginManager, log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := backupStore.IsValid(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PatchStatus patches the status.phase field as well as the status.lastValidationTime to the current time
|
||||
func (p *StorageLocation) PatchStatus(location *velerov1api.BackupStorageLocation, phase velerov1api.BackupStorageLocationPhase) error {
|
||||
statusPatch := client.MergeFrom(location.DeepCopyObject())
|
||||
location.Status.Phase = phase
|
||||
location.Status.LastValidationTime = &metav1.Time{Time: time.Now().UTC()}
|
||||
if err := p.Client.Status().Patch(p.Ctx, location, statusPatch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListBackupStorageLocations verifies if there are any backup storage locations.
|
||||
// For all purposes, if either there is an error while attempting to fetch items or
|
||||
// if there are no items an error would be returned since the functioning of the system
|
||||
// would be haulted.
|
||||
func ListBackupStorageLocations(kbClient client.Client, ctx context.Context, namespace string) (velerov1api.BackupStorageLocationList, error) {
|
||||
var locations velerov1api.BackupStorageLocationList
|
||||
if err := kbClient.List(ctx, &locations, &client.ListOptions{
|
||||
Namespace: namespace,
|
||||
}); err != nil {
|
||||
return velerov1api.BackupStorageLocationList{}, err
|
||||
}
|
||||
|
||||
if len(locations.Items) == 0 {
|
||||
return velerov1api.BackupStorageLocationList{}, errors.New("no backup storage locations found")
|
||||
}
|
||||
|
||||
return locations, nil
|
||||
}
|
||||
261
internal/velero/storagelocation_test.go
Normal file
261
internal/velero/storagelocation_test.go
Normal file
@@ -0,0 +1,261 @@
|
||||
/*Copyright 2020 the Velero contributors.
|
||||
|
||||
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 velero
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sirupsen/logrus"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
|
||||
"github.com/vmware-tanzu/velero/pkg/persistence"
|
||||
persistencemocks "github.com/vmware-tanzu/velero/pkg/persistence/mocks"
|
||||
"github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt"
|
||||
pluginmocks "github.com/vmware-tanzu/velero/pkg/plugin/mocks"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
)
|
||||
|
||||
func TestIsReadyToValidate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
serverDefaultValidationFrequency time.Duration
|
||||
backupLocation *velerov1api.BackupStorageLocation
|
||||
ready bool
|
||||
}{
|
||||
{
|
||||
name: "don't validate, since frequency is set to zero",
|
||||
serverDefaultValidationFrequency: 0,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-2").ValidationFrequency(0).Result(),
|
||||
ready: false,
|
||||
},
|
||||
{
|
||||
name: "validate as per location setting, as that takes precedence, and always if it has never been validated before regardless of the frequency setting",
|
||||
serverDefaultValidationFrequency: 0,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").ValidationFrequency(1 * time.Hour).Result(),
|
||||
ready: true,
|
||||
},
|
||||
{
|
||||
name: "don't validate as per location setting, as it is set to zero and that takes precedence",
|
||||
serverDefaultValidationFrequency: 1,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").ValidationFrequency(0).Result(),
|
||||
ready: false,
|
||||
},
|
||||
{
|
||||
name: "validate as per default setting when location setting is not set",
|
||||
serverDefaultValidationFrequency: 1,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-2").Result(),
|
||||
ready: true,
|
||||
},
|
||||
{
|
||||
name: "don't validate when default setting is set to zero and the location setting is not set",
|
||||
serverDefaultValidationFrequency: 0,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-2").Result(),
|
||||
ready: false,
|
||||
},
|
||||
{
|
||||
name: "don't validate when now is before the NEXT validation time (validation frequency + last validation time)",
|
||||
serverDefaultValidationFrequency: 0,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").ValidationFrequency(1 * time.Second).LastValidationTime(time.Now()).Result(),
|
||||
ready: false,
|
||||
},
|
||||
{
|
||||
name: "validate when now is equal to the NEXT validation time (validation frequency + last validation time)",
|
||||
serverDefaultValidationFrequency: 0,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-2").ValidationFrequency(1 * time.Second).LastValidationTime(time.Now().Add(-1 * time.Second)).Result(),
|
||||
ready: true,
|
||||
},
|
||||
{
|
||||
name: "validate when now is after the NEXT validation time (validation frequency + last validation time)",
|
||||
serverDefaultValidationFrequency: 0,
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-2").ValidationFrequency(1 * time.Second).LastValidationTime(time.Now().Add(-2 * time.Second)).Result(),
|
||||
ready: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
storageLocationInfo := StorageLocation{
|
||||
DefaultStoreValidationFrequency: tt.serverDefaultValidationFrequency,
|
||||
}
|
||||
|
||||
g.Expect(storageLocationInfo.IsReadyToValidate(tt.backupLocation, velerotest.NewLogger())).To(BeIdenticalTo(tt.ready))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
backupLocation *velerov1api.BackupStorageLocation
|
||||
isValidError error
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "do not expect an error when store is valid",
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").Result(),
|
||||
isValidError: nil,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "expect an error when store is not valid",
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").Result(),
|
||||
isValidError: errors.New("an error"),
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
var (
|
||||
pluginManager = &pluginmocks.Manager{}
|
||||
backupStores = make(map[string]*persistencemocks.BackupStore)
|
||||
)
|
||||
pluginManager.On("CleanupClients").Return(nil)
|
||||
|
||||
location := tt.backupLocation
|
||||
backupStores[location.Name] = &persistencemocks.BackupStore{}
|
||||
backupStore := backupStores[location.Name]
|
||||
backupStore.On("IsValid").Return(tt.isValidError)
|
||||
|
||||
storageLocationInfo := StorageLocation{
|
||||
NewPluginManager: func(logrus.FieldLogger) clientmgmt.Manager { return pluginManager },
|
||||
NewBackupStore: func(loc *velerov1api.BackupStorageLocation, _ persistence.ObjectStoreGetter, _ logrus.FieldLogger) (persistence.BackupStore, error) {
|
||||
return backupStores[loc.Name], nil
|
||||
},
|
||||
}
|
||||
|
||||
actual := storageLocationInfo.IsValid(tt.backupLocation, velerotest.NewLogger())
|
||||
if tt.expectError {
|
||||
g.Expect(actual).NotTo(BeNil())
|
||||
} else {
|
||||
g.Expect(actual).To(BeNil())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatchStatus(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
backupLocation *velerov1api.BackupStorageLocation
|
||||
newPhase velerov1api.BackupStorageLocationPhase
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "an update to the same phase should succeed",
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").Phase(velerov1api.BackupStorageLocationPhaseAvailable).Result(),
|
||||
newPhase: velerov1api.BackupStorageLocationPhaseAvailable,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "an update to a different phase should succeed",
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").Phase(velerov1api.BackupStorageLocationPhaseAvailable).Result(),
|
||||
newPhase: velerov1api.BackupStorageLocationPhaseUnavailable,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "an update to a location that doesn't exist should fail (see actual test)",
|
||||
backupLocation: builder.ForBackupStorageLocation("ns-1", "location-1").Phase(velerov1api.BackupStorageLocationPhaseAvailable).Result(),
|
||||
newPhase: velerov1api.BackupStorageLocationPhaseUnavailable,
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
storageLocationInfo := StorageLocation{
|
||||
Client: fake.NewFakeClientWithScheme(scheme.Scheme, tt.backupLocation),
|
||||
}
|
||||
|
||||
if tt.expectError {
|
||||
backupLocation := builder.ForBackupStorageLocation("ns-1", "location-2").Phase(velerov1api.BackupStorageLocationPhaseAvailable).Result()
|
||||
// an update to a location that was never created will fail:
|
||||
g.Expect(storageLocationInfo.PatchStatus(backupLocation, tt.newPhase)).NotTo(BeNil())
|
||||
} else {
|
||||
g.Expect(storageLocationInfo.PatchStatus(tt.backupLocation, tt.newPhase)).To(BeNil())
|
||||
|
||||
key := client.ObjectKey{Name: tt.backupLocation.Name, Namespace: tt.backupLocation.Namespace}
|
||||
instance := &velerov1api.BackupStorageLocation{}
|
||||
err := storageLocationInfo.Client.Get(context.Background(), key, instance)
|
||||
g.Expect(err).To(BeNil())
|
||||
g.Expect(instance.Status.Phase).To(BeIdenticalTo(tt.newPhase))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListBackupStorageLocations(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
backupLocations *velerov1api.BackupStorageLocationList
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "1 existing location",
|
||||
backupLocations: &velerov1api.BackupStorageLocationList{
|
||||
Items: []velerov1api.BackupStorageLocation{
|
||||
*builder.ForBackupStorageLocation("ns-1", "location-1").Result(),
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "multiple existing location",
|
||||
backupLocations: &velerov1api.BackupStorageLocationList{
|
||||
Items: []velerov1api.BackupStorageLocation{
|
||||
*builder.ForBackupStorageLocation("ns-1", "location-1").Result(),
|
||||
*builder.ForBackupStorageLocation("ns-1", "location-2").Result(),
|
||||
*builder.ForBackupStorageLocation("ns-1", "location-3").Result(),
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "no existing locations",
|
||||
backupLocations: &velerov1api.BackupStorageLocationList{},
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
client := fake.NewFakeClientWithScheme(scheme.Scheme, tt.backupLocations)
|
||||
if tt.expectError {
|
||||
_, err := ListBackupStorageLocations(client, context.Background(), "ns-1")
|
||||
g.Expect(err).NotTo(BeNil())
|
||||
} else {
|
||||
_, err := ListBackupStorageLocations(client, context.Background(), "ns-1")
|
||||
g.Expect(err).To(BeNil())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017, 2019 the Velero contributors.
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -82,6 +82,12 @@ type BackupSpec struct {
|
||||
// VolumeSnapshotLocations is a list containing names of VolumeSnapshotLocations associated with this backup.
|
||||
// +optional
|
||||
VolumeSnapshotLocations []string `json:"volumeSnapshotLocations,omitempty"`
|
||||
|
||||
// DefaultVolumesToRestic specifies whether restic should be used to take a
|
||||
// backup of all pod volumes by default.
|
||||
// +optional
|
||||
// + nullable
|
||||
DefaultVolumesToRestic *bool `json:"defaultVolumesToRestic,omitempty"`
|
||||
}
|
||||
|
||||
// BackupHooks contains custom behaviors that should be executed at different phases of the backup.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
Copyright 2017, 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -21,33 +21,99 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// BackupStorageLocationSpec defines the desired state of a Velero BackupStorageLocation
|
||||
type BackupStorageLocationSpec struct {
|
||||
// Provider is the provider of the backup storage.
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// Config is for provider-specific configuration fields.
|
||||
// +optional
|
||||
Config map[string]string `json:"config,omitempty"`
|
||||
|
||||
StorageType `json:",inline"`
|
||||
|
||||
// AccessMode defines the permissions for the backup storage location.
|
||||
// +optional
|
||||
AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"`
|
||||
|
||||
// BackupSyncPeriod defines how frequently to sync backup API objects from object storage. A value of 0 disables sync.
|
||||
// +optional
|
||||
// +nullable
|
||||
BackupSyncPeriod *metav1.Duration `json:"backupSyncPeriod,omitempty"`
|
||||
|
||||
// ValidationFrequency defines how frequently to validate the corresponding object storage. A value of 0 disables validation.
|
||||
// +optional
|
||||
// +nullable
|
||||
ValidationFrequency *metav1.Duration `json:"validationFrequency,omitempty"`
|
||||
}
|
||||
|
||||
// BackupStorageLocationStatus defines the observed state of BackupStorageLocation
|
||||
type BackupStorageLocationStatus struct {
|
||||
// Phase is the current state of the BackupStorageLocation.
|
||||
// +optional
|
||||
Phase BackupStorageLocationPhase `json:"phase,omitempty"`
|
||||
|
||||
// LastSyncedTime is the last time the contents of the location were synced into
|
||||
// the cluster.
|
||||
// +optional
|
||||
// +nullable
|
||||
LastSyncedTime *metav1.Time `json:"lastSyncedTime,omitempty"`
|
||||
|
||||
// LastValidationTime is the last time the backup store location was validated
|
||||
// the cluster.
|
||||
// +optional
|
||||
// +nullable
|
||||
LastValidationTime *metav1.Time `json:"lastValidationTime,omitempty"`
|
||||
|
||||
// LastSyncedRevision is the value of the `metadata/revision` file in the backup
|
||||
// storage location the last time the BSL's contents were synced into the cluster.
|
||||
//
|
||||
// Deprecated: this field is no longer updated or used for detecting changes to
|
||||
// the location's contents and will be removed entirely in v2.0.
|
||||
// +optional
|
||||
LastSyncedRevision types.UID `json:"lastSyncedRevision,omitempty"`
|
||||
|
||||
// AccessMode is an unused field.
|
||||
//
|
||||
// Deprecated: there is now an AccessMode field on the Spec and this field
|
||||
// will be removed entirely as of v2.0.
|
||||
// +optional
|
||||
AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runttime-controller client,
|
||||
// the genclient and k8s:deepcopy markers will no longer be needed and should be removed.
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:object:generate=true
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Backup Storage Location status such as Available/Unavailable"
|
||||
// +kubebuilder:printcolumn:name="Last Validated",type="date",JSONPath=".status.lastValidationTime",description="LastValidationTime is the last time the backup store location was validated"
|
||||
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
|
||||
|
||||
// BackupStorageLocation is a location where Velero stores backup objects.
|
||||
// BackupStorageLocation is a location where Velero stores backup objects
|
||||
type BackupStorageLocation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec BackupStorageLocationSpec `json:"spec,omitempty"`
|
||||
|
||||
// +optional
|
||||
Spec BackupStorageLocationSpec `json:"spec,omitempty"`
|
||||
Status BackupStorageLocationStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// TODO(2.0) After converting all resources to use the runttime-controller client,
|
||||
// the k8s:deepcopy marker will no longer be needed and should be removed.
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=backupstoragelocations,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=backupstoragelocations/status,verbs=get;update;patch
|
||||
|
||||
// BackupStorageLocationList is a list of BackupStorageLocations.
|
||||
// BackupStorageLocationList contains a list of BackupStorageLocation
|
||||
type BackupStorageLocationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []BackupStorageLocation `json:"items"`
|
||||
Items []BackupStorageLocation `json:"items"`
|
||||
}
|
||||
|
||||
// StorageType represents the type of storage that a backup location uses.
|
||||
@@ -70,29 +136,9 @@ type ObjectStorageLocation struct {
|
||||
CACert []byte `json:"caCert,omitempty"`
|
||||
}
|
||||
|
||||
// BackupStorageLocationSpec defines the specification for a Velero BackupStorageLocation.
|
||||
type BackupStorageLocationSpec struct {
|
||||
// Provider is the provider of the backup storage.
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// Config is for provider-specific configuration fields.
|
||||
// +optional
|
||||
Config map[string]string `json:"config,omitempty"`
|
||||
|
||||
StorageType `json:",inline"`
|
||||
|
||||
// AccessMode defines the permissions for the backup storage location.
|
||||
// +optional
|
||||
AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"`
|
||||
|
||||
// BackupSyncPeriod defines how frequently to sync backup API objects from object storage. A value of 0 disables sync.
|
||||
// +optional
|
||||
// +nullable
|
||||
BackupSyncPeriod *metav1.Duration `json:"backupSyncPeriod,omitempty"`
|
||||
}
|
||||
|
||||
// BackupStorageLocationPhase is the lifecyle phase of a Velero BackupStorageLocation.
|
||||
// BackupStorageLocationPhase is the lifecycle phase of a Velero BackupStorageLocation.
|
||||
// +kubebuilder:validation:Enum=Available;Unavailable
|
||||
// +kubebuilder:default=Unavailable
|
||||
type BackupStorageLocationPhase string
|
||||
|
||||
const (
|
||||
@@ -117,31 +163,3 @@ const (
|
||||
|
||||
// TODO(2.0): remove the AccessMode field from BackupStorageLocationStatus.
|
||||
// TODO(2.0): remove the LastSyncedRevision field from BackupStorageLocationStatus.
|
||||
|
||||
// BackupStorageLocationStatus describes the current status of a Velero BackupStorageLocation.
|
||||
type BackupStorageLocationStatus struct {
|
||||
// Phase is the current state of the BackupStorageLocation.
|
||||
// +optional
|
||||
Phase BackupStorageLocationPhase `json:"phase,omitempty"`
|
||||
|
||||
// LastSyncedTime is the last time the contents of the location were synced into
|
||||
// the cluster.
|
||||
// +optional
|
||||
// +nullable
|
||||
LastSyncedTime *metav1.Time `json:"lastSyncedTime,omitempty"`
|
||||
|
||||
// LastSyncedRevision is the value of the `metadata/revision` file in the backup
|
||||
// storage location the last time the BSL's contents were synced into the cluster.
|
||||
//
|
||||
// Deprecated: this field is no longer updated or used for detecting changes to
|
||||
// the location's contents and will be removed entirely in v2.0.
|
||||
// +optional
|
||||
LastSyncedRevision types.UID `json:"lastSyncedRevision,omitempty"`
|
||||
|
||||
// AccessMode is an unused field.
|
||||
//
|
||||
// Deprecated: there is now an AccessMode field on the Spec and this field
|
||||
// will be removed entirely as of v2.0.
|
||||
// +optional
|
||||
AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"`
|
||||
}
|
||||
36
pkg/apis/velero/v1/groupversion_info.go
Normal file
36
pkg/apis/velero/v1/groupversion_info.go
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
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 velero v1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=velero.io
|
||||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
SchemeGroupVersion = schema.GroupVersion{Group: "velero.io", Version: "v1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
@@ -22,20 +22,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeBuilder collects the scheme builder functions for the Velero API
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
|
||||
// AddToScheme applies the SchemeBuilder functions to a specified scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// GroupName is the group name for the Velero API
|
||||
const GroupName = "velero.io"
|
||||
|
||||
// SchemeGroupVersion is the GroupVersion for the Velero API
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Resource gets a Velero GroupResource for a specified resource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
|
||||
@@ -16,7 +16,12 @@ limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ScheduleSpec defines the specification for a Velero schedule
|
||||
type ScheduleSpec struct {
|
||||
@@ -95,3 +100,8 @@ type ScheduleList struct {
|
||||
|
||||
Items []Schedule `json:"items"`
|
||||
}
|
||||
|
||||
// TimestampedName returns the default backup name format based on the schedule
|
||||
func (s *Schedule) TimestampedName(timestamp time.Time) string {
|
||||
return fmt.Sprintf("%s-%s", s.Name, timestamp.Format("20060102150405"))
|
||||
}
|
||||
|
||||
@@ -246,6 +246,11 @@ func (in *BackupSpec) DeepCopyInto(out *BackupSpec) {
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DefaultVolumesToRestic != nil {
|
||||
in, out := &in.DefaultVolumesToRestic, &out.DefaultVolumesToRestic
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -374,6 +379,11 @@ func (in *BackupStorageLocationSpec) DeepCopyInto(out *BackupStorageLocationSpec
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.ValidationFrequency != nil {
|
||||
in, out := &in.ValidationFrequency, &out.ValidationFrequency
|
||||
*out = new(metav1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -394,6 +404,10 @@ func (in *BackupStorageLocationStatus) DeepCopyInto(out *BackupStorageLocationSt
|
||||
in, out := &in.LastSyncedTime, &out.LastSyncedTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
if in.LastValidationTime != nil {
|
||||
in, out := &in.LastValidationTime, &out.LastValidationTime
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017, 2020 the Velero contributors.
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -71,6 +71,7 @@ type kubernetesBackupper struct {
|
||||
podCommandExecutor podexec.PodCommandExecutor
|
||||
resticBackupperFactory restic.BackupperFactory
|
||||
resticTimeout time.Duration
|
||||
defaultVolumesToRestic bool
|
||||
}
|
||||
|
||||
type resolvedAction struct {
|
||||
@@ -103,6 +104,7 @@ func NewKubernetesBackupper(
|
||||
podCommandExecutor podexec.PodCommandExecutor,
|
||||
resticBackupperFactory restic.BackupperFactory,
|
||||
resticTimeout time.Duration,
|
||||
defaultVolumesToRestic bool,
|
||||
) (Backupper, error) {
|
||||
return &kubernetesBackupper{
|
||||
backupClient: backupClient,
|
||||
@@ -111,6 +113,7 @@ func NewKubernetesBackupper(
|
||||
podCommandExecutor: podCommandExecutor,
|
||||
resticBackupperFactory: resticBackupperFactory,
|
||||
resticTimeout: resticTimeout,
|
||||
defaultVolumesToRestic: defaultVolumesToRestic,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -239,6 +242,7 @@ func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Req
|
||||
backupRequest.ResourceIncludesExcludes = getResourceIncludesExcludes(kb.discoveryHelper, backupRequest.Spec.IncludedResources, backupRequest.Spec.ExcludedResources)
|
||||
log.Infof("Including resources: %s", backupRequest.ResourceIncludesExcludes.IncludesString())
|
||||
log.Infof("Excluding resources: %s", backupRequest.ResourceIncludesExcludes.ExcludesString())
|
||||
log.Infof("Backing up all pod volumes using restic: %t", *backupRequest.Backup.Spec.DefaultVolumesToRestic)
|
||||
|
||||
var err error
|
||||
backupRequest.ResourceHooks, err = getResourceHooks(backupRequest.Spec.Hooks.Resources, kb.discoveryHelper)
|
||||
@@ -296,7 +300,7 @@ func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Req
|
||||
|
||||
backupRequest.Status.Progress = &velerov1api.BackupProgress{TotalItems: len(items)}
|
||||
patch := fmt.Sprintf(`{"status":{"progress":{"totalItems":%d}}}`, len(items))
|
||||
if _, err := kb.backupClient.Backups(backupRequest.Namespace).Patch(backupRequest.Name, types.MergePatchType, []byte(patch)); err != nil {
|
||||
if _, err := kb.backupClient.Backups(backupRequest.Namespace).Patch(context.TODO(), backupRequest.Name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}); err != nil {
|
||||
log.WithError(errors.WithStack((err))).Warn("Got error trying to update backup's status.progress.totalItems")
|
||||
}
|
||||
|
||||
@@ -350,7 +354,7 @@ func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Req
|
||||
backupRequest.Status.Progress.ItemsBackedUp = lastUpdate.itemsBackedUp
|
||||
|
||||
patch := fmt.Sprintf(`{"status":{"progress":{"totalItems":%d,"itemsBackedUp":%d}}}`, lastUpdate.totalItems, lastUpdate.itemsBackedUp)
|
||||
if _, err := kb.backupClient.Backups(backupRequest.Namespace).Patch(backupRequest.Name, types.MergePatchType, []byte(patch)); err != nil {
|
||||
if _, err := kb.backupClient.Backups(backupRequest.Namespace).Patch(context.TODO(), backupRequest.Name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}); err != nil {
|
||||
log.WithError(errors.WithStack((err))).Warn("Got error trying to update backup's status.progress")
|
||||
}
|
||||
lastUpdate = nil
|
||||
@@ -429,7 +433,7 @@ func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Req
|
||||
backupRequest.Status.Progress.ItemsBackedUp = len(backupRequest.BackedUpItems)
|
||||
|
||||
patch = fmt.Sprintf(`{"status":{"progress":{"totalItems":%d,"itemsBackedUp":%d}}}`, len(backupRequest.BackedUpItems), len(backupRequest.BackedUpItems))
|
||||
if _, err := kb.backupClient.Backups(backupRequest.Namespace).Patch(backupRequest.Name, types.MergePatchType, []byte(patch)); err != nil {
|
||||
if _, err := kb.backupClient.Backups(backupRequest.Namespace).Patch(context.TODO(), backupRequest.Name, types.MergePatchType, []byte(patch), metav1.PatchOptions{}); err != nil {
|
||||
log.WithError(errors.WithStack((err))).Warn("Got error trying to update backup's status.progress")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 the Velero contributors.
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -1723,7 +1723,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
||||
},
|
||||
|
||||
{
|
||||
name: "if there's an error backing up additional items, the item the action was run for isn't backed up",
|
||||
name: "if additional items aren't found in the API, they're skipped and the original item is still backed up",
|
||||
backup: defaultBackup().Result(),
|
||||
apiResources: []*test.APIResource{
|
||||
test.Pods(
|
||||
@@ -1746,8 +1746,10 @@ func TestBackupActionAdditionalItems(t *testing.T) {
|
||||
},
|
||||
},
|
||||
want: []string{
|
||||
"resources/pods/namespaces/ns-1/pod-1.json",
|
||||
"resources/pods/namespaces/ns-2/pod-2.json",
|
||||
"resources/pods/namespaces/ns-3/pod-3.json",
|
||||
"resources/pods/v1-preferredversion/namespaces/ns-1/pod-1.json",
|
||||
"resources/pods/v1-preferredversion/namespaces/ns-2/pod-2.json",
|
||||
"resources/pods/v1-preferredversion/namespaces/ns-3/pod-3.json",
|
||||
},
|
||||
@@ -2704,9 +2706,9 @@ func (h *harness) addItems(t *testing.T, resource *test.APIResource) {
|
||||
unstructuredObj := &unstructured.Unstructured{Object: obj}
|
||||
|
||||
if resource.Namespaced {
|
||||
_, err = h.DynamicClient.Resource(resource.GVR()).Namespace(item.GetNamespace()).Create(unstructuredObj, metav1.CreateOptions{})
|
||||
_, err = h.DynamicClient.Resource(resource.GVR()).Namespace(item.GetNamespace()).Create(context.TODO(), unstructuredObj, metav1.CreateOptions{})
|
||||
} else {
|
||||
_, err = h.DynamicClient.Resource(resource.GVR()).Create(unstructuredObj, metav1.CreateOptions{})
|
||||
_, err = h.DynamicClient.Resource(resource.GVR()).Create(context.TODO(), unstructuredObj, metav1.CreateOptions{})
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -2750,7 +2752,7 @@ func newSnapshotLocation(ns, name, provider string) *velerov1.VolumeSnapshotLoca
|
||||
}
|
||||
|
||||
func defaultBackup() *builder.BackupBuilder {
|
||||
return builder.ForBackup(velerov1.DefaultNamespace, "backup-1")
|
||||
return builder.ForBackup(velerov1.DefaultNamespace, "backup-1").DefaultVolumesToRestic(false)
|
||||
}
|
||||
|
||||
func toUnstructuredOrFail(t *testing.T, obj interface{}) map[string]interface{} {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Velero contributors.
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
@@ -140,7 +141,7 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
|
||||
// Get the list of volumes to back up using restic from the pod's annotations. Remove from this list
|
||||
// any volumes that use a PVC that we've already backed up (this would be in a read-write-many scenario,
|
||||
// where it's been backed up from another pod), since we don't need >1 backup per PVC.
|
||||
for _, volume := range restic.GetVolumesToBackup(pod) {
|
||||
for _, volume := range restic.GetPodVolumesUsingRestic(pod, boolptr.IsSetToTrue(ib.backupRequest.Spec.DefaultVolumesToRestic)) {
|
||||
if found, pvcName := ib.resticSnapshotTracker.HasPVCForPodVolume(pod, volume); found {
|
||||
log.WithFields(map[string]interface{}{
|
||||
"podVolume": volume,
|
||||
@@ -159,6 +160,12 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
|
||||
}
|
||||
}
|
||||
|
||||
// capture the version of the object before invoking plugin actions as the plugin may update
|
||||
// the group version of the object.
|
||||
// group version of this object
|
||||
// Used on filepath to backup up all groups and versions
|
||||
version := resourceVersion(obj)
|
||||
|
||||
updatedObj, err := ib.executeActions(log, obj, groupResource, name, namespace, metadata)
|
||||
if err != nil {
|
||||
backupErrs = append(backupErrs, err)
|
||||
@@ -203,10 +210,6 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
|
||||
return false, kubeerrs.NewAggregate(backupErrs)
|
||||
}
|
||||
|
||||
// group version of this object
|
||||
// Used on filepath to backup up all groups and versions
|
||||
version := resourceVersion(obj)
|
||||
|
||||
// Getting the preferred group version of this resource
|
||||
preferredVersion := preferredGVR.Version
|
||||
|
||||
@@ -249,6 +252,7 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
|
||||
|
||||
// backing up the preferred version backup without API Group version on path - this is for backward compability
|
||||
|
||||
log.Debugf("Resource %s/%s, version= %s, preferredVersion=%s", groupResource.String(), name, version, preferredVersion)
|
||||
if version == preferredVersion {
|
||||
if namespace != "" {
|
||||
filePath = filepath.Join(velerov1api.ResourcesDir, groupResource.String(), velerov1api.NamespaceScopedDir, namespace, name+".json")
|
||||
@@ -271,7 +275,6 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
|
||||
if _, err := ib.tarWriter.Write(itemBytes); err != nil {
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true, nil
|
||||
@@ -339,12 +342,20 @@ func (ib *itemBackupper) executeActions(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
additionalItem, err := client.Get(additionalItem.Name, metav1.GetOptions{})
|
||||
item, err := client.Get(additionalItem.Name, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"groupResource": additionalItem.GroupResource,
|
||||
"namespace": additionalItem.Namespace,
|
||||
"name": additionalItem.Name,
|
||||
}).Warnf("Additional item was not found in Kubernetes API, can't back it up")
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if _, err = ib.backupItem(log, additionalItem, gvr.GroupResource(), gvr); err != nil {
|
||||
if _, err = ib.backupItem(log, item, gvr.GroupResource(), gvr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,10 +83,10 @@ func (h *defaultItemHookHandler) handleHooks(
|
||||
name := metadata.GetName()
|
||||
|
||||
// If the pod has the hook specified via annotations, that takes priority.
|
||||
hookFromAnnotations := getPodExecHookFromAnnotations(metadata.GetAnnotations(), phase)
|
||||
hookFromAnnotations := getPodExecHookFromAnnotations(metadata.GetAnnotations(), phase, log)
|
||||
if phase == hookPhasePre && hookFromAnnotations == nil {
|
||||
// See if the pod has the legacy hook annotation keys (i.e. without a phase specified)
|
||||
hookFromAnnotations = getPodExecHookFromAnnotations(metadata.GetAnnotations(), "")
|
||||
hookFromAnnotations = getPodExecHookFromAnnotations(metadata.GetAnnotations(), "", log)
|
||||
}
|
||||
if hookFromAnnotations != nil {
|
||||
hookLog := log.WithFields(
|
||||
@@ -164,7 +164,8 @@ func getHookAnnotation(annotations map[string]string, key string, phase hookPhas
|
||||
|
||||
// getPodExecHookFromAnnotations returns an ExecHook based on the annotations, as long as the
|
||||
// 'command' annotation is present. If it is absent, this returns nil.
|
||||
func getPodExecHookFromAnnotations(annotations map[string]string, phase hookPhase) *api.ExecHook {
|
||||
// If there is an error in parsing a supplied timeout, it is logged.
|
||||
func getPodExecHookFromAnnotations(annotations map[string]string, phase hookPhase, log logrus.FieldLogger) *api.ExecHook {
|
||||
commandValue := getHookAnnotation(annotations, podBackupHookCommandAnnotationKey, phase)
|
||||
if commandValue == "" {
|
||||
return nil
|
||||
@@ -192,7 +193,7 @@ func getPodExecHookFromAnnotations(annotations map[string]string, phase hookPhas
|
||||
if temp, err := time.ParseDuration(timeoutString); err == nil {
|
||||
timeout = temp
|
||||
} else {
|
||||
// TODO: log error that we couldn't parse duration
|
||||
log.Warn(errors.Wrapf(err, "Unable to parse provided timeout %s, using default", timeoutString))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -575,7 +575,7 @@ func TestGetPodExecHookFromAnnotations(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid timeout is ignored",
|
||||
name: "invalid timeout is logged",
|
||||
annotations: map[string]string{
|
||||
phasedKey(phase, podBackupHookCommandAnnotationKey): "/usr/bin/foo",
|
||||
phasedKey(phase, podBackupHookTimeoutAnnotationKey): "invalid",
|
||||
@@ -599,7 +599,8 @@ func TestGetPodExecHookFromAnnotations(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%s (phase=%q)", test.name, phase), func(t *testing.T) {
|
||||
hook := getPodExecHookFromAnnotations(test.annotations, phase)
|
||||
l := velerotest.NewLogger()
|
||||
hook := getPodExecHookFromAnnotations(test.annotations, phase, l)
|
||||
assert.Equal(t, test.expectedHook, hook)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
rbacbeta "k8s.io/api/rbac/v1beta1"
|
||||
@@ -45,7 +47,7 @@ type v1ClusterRoleBindingLister struct {
|
||||
}
|
||||
|
||||
func (v1 v1ClusterRoleBindingLister) List() ([]ClusterRoleBinding, error) {
|
||||
crbList, err := v1.client.List(metav1.ListOptions{})
|
||||
crbList, err := v1.client.List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
@@ -62,7 +64,7 @@ type v1beta1ClusterRoleBindingLister struct {
|
||||
}
|
||||
|
||||
func (v1beta1 v1beta1ClusterRoleBindingLister) List() ([]ClusterRoleBinding, error) {
|
||||
crbList, err := v1beta1.client.List(metav1.ListOptions{})
|
||||
crbList, err := v1beta1.client.List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -101,7 +102,7 @@ func (a *RemapCRDVersionAction) Execute(item runtime.Unstructured, backup *v1.Ba
|
||||
}
|
||||
|
||||
func fetchV1beta1CRD(name string, betaCRDClient apiextv1beta1client.CustomResourceDefinitionInterface) (*unstructured.Unstructured, error) {
|
||||
betaCRD, err := betaCRDClient.Get(name, metav1.GetOptions{})
|
||||
betaCRD, err := betaCRDClient.Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error fetching v1beta1 version of %s", name)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -45,7 +46,7 @@ func TestRemapCRDVersionAction(t *testing.T) {
|
||||
// keep the same one for all 3 tests, since there's little value in recreating it
|
||||
b := builder.ForCustomResourceDefinition("test.velero.io")
|
||||
c := b.Result()
|
||||
_, err := betaClient.Create(c)
|
||||
_, err := betaClient.Create(context.TODO(), c, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
a := NewRemapCRDVersionAction(velerotest.NewLogger(), betaClient)
|
||||
@@ -162,7 +163,7 @@ func TestRemapCRDVersionActionData(t *testing.T) {
|
||||
err = json.Unmarshal([]byte(f), &crd)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = betaClient.Create(&crd)
|
||||
_, err = betaClient.Create(context.TODO(), &crd, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Run method under test
|
||||
@@ -170,6 +171,7 @@ func TestRemapCRDVersionActionData(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "apiextensions.k8s.io/v1beta1", item.UnstructuredContent()["apiVersion"])
|
||||
assert.Equal(t, crd.Kind, item.GetObjectKind().GroupVersionKind().GroupKind().Kind)
|
||||
name, _, err := unstructured.NestedString(item.UnstructuredContent(), "metadata", "name")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, crd.Name, name)
|
||||
@@ -185,7 +187,7 @@ func TestRemapCRDVersionActionData(t *testing.T) {
|
||||
}
|
||||
|
||||
// Clean up the item created in the test.
|
||||
betaClient.Delete(crd.Name, &metav1.DeleteOptions{})
|
||||
betaClient.Delete(context.TODO(), crd.Name, metav1.DeleteOptions{})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 the Velero contributors.
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -128,6 +128,12 @@ func (b *BackupBuilder) SnapshotVolumes(val bool) *BackupBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
// DefaultVolumesToRestic sets the Backup's "DefaultVolumesToRestic" flag.
|
||||
func (b *BackupBuilder) DefaultVolumesToRestic(val bool) *BackupBuilder {
|
||||
b.object.Spec.DefaultVolumesToRestic = &val
|
||||
return b
|
||||
}
|
||||
|
||||
// Phase sets the Backup's phase.
|
||||
func (b *BackupBuilder) Phase(phase velerov1api.BackupPhase) *BackupBuilder {
|
||||
b.object.Status.Phase = phase
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package builder
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
@@ -86,3 +88,21 @@ func (b *BackupStorageLocationBuilder) AccessMode(accessMode velerov1api.BackupS
|
||||
b.object.Spec.AccessMode = accessMode
|
||||
return b
|
||||
}
|
||||
|
||||
// ValidationFrequency sets the BackupStorageLocation's validation frequency.
|
||||
func (b *BackupStorageLocationBuilder) ValidationFrequency(frequency time.Duration) *BackupStorageLocationBuilder {
|
||||
b.object.Spec.ValidationFrequency = &metav1.Duration{Duration: frequency}
|
||||
return b
|
||||
}
|
||||
|
||||
// LastValidationTime sets the BackupStorageLocation's last validated time.
|
||||
func (b *BackupStorageLocationBuilder) LastValidationTime(lastValidated time.Time) *BackupStorageLocationBuilder {
|
||||
b.object.Status.LastValidationTime = &metav1.Time{Time: lastValidated}
|
||||
return b
|
||||
}
|
||||
|
||||
// Phase sets the BackupStorageLocation's status phase.
|
||||
func (b *BackupStorageLocationBuilder) Phase(phase velerov1api.BackupStorageLocationPhase) *BackupStorageLocationBuilder {
|
||||
b.object.Status.Phase = phase
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -97,21 +99,21 @@ type dynamicResourceClient struct {
|
||||
var _ Dynamic = &dynamicResourceClient{}
|
||||
|
||||
func (d *dynamicResourceClient) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
return d.resourceClient.Create(obj, metav1.CreateOptions{})
|
||||
return d.resourceClient.Create(context.TODO(), obj, metav1.CreateOptions{})
|
||||
}
|
||||
|
||||
func (d *dynamicResourceClient) List(options metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||
return d.resourceClient.List(options)
|
||||
return d.resourceClient.List(context.TODO(), options)
|
||||
}
|
||||
|
||||
func (d *dynamicResourceClient) Watch(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return d.resourceClient.Watch(options)
|
||||
return d.resourceClient.Watch(context.TODO(), options)
|
||||
}
|
||||
|
||||
func (d *dynamicResourceClient) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
||||
return d.resourceClient.Get(name, opts)
|
||||
return d.resourceClient.Get(context.TODO(), name, opts)
|
||||
}
|
||||
|
||||
func (d *dynamicResourceClient) Patch(name string, data []byte) (*unstructured.Unstructured, error) {
|
||||
return d.resourceClient.Patch(name, types.MergePatchType, data, metav1.PatchOptions{})
|
||||
return d.resourceClient.Patch(context.TODO(), name, types.MergePatchType, data, metav1.PatchOptions{})
|
||||
}
|
||||
|
||||
@@ -19,13 +19,16 @@ package client
|
||||
import (
|
||||
"os"
|
||||
|
||||
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
@@ -42,6 +45,9 @@ type Factory interface {
|
||||
// DynamicClient returns a Kubernetes dynamic client. It uses the following priority to specify the cluster
|
||||
// configuration: --kubeconfig flag, KUBECONFIG environment variable, in-cluster configuration.
|
||||
DynamicClient() (dynamic.Interface, error)
|
||||
// KubebuilderClient returns a Kubernetes dynamic client. It uses the following priority to specify the cluster
|
||||
// configuration: --kubeconfig flag, KUBECONFIG environment variable, in-cluster configuration.
|
||||
KubebuilderClient() (kbclient.Client, error)
|
||||
// SetBasename changes the basename for an already-constructed client.
|
||||
// This is useful for generating clients that require a different user-agent string below the root `velero`
|
||||
// command, such as the server subcommand.
|
||||
@@ -81,7 +87,7 @@ func NewFactory(baseName string, config VeleroConfig) Factory {
|
||||
// We didn't get the namespace via env var or config file, so use the default.
|
||||
// Command line flags will override when BindFlags is called.
|
||||
if f.namespace == "" {
|
||||
f.namespace = v1.DefaultNamespace
|
||||
f.namespace = velerov1api.DefaultNamespace
|
||||
}
|
||||
|
||||
f.flags.StringVar(&f.kubeconfig, "kubeconfig", "", "Path to the kubeconfig file to use to talk to the Kubernetes apiserver. If unset, try the environment variable KUBECONFIG, as well as in-cluster configuration")
|
||||
@@ -137,6 +143,21 @@ func (f *factory) DynamicClient() (dynamic.Interface, error) {
|
||||
return dynamicClient, nil
|
||||
}
|
||||
|
||||
func (f *factory) KubebuilderClient() (kbclient.Client, error) {
|
||||
clientConfig, err := f.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
velerov1api.AddToScheme(scheme)
|
||||
kubebuilderClient, err := kbclient.New(clientConfig, kbclient.Options{
|
||||
Scheme: scheme,
|
||||
})
|
||||
|
||||
return kubebuilderClient, nil
|
||||
}
|
||||
|
||||
func (f *factory) SetBasename(name string) {
|
||||
f.baseName = name
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Velero contributors.
|
||||
Copyright 2020 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,9 +17,12 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -43,7 +46,7 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
Use: use + " NAME",
|
||||
Short: "Create a backup",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
cmd.CheckError(o.Complete(args, f))
|
||||
cmd.CheckError(o.Validate(c, args, f))
|
||||
@@ -58,9 +61,12 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
|
||||
# create a backup excluding the velero and default namespaces
|
||||
velero backup create backup2 --exclude-namespaces velero,default
|
||||
|
||||
# create a backup based on a schedule named daily-backup
|
||||
velero backup create --from-schedule daily-backup
|
||||
|
||||
# view the YAML for a backup that doesn't snapshot volumes, without sending it to the server
|
||||
velero backup create backup3 --snapshot-volumes=false -o yaml
|
||||
|
||||
|
||||
# wait for a backup to complete before returning from the command
|
||||
velero backup create backup4 --wait`,
|
||||
}
|
||||
@@ -78,6 +84,7 @@ type CreateOptions struct {
|
||||
Name string
|
||||
TTL time.Duration
|
||||
SnapshotVolumes flag.OptionalBool
|
||||
DefaultVolumesToRestic flag.OptionalBool
|
||||
IncludeNamespaces flag.StringArray
|
||||
ExcludeNamespaces flag.StringArray
|
||||
IncludeResources flag.StringArray
|
||||
@@ -120,6 +127,9 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) {
|
||||
|
||||
f = flags.VarPF(&o.IncludeClusterResources, "include-cluster-resources", "", "include cluster-scoped resources in the backup")
|
||||
f.NoOptDefVal = "true"
|
||||
|
||||
f = flags.VarPF(&o.DefaultVolumesToRestic, "default-volumes-to-restic", "", "use restic by default to backup all pod volumes")
|
||||
f.NoOptDefVal = "true"
|
||||
}
|
||||
|
||||
// BindWait binds the wait flag separately so it is not called by other create
|
||||
@@ -131,7 +141,7 @@ func (o *CreateOptions) BindWait(flags *pflag.FlagSet) {
|
||||
// BindFromSchedule binds the from-schedule flag separately so it is not called
|
||||
// by other create commands that reuse CreateOptions's BindFlags method.
|
||||
func (o *CreateOptions) BindFromSchedule(flags *pflag.FlagSet) {
|
||||
flags.StringVar(&o.FromSchedule, "from-schedule", "", "create a backup from the template of an existing schedule. Cannot be used with any other filters.")
|
||||
flags.StringVar(&o.FromSchedule, "from-schedule", "", "create a backup from the template of an existing schedule. Cannot be used with any other filters. Backup name is optional if used.")
|
||||
}
|
||||
|
||||
func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Factory) error {
|
||||
@@ -139,14 +149,28 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := f.KubebuilderClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure that unless FromSchedule is set, args contains a backup name
|
||||
if o.FromSchedule == "" && len(args) != 1 {
|
||||
return fmt.Errorf("a backup name is required, unless you are creating based on a schedule")
|
||||
}
|
||||
|
||||
if o.StorageLocation != "" {
|
||||
if _, err := o.client.VeleroV1().BackupStorageLocations(f.Namespace()).Get(o.StorageLocation, metav1.GetOptions{}); err != nil {
|
||||
location := &velerov1api.BackupStorageLocation{}
|
||||
if err := client.Get(context.Background(), kbclient.ObjectKey{
|
||||
Namespace: f.Namespace(),
|
||||
Name: o.StorageLocation,
|
||||
}, location); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, loc := range o.SnapshotLocations {
|
||||
if _, err := o.client.VeleroV1().VolumeSnapshotLocations(f.Namespace()).Get(loc, metav1.GetOptions{}); err != nil {
|
||||
if _, err := o.client.VeleroV1().VolumeSnapshotLocations(f.Namespace()).Get(context.TODO(), loc, metav1.GetOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -155,7 +179,10 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
|
||||
}
|
||||
|
||||
func (o *CreateOptions) Complete(args []string, f client.Factory) error {
|
||||
o.Name = args[0]
|
||||
// If an explict name is specified, use that name
|
||||
if len(args) > 0 {
|
||||
o.Name = args[0]
|
||||
}
|
||||
client, err := f.Client()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -218,7 +245,7 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
|
||||
go backupInformer.Run(stop)
|
||||
}
|
||||
|
||||
_, err = o.client.VeleroV1().Backups(backup.Namespace).Create(backup)
|
||||
_, err = o.client.VeleroV1().Backups(backup.Namespace).Create(context.TODO(), backup, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -255,16 +282,20 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
|
||||
}
|
||||
|
||||
func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, error) {
|
||||
backupBuilder := builder.ForBackup(namespace, o.Name)
|
||||
var backupBuilder *builder.BackupBuilder
|
||||
|
||||
if o.FromSchedule != "" {
|
||||
schedule, err := o.client.VeleroV1().Schedules(namespace).Get(o.FromSchedule, metav1.GetOptions{})
|
||||
schedule, err := o.client.VeleroV1().Schedules(namespace).Get(context.TODO(), o.FromSchedule, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
backupBuilder.FromSchedule(schedule)
|
||||
if o.Name == "" {
|
||||
o.Name = schedule.TimestampedName(time.Now())
|
||||
}
|
||||
backupBuilder = builder.ForBackup(namespace, o.Name).
|
||||
FromSchedule(schedule)
|
||||
} else {
|
||||
backupBuilder.
|
||||
backupBuilder = builder.ForBackup(namespace, o.Name).
|
||||
IncludedNamespaces(o.IncludeNamespaces...).
|
||||
ExcludedNamespaces(o.ExcludeNamespaces...).
|
||||
IncludedResources(o.IncludeResources...).
|
||||
@@ -280,6 +311,9 @@ func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, erro
|
||||
if o.IncludeClusterResources.Value != nil {
|
||||
backupBuilder.IncludeClusterResources(*o.IncludeClusterResources.Value)
|
||||
}
|
||||
if o.DefaultVolumesToRestic.Value != nil {
|
||||
backupBuilder.DefaultVolumesToRestic(*o.DefaultVolumesToRestic.Value)
|
||||
}
|
||||
}
|
||||
|
||||
backup := backupBuilder.ObjectMeta(builder.WithLabelsMap(o.Labels.Data())).Result()
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -60,7 +61,7 @@ func TestCreateOptions_BuildBackupFromSchedule(t *testing.T) {
|
||||
|
||||
expectedBackupSpec := builder.ForBackup("test", testNamespace).IncludedNamespaces("test").Result().Spec
|
||||
schedule := builder.ForSchedule(testNamespace, "test").Template(expectedBackupSpec).ObjectMeta(builder.WithLabels("velero.io/test", "true")).Result()
|
||||
o.client.VeleroV1().Schedules(testNamespace).Create(schedule)
|
||||
o.client.VeleroV1().Schedules(testNamespace).Create(context.TODO(), schedule, metav1.CreateOptions{})
|
||||
|
||||
t.Run("existing schedule", func(t *testing.T) {
|
||||
backup, err := o.BuildBackup(testNamespace)
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -82,7 +83,7 @@ func Run(o *cli.DeleteOptions) error {
|
||||
switch {
|
||||
case len(o.Names) > 0:
|
||||
for _, name := range o.Names {
|
||||
backup, err := o.Client.VeleroV1().Backups(o.Namespace).Get(name, metav1.GetOptions{})
|
||||
backup, err := o.Client.VeleroV1().Backups(o.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
errs = append(errs, errors.WithStack(err))
|
||||
continue
|
||||
@@ -96,7 +97,7 @@ func Run(o *cli.DeleteOptions) error {
|
||||
selector = o.Selector.String()
|
||||
}
|
||||
|
||||
res, err := o.Client.VeleroV1().Backups(o.Namespace).List(metav1.ListOptions{LabelSelector: selector})
|
||||
res, err := o.Client.VeleroV1().Backups(o.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector})
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
@@ -114,7 +115,7 @@ func Run(o *cli.DeleteOptions) error {
|
||||
for _, b := range backups {
|
||||
deleteRequest := backup.NewDeleteBackupRequest(b.Name, string(b.UID))
|
||||
|
||||
if _, err := o.Client.VeleroV1().DeleteBackupRequests(o.Namespace).Create(deleteRequest); err != nil {
|
||||
if _, err := o.Client.VeleroV1().DeleteBackupRequests(o.Namespace).Create(context.TODO(), deleteRequest, metav1.CreateOptions{}); err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
@@ -59,25 +60,25 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
|
||||
if len(args) > 0 {
|
||||
backups = new(velerov1api.BackupList)
|
||||
for _, name := range args {
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(name, metav1.GetOptions{})
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
cmd.CheckError(err)
|
||||
backups.Items = append(backups.Items, *backup)
|
||||
}
|
||||
} else {
|
||||
backups, err = veleroClient.VeleroV1().Backups(f.Namespace()).List(listOptions)
|
||||
backups, err = veleroClient.VeleroV1().Backups(f.Namespace()).List(context.TODO(), listOptions)
|
||||
cmd.CheckError(err)
|
||||
}
|
||||
|
||||
first := true
|
||||
for _, backup := range backups.Items {
|
||||
deleteRequestListOptions := pkgbackup.NewDeleteBackupRequestListOptions(backup.Name, string(backup.UID))
|
||||
deleteRequestList, err := veleroClient.VeleroV1().DeleteBackupRequests(f.Namespace()).List(deleteRequestListOptions)
|
||||
deleteRequestList, err := veleroClient.VeleroV1().DeleteBackupRequests(f.Namespace()).List(context.TODO(), deleteRequestListOptions)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error getting DeleteBackupRequests for backup %s: %v\n", backup.Name, err)
|
||||
}
|
||||
|
||||
opts := label.NewListOptionsForBackup(backup.Name)
|
||||
podVolumeBackupList, err := veleroClient.VeleroV1().PodVolumeBackups(f.Namespace()).List(opts)
|
||||
podVolumeBackupList, err := veleroClient.VeleroV1().PodVolumeBackups(f.Namespace()).List(context.TODO(), opts)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error getting PodVolumeBackups for backup %s: %v\n", backup.Name, err)
|
||||
}
|
||||
@@ -92,7 +93,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
|
||||
csiClient, err = snapshotv1beta1client.NewForConfig(clientConfig)
|
||||
cmd.CheckError(err)
|
||||
|
||||
vscList, err = csiClient.SnapshotV1beta1().VolumeSnapshotContents().List(opts)
|
||||
vscList, err = csiClient.SnapshotV1beta1().VolumeSnapshotContents().List(context.TODO(), opts)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error getting VolumeSnapshotContent objects for backup %s: %v\n", backup.Name, err)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -43,7 +44,8 @@ func NewDownloadCommand(f client.Factory) *cobra.Command {
|
||||
|
||||
c := &cobra.Command{
|
||||
Use: "download NAME",
|
||||
Short: "Download a backup",
|
||||
Short: "Download all Kubernetes manifests for a backup",
|
||||
Long: "Download all Kubernetes manifests for a backup. Contents of persistent volume snapshots are not included.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: func(c *cobra.Command, args []string) {
|
||||
cmd.CheckError(o.Complete(args))
|
||||
@@ -86,7 +88,7 @@ func (o *DownloadOptions) Validate(c *cobra.Command, args []string, f client.Fac
|
||||
veleroClient, err := f.Client()
|
||||
cmd.CheckError(err)
|
||||
|
||||
if _, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(o.Name, metav1.GetOptions{}); err != nil {
|
||||
if _, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), o.Name, metav1.GetOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -43,12 +45,12 @@ func NewGetCommand(f client.Factory, use string) *cobra.Command {
|
||||
if len(args) > 0 {
|
||||
backups = new(api.BackupList)
|
||||
for _, name := range args {
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(name, metav1.GetOptions{})
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
cmd.CheckError(err)
|
||||
backups.Items = append(backups.Items, *backup)
|
||||
}
|
||||
} else {
|
||||
backups, err = veleroClient.VeleroV1().Backups(f.Namespace()).List(listOptions)
|
||||
backups, err = veleroClient.VeleroV1().Backups(f.Namespace()).List(context.TODO(), listOptions)
|
||||
cmd.CheckError(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
@@ -51,7 +52,7 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
|
||||
veleroClient, err := f.Client()
|
||||
cmd.CheckError(err)
|
||||
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(backupName, metav1.GetOptions{})
|
||||
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), backupName, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
cmd.Exit("Backup %q does not exist.", backupName)
|
||||
} else if err != nil {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user