Convert docs to docsy

This commit is contained in:
Phillip Wittrock
2020-06-07 21:07:46 -07:00
parent 25a38ad2b6
commit 42497c664f
11469 changed files with 816051 additions and 4557 deletions

28
site/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,28 @@
# How to Contribute
We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution;
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
## Community Guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).

201
site/LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

58
site/README.md Normal file
View File

@@ -0,0 +1,58 @@
# Docsy Example
[Docsy](https://github.com/google/docsy) is a Hugo theme for technical documentation sites, providing easy site navigation, structure, and more. This **Docsy Example Project** uses the Docsy theme, as well as providing a skeleton documentation structure for you to use. You can either copy this project and edit it with your own content, or use the theme in your projects like any other [Hugo theme](https://gohugo.io/themes/installing-and-using-themes/).
This Docsy Example Project is hosted at [https://example.docsy.dev/](https://example.docsy.dev/).
You can find detailed theme instructions in the Docsy user guide: https://docsy.dev/docs/
This is not an officially supported Google product. This project is currently maintained.
## Cloning the Docsy Example Project
The following will give you a project that is set up and ready to use (don't forget to use `--recurse-submodules` or you won't pull down some of the code you need to generate a working site). The `hugo server` command builds and serves the site. If you just want to build the site, run `hugo` instead.
```bash
git clone --recurse-submodules --depth 1 https://github.com/google/docsy-example.git
cd docsy-example
hugo server
```
The theme is included as a Git submodule:
```bash
▶ git submodule
a053131a4ebf6a59e4e8834a42368e248d98c01d themes/docsy (heads/master)
```
If you want to do SCSS edits and want to publish these, you need to install `PostCSS` (not needed for `hugo server`):
```bash
npm install
```
<!--### Cloning the Example from the Theme Project
```bash
git clone --recurse-submodules --depth 1 https://github.com/docsy.git
cd tech-doc-hugo-theme/exampleSite
HUGO_THEMESDIR="../.." hugo server
```
Note that the Hugo Theme Site requires the `exampleSite` to live in a subfolder of the theme itself. To avoid recursive duplication, the example site is added as a Git subtree:
```bash
git subtree add --prefix exampleSite https://github.com/google/docsy.git master --squash
```
To pull in changes, see `pull-deps.sh` script in the theme.-->
## Running the website locally
Once you've cloned the site repo, from the repo root folder, run:
```
hugo server
```

View File

@@ -0,0 +1,6 @@
/*
Add styles or override variables from the theme here.
*/

150
site/config.toml Normal file
View File

@@ -0,0 +1,150 @@
baseURL = "https://kubernetes-sigs.github.io/kustomize/"
title = "Kustomize"
publishDir = "../docs"
enableRobotsTXT = true
# Hugo allows theme composition (and inheritance). The precedence is from left to right.
theme = ["docsy"]
# Will give values to .Lastmod etc.
enableGitInfo = true
# Language settings
contentDir = "content/en"
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = false
# Useful when translating.
enableMissingTranslationPlaceholders = true
disableKinds = ["taxonomy", "taxonomyTerm"]
# Highlighting config
pygmentsCodeFences = true
pygmentsUseClasses = false
# Use the new Chroma Go highlighter in Hugo.
pygmentsUseClassic = false
#pygmentsOptions = "linenos=table"
# See https://help.farbox.com/pygments.html
pygmentsStyle = "tango"
# Configure how URLs look like per section.
[permalinks]
blog = "/:section/:year/:month/:day/:slug/"
## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
[blackfriday]
plainIDAnchors = true
hrefTargetBlank = true
angledQuotes = false
latexDashes = true
# Image processing configuration.
[imaging]
resampleFilter = "CatmullRom"
quality = 75
anchor = "smart"
[services]
[services.googleAnalytics]
# Comment out the next line to disable GA tracking. Also disables the feature described in [params.ui.feedback].
#id = "UA-00000000-0"
# Language configuration
[languages]
[languages.en]
title = "Kustomize"
description = "Kubernetes Configuration Customization"
languageName ="English"
# Weight used for sorting.
weight = 1
[markup]
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
# Everything below this are Site Params
[params]
copyright = "Kubernetes Authors"
# First one is picked as the Twitter card image if not set on page.
# images = ["images/project-illustration.png"]
# Menu title if your navbar has a versions selector to access old versions of your site.
# This menu appears only if you have at least one [params.versions] set.
version_menu = "Releases"
# Flag used in the "version-banner" partial to decide whether to display a
# banner on every page indicating that this is an archived version of the docs.
# Set this flag to "true" if you want to display the banner.
archived_version = false
# The version number for the version of the docs represented in this doc set.
# Used in the "version-banner" partial to display a version number for the
# current doc set.
version = "0.0"
# A link to latest version of the docs. Used in the "version-banner" partial to
# point people to the main doc site.
url_latest_version = "https://kubernetes-sigs.github.io/kustomize"
# Repository configuration (URLs for in-page links to opening issues and suggesting changes)
github_repo = "https://github.com/kubernetes-sigs/kustomize"
# An optional link to a related project repo. For example, the sibling repository where your product code lives.
github_project_repo = "https://github.com/kubernetes-sigs/kustomize"
# Specify a value here if your content directory is not in your repo's root directory
github_subdir = "site"
# Google Custom Search Engine ID. Remove or comment out to disable search.
# gcs_engine_id = "011737558837375720776:fsdu1nryfng"
# Enable Algolia DocSearch
algolia_docsearch = false
# Enable Lunr.js offline search
offlineSearch = false
# User interface configuration
[params.ui]
# Enable to show the side bar menu in its compact state.
sidebar_menu_compact = false
# Set to true to disable breadcrumb navigation.
breadcrumb_disable = false
# Set to true to hide the sidebar search box (the top nav search box will still be displayed if search is enabled)
sidebar_search_disable = false
# Set to false if you don't want to display a logo (/assets/icons/logo.svg) in the top nav bar
navbar_logo = false
# Set to true to disable the About link in the site footer
footer_about_disable = false
# Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events.
# This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set.
# If you want this feature, but occasionally need to remove the "Feedback" section from a single page,
# add "hide_feedback: true" to the page's front matter.
[params.ui.feedback]
enable = false
# The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful).
yes = 'Glad to hear it! Please <a href="https://github.com/kubernetes-sigs/kustomize/issues/new">tell us how we can improve</a>.'
no = 'Sorry to hear that. Please <a href="https://github.com/kubernetes-sigs/kustomize/issues/new">tell us how we can improve</a>.'
[params.links]
# End user relevant links. These will show up on left side of footer and in the community page if you have one.
[[params.links.user]]
name = "User mailing list"
url = "https://groups.google.com/forum/#!forum/kubernetes-sig-cli"
icon = "fa fa-envelope"
desc = "Discussion and help from your fellow users"
# Developer relevant links. These will show up on right side of footer and in the community page if you have one.
[[params.links.developer]]
name = "GitHub"
url = "https://github.com/kubernetes-sigs/kustomize"
icon = "fab fa-github"
desc = "Development takes place here!"

22
site/content/en/_index.md Normal file
View File

@@ -0,0 +1,22 @@
+++
title = "Kustomize"
linkTitle = "Kustomize"
+++
{{% blocks/lead color="primary" %}}
Kustomize provides a solution for customizing Kubernetes resource configuration free from templates
and DSLs.
{{% /blocks/lead %}}
{{< blocks/section >}}
{{% blocks/feature icon="fab fa-github" title="Contribute" %}}
We do a [Pull Request](https://github.com/kubernetes-sigs/kustomize/pulls) contributions workflow on **GitHub**.
New users are always welcome!
{{% /blocks/feature %}}
{{< /blocks/section >}}

View File

@@ -0,0 +1,11 @@
---
title: "API Reference"
linkTitle: "API Reference"
type: docs
weight: 4
menu:
main:
weight: 40
description: >
Reference for Kustomize client-side APIs
---

View File

@@ -0,0 +1,483 @@
---
title: "Glossary"
linkTitle: "Glossary"
type: docs
weight: 99
description: >
Glossary of terms
---
# Glossary
[CRD spec]: https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
[CRD]: #custom-resource-definition
[DAM]: #declarative-application-management
[Declarative Application Management]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/declarative-application-management.md
[JSON]: https://www.json.org/
[JSONPatch]: https://tools.ietf.org/html/rfc6902
[JSONMergePatch]: https://tools.ietf.org/html/rfc7386
[Resource]: #resource
[YAML]: http://www.yaml.org/start.html
[application]: #application
[apply]: #apply
[apt]: https://en.wikipedia.org/wiki/APT_(Debian)
[base]: #base
[bases]: #base
[bespoke]: #bespoke-configuration
[gitops]: #gitops
[k8s]: #kubernetes
[kubernetes]: #kubernetes
[kustomize]: #kustomize
[kustomization]: #kustomization
[kustomizations]: #kustomization
[off-the-shelf]: #off-the-shelf-configuration
[overlay]: #overlay
[overlays]: #overlay
[patch]: #patch
[patches]: #patch
[patchJson6902]: #patchjson6902
[patchExampleJson6902]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/jsonpatch.md
[patchesJson6902]: #patchjson6902
[proposal]: https://github.com/kubernetes/community/pull/1629
[rebase]: https://git-scm.com/docs/git-rebase
[resource]: #resource
[resources]: #resource
[root]: #kustomization-root
[rpm]: https://en.wikipedia.org/wiki/Rpm_(software)
[strategic-merge]: https://git.k8s.io/community/contributors/devel/sig-api-machinery/strategic-merge-patch.md
[target]: #target
[transformer]: #transformer
[variant]: #variant
[variants]: #variant
[workflow]: /kustomize/guides
## application
An _application_ is a group of k8s resources related by
some common purpose, e.g. a load balancer in front of a
webserver backed by a database.
[Resource] labelling, naming and metadata schemes have
historically served to group resources together for
collective operations like _list_ and _remove_.
This [proposal] describes a new k8s resource called
_application_ to more formally describe this idea and
provide support for application-level operations and
dashboards.
[kustomize] configures k8s resources, and the proposed
application resource is just another resource.
## apply
The verb _apply_ in the context of k8s refers to a
kubectl command and an in-progress [API
endpoint](https://goo.gl/UbCRuf) for mutating a
cluster.
One _applies_ a statement of what one wants to a
cluster in the form of a complete resource list.
The cluster merges this with the previously applied
state and the actual state to arrive at a new desired
state, which the cluster's reconciliation loop attempts
to create. This is the foundation of level-based state
management in k8s.
## base
A _base_ is a [kustomization] referred to
by some other [kustomization].
Any kustomization, including an [overlay], can be a base to
another kustomization.
A base has no knowledge of the overlays that refer to it.
For simple [gitops] management, a base configuration
could be the _sole content of a git repository
dedicated to that purpose_. Same with [overlays].
Changes in a repo could generate a build, test and
deploy cycle.
## bespoke configuration
A _bespoke_ configuration is a [kustomization] and some
[resources] created and maintained internally by some
organization for their own purposes.
The [workflow] associated with a _bespoke_ config is
simpler than the workflow associated with an
[off-the-shelf] config, because there's no notion of
periodically capturing someone else's upgrades to the
[off-the-shelf] config.
## custom resource definition
One can extend the k8s API by making a
Custom Resource Definition ([CRD spec]).
This defines a custom [resource] (CD), an entirely
new resource that can be used alongside _native_
resources like ConfigMaps, Deployments, etc.
Kustomize can customize a CD, but to do so
kustomize must also be given the corresponding CRD
so that it can interpret the structure correctly.
## declarative application management
Kustomize aspires to support [Declarative Application Management],
a set of best practices around managing k8s clusters.
In brief, kustomize should
* Work with any configuration, be it bespoke,
off-the-shelf, stateless, stateful, etc.
* Support common customizations, and creation of
[variants] (e.g. _development_ vs.
_staging_ vs. _production_).
* Expose and teach native k8s APIs, rather than
hide them.
* Add no friction to version control integration to
support reviews and audit trails.
* Compose with other tools in a unix sense.
* Eschew crossing the line into templating, domain
specific languages, etc., frustrating the other
goals.
## generator
A generator makes resources that can be used as is,
or fed into a [transformer].
## gitops
Devops or CICD workflows that use a git repository as a
single source of truth and take action (e.g., build,
test or deploy) when that truth changes.
## kustomization
The term _kustomization_ refers to a
`kustomization.yaml` file, or more generally to a
directory (the [root]) containing the
`kustomization.yaml` file and all the relative file
paths that it immediately references (all the local
data that doesn't require a URL specification).
I.e. if someone gives you a _kustomization_ for use
with [kustomize], it could be in the form of
* one file called `kustomization.yaml`,
* a tarball (containing that YAML file plus what it references),
* a git archive (ditto),
* a URL to a git repo (ditto), etc.
A kustomization file contains [fields](fields.md)
falling into four categories:
* _resources_ - what existing [resources] are to be customized.
Example fields: _resources_, _crds_.
* _generators_ - what _new_ resources should be created.
Example fields: _configMapGenerator_ (legacy),
_secretGenerator_ (legacy), _generators_ (v2.1).
* _transformers_ - what to _do_ to the aforementioned resources.
Example fields: _namePrefix_, _nameSuffix_, _images_,
_commonLabels_, _patchesJson6902_, etc. and the more
general _transformers_ (v2.1) field.
* _meta_ - fields which may influence all or some of
the above. Example fields: _vars_, _namespace_,
_apiVersion_, _kind_, etc.
## kustomization root
The directory that immediately contains a
`kustomization.yaml` file.
When a kustomization file is processed, it may or may
not be able to access files outside its root.
Data files like resource YAML files, or text files
containing _name=value_ pairs intended for a ConfigMap
or Secret, or files representing a patch to be used in
a patch transformation, must live _within or below_ the
root, and as such are specified via _relative
paths_ exclusively.
A special flag (in v2.1), `--load_restrictions none`,
is provided to relax this security feature, to, say,
allow a patch file to be shared by more than one
kustomization.
Other kustomizations (other directories containing a
`kustomization.yaml` file) may be referred to by URL, by
absolute path, or by relative path.
If kustomization __A__ depends on kustomization __B__, then
* __B__ may not _contain_ __A__.
* __B__ may not _depend on_ __A__, even transitively.
__A__ may contain __B__, but in this case it might be
simplest to have __A__ directly depend on __B__'s
resources and eliminate __B__'s kustomization.yaml file
(i.e. absorb __B__ into __A__).
Conventionally, __B__ is in a directory that's sibling
to __A__, or __B__ is off in a completely independent
git repository, referencable from any kustomization.
A common layout is
> ```
> ├── base
> │   ├── deployment.yaml
> │   ├── kustomization.yaml
> │   └── service.yaml
> └── overlays
> ├── dev
> │   ├── kustomization.yaml
> │   └── patch.yaml
> ├── prod
> │   ├── kustomization.yaml
> │   └── patch.yaml
> └── staging
> ├── kustomization.yaml
> └── patch.yaml
> ```
The three roots `dev`, `prod` and `staging`
(presumably) all refer to the `base` root. One would
have to inspect the `kustomization.yaml` files to be
sure.
## kubernetes
[Kubernetes](https://kubernetes.io) is an open-source
system for automating deployment, scaling, and
management of containerized applications.
It's often abbreviated as _k8s_.
## kubernetes-style object
[fields required]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
An object, expressed in a YAML or JSON file, with the
[fields required] by kubernetes. Basically just a
_kind_ field to identify the type, a _metadata/name_
field to identify the particular instance, and an
_apiVersion_ field to identify the version (if there's
more than one version).
## kustomize
_kustomize_ is a command line tool supporting
template-free, structured customization of declarative
configuration targeted to k8s-style objects.
_Targeted to k8s means_ that kustomize has some
understanding of API resources, k8s concepts like
names, labels, namespaces, etc. and the semantics of
resource patching.
kustomize is an implementation of [DAM].
## off-the-shelf configuration
An _off-the-shelf_ configuration is a kustomization and
resources intentionally published somewhere for others
to use.
E.g. one might create a github repository like this:
> ```
> github.com/username/someapp/
> kustomization.yaml
> deployment.yaml
> configmap.yaml
> README.md
> ```
Someone could then _fork_ this repo (on github) and
_clone_ their fork to their local disk for
customization.
This clone could act as a [base] for the user's
own [overlays] to do further customization.
## overlay
An _overlay_ is a kustomization that depends on
another kustomization.
The [kustomizations] an overlay refers to (via file
path, URI or other method) are called [bases].
An overlay is unusable without its bases.
An overlay may act as a base to another overlay.
Overlays make the most sense when there is _more than
one_, because they create different [variants] of a
common base - e.g. _development_, _QA_, _staging_ and
_production_ environment variants.
These variants use the same overall resources, and vary
in relatively simple ways, e.g. the number of replicas
in a deployment, the CPU to a particular pod, the data
source used in a ConfigMap, etc.
One configures a cluster like this:
> ```
> kustomize build someapp/overlays/staging |\
> kubectl apply -f -
>
> kustomize build someapp/overlays/production |\
> kubectl apply -f -
> ```
Usage of the base is implicit - the overlay's
kustomization points to the base.
See also [root].
## package
The word _package_ has no meaning in kustomize, as
kustomize is not to be confused with a package
management tool in the tradition of, say, [apt] or
[rpm].
## patch
General instructions to modify a resource.
There are two alternative techniques with similar
power but different notation - the
[strategic merge patch](#patchstrategicmerge)
and the [JSON patch](#patchjson6902).
## patchStrategicMerge
A _patchStrategicMerge_ is [strategic-merge]-style patch (SMP).
An SMP looks like an incomplete YAML specification of
a k8s resource. The SMP includes `TypeMeta`
fields to establish the group/version/kind/name of the
[resource] to patch, then just enough remaining fields
to step into a nested structure to specify a new field
value, e.g. an image tag.
By default, an SMP _replaces_ values. This is
usually desired when the target value is a simple
string, but may not be desired when the target
value is a list.
To change this
default behavior, add a _directive_. Recognized
directives in YAML patches are _replace_ (the default)
and _delete_ (see [these notes][strategic-merge]).
Note that for custom resources, SMPs are treated as
[json merge patches][JSONMergePatch].
Fun fact - any resource file can be used as
an SMP, overwriting matching fields in another
resource with the same group/version/kind/name,
but leaving all other fields as they were.
TODO(monopole): add ptr to example.
## patchJson6902
A _patchJson6902_ refers to a kubernetes [resource] and
a [JSONPatch] specifying how to change the resource.
A _patchJson6902_ can do almost everything a
_patchStrategicMerge_ can do, but with a briefer
syntax. See this [example][patchExampleJson6902].
## plugin
A chunk of code used by kustomize, but not necessarily
compiled into kustomize, to generate and/or transform a
kubernetes resource as part of a kustomization.
Details [here](plugins).
## resource
A _resource_ in the context of a REST-ful API is the
target object of an HTTP operation like _GET_, _PUT_ or
_POST_. k8s offers a REST-ful API surface to interact
with clients.
A _resource_, in the context of a kustomization, is a
[root] relative path to a [YAML] or [JSON] file
describing a k8s API object, like a Deployment or a
ConfigMap, or it's a path to a kustomization, or a URL
that resolves to a kustomization.
More generally, a resource can be any correct YAML file
that [defines an object](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields)
with a _kind_ and a _metadata/name_ field.
## root
See [kustomization root][root].
## sub-target / sub-application / sub-package
A _sub-whatever_ is not a thing. There are only
[bases] and [overlays].
## target
The _target_ is the argument to `kustomize build`, e.g.:
> ```
> kustomize build $target
> ```
`$target` must be a path or a url to a [kustomization].
The target contains, or refers to, all the information
needed to create customized resources to send to the
[apply] operation.
A target can be a [base] or an [overlay].
## transformer
A transformer can modify a resource, or merely
visit it and collect information about it in the
course of a `kustomize build`.
## variant
A _variant_ is the outcome, in a cluster, of applying
an [overlay] to a [base].
E.g., a _staging_ and _production_ overlay both modify
some common base to create distinct variants.
The _staging_ variant is the set of resources exposed
to quality assurance testing, or to some external users
who'd like to see what the next version of production
will look like.
The _production_ variant is the set of resources
exposed to production traffic, and thus may employ
deployments with a large number of replicas and higher
cpu and memory requests.

View File

@@ -0,0 +1,11 @@
---
title: "kustomization.yaml"
linkTitle: "kustomization.yaml"
type: docs
weight: 10
description: >
kustomization.yaml fields and API
---

View File

@@ -0,0 +1,17 @@
---
title: "bases"
linkTitle: "bases"
type: docs
description: >
Add resources from a kustomization dir.
---
{{% pageinfo color="warning" %}}
The `bases` field was deprecated in v2.1.0
{{% /pageinfo %}}
Move entries into the [resources](/kustomize/api-reference/kustomization/resources)
field. This allows bases - which are still a
[central concept](/kustomize/api-reference/kustomization/glossary#base) - to be
ordered relative to other input resources.

View File

@@ -0,0 +1,17 @@
---
title: "commonAnnotations"
linkTitle: "commonAnnotations"
type: docs
description: >
Add annotations to add all resources.
---
Add annotations (non-identifying metadata) to all resources. These are key value pairs.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonAnnotations:
oncallPager: 800-555-1212
```

View File

@@ -0,0 +1,19 @@
---
title: "commonLabels"
linkTitle: "commonLabels"
type: docs
description: >
Add labels and selectors to add all resources.
---
Add labels and selectors to all resources.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
someName: someValue
owner: alice
app: bingo
```

View File

@@ -0,0 +1,9 @@
---
title: "components"
linkTitle: "components"
type: docs
description: >
Compose kustomizations.
---
*Coming soon*

View File

@@ -0,0 +1,84 @@
---
title: "configMapGenerator"
linkTitle: "configMapGenerator"
type: docs
description: >
Generate ConfigMap resources.
---
Each entry in this list results in the creation of
one ConfigMap resource (it's a generator of n maps).
The example below creates three ConfigMaps. One with the names and contents of
the given files, one with key/value as data, and a third which sets an
annotation and label via `options` for that single ConfigMap.
Each configMapGenerator item accepts a parameter of
`behavior: [create|replace|merge]`.
This allows an overlay to modify or
replace an existing configMap from the parent.
Also, each entry has an `options` field, that has the
same subfields as the kustomization file's `generatorOptions` field.
This `options` field allows one to add labels and/or
annotations to the generated instance, or to individually
disable the name suffix hash for that instance.
Labels and annotations added here will not be overwritten
by the global options associated with the kustomization
file `generatorOptions` field. However, due to how
booleans behave, if the global `generatorOptions` field
specifies `disableNameSuffixHash: true`, this will
trump any attempt to locally override it.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# These labels are added to all configmaps and secrets.
generatorOptions:
labels:
fruit: apple
configMapGenerator:
- name: my-java-server-props
behavior: merge
files:
- application.properties
- more.properties
- name: my-java-server-env-vars
literals:
- JAVA_HOME=/opt/java/jdk
- JAVA_TOOL_OPTIONS=-agentlib:hprof
options:
disableNameSuffixHash: true
labels:
pet: dog
- name: dashboards
files:
- mydashboard.json
options:
annotations:
dashboard: "1"
labels:
app.kubernetes.io/name: "app1"
```
It is also possible to
[define a key](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#define-the-key-to-use-when-creating-a-configmap-from-a-file)
to set a name different than the filename.
The example below creates a ConfigMap
with the name of file as `myFileName.ini`
while the _actual_ filename from which the
configmap is created is `whatever.ini`.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: app-whatever
files:
- myFileName.ini=whatever.ini
```

View File

@@ -0,0 +1,39 @@
---
title: "crds"
linkTitle: "crds"
type: docs
description: >
Adding CRD support
---
Each entry in this list should be a relative path to
a file for custom resource definition (CRD).
The presence of this field is to allow kustomize be
aware of CRDs and apply proper
transformation for any objects in those types.
Typical use case: A CRD object refers to a
ConfigMap object. In a kustomization, the ConfigMap
object name may change by adding namePrefix,
nameSuffix, or hashing. The name reference for this
ConfigMap object in CRD object need to be updated
with namePrefix, nameSuffix, or hashing in the
same way.
The annotations can be put into openAPI definitions are:
- "x-kubernetes-annotation": ""
- "x-kubernetes-label-selector": ""
- "x-kubernetes-identity": ""
- "x-kubernetes-object-ref-api-version": "v1",
- "x-kubernetes-object-ref-kind": "Secret",
- "x-kubernetes-object-ref-name-key": "name",
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
crds:
- crds/typeA.yaml
- crds/typeB.yaml
```

View File

@@ -0,0 +1,31 @@
---
title: "generatorOptions"
linkTitle: "generatorOptions"
type: docs
description: >
Control behavior of [ConfigMap](/kustomize/api-reference/kustomization/configmapgenerator) and
[Secret](/kustomize/api-reference/kustomization/secretgenerator) generators.
---
Additionally, generatorOptions can be set on a per resource level within each
generator. For details on per-resource generatorOptions usage see
[field-name-configMapGenerator] and See [field-name-secretGenerator].
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generatorOptions:
# labels to add to all generated resources
labels:
kustomize.generated.resources: somevalue
# annotations to add to all generated resources
annotations:
kustomize.generated.resource: somevalue
# disableNameSuffixHash is true disables the default behavior of adding a
# suffix to the names of generated resources that is a hash of
# the resource contents.
disableNameSuffixHash: true
```

View File

@@ -0,0 +1,52 @@
---
title: "images"
linkTitle: "images"
type: docs
description: >
Modify the name, tags and/or digest for images.
---
Images modify the name, tags and/or digest for images without creating patches. E.g. Given this
kubernetes Deployment fragment:
```yaml
kind: Deployment
...
spec:
template:
spec:
containers:
- name: mypostgresdb
image: postgres:8
- name: nginxapp
image: nginx:1.7.9
- name: myapp
image: my-demo-app:latest
- name: alpine-app
image: alpine:3.7
```
one can change the `image` in the following ways:
- `postgres:8` to `my-registry/my-postgres:v1`,
- nginx tag `1.7.9` to `1.8.0`,
- image name `my-demo-app` to `my-app`,
- alpine's tag `3.7` to a digest value
all with the following *kustomization*:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: postgres
newName: my-registry/my-postgres
newTag: v1
- name: nginx
newTag: 1.8.0
- name: my-demo-app
newName: my-app
- name: alpine
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
```

View File

@@ -0,0 +1,16 @@
---
title: "namePrefix"
linkTitle: "namePrefix"
type: docs
description: >
Prepends the value to the names of all resources and references.
---
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: alices-
```
A deployment named `wordpress` would become `alices-wordpress`.

View File

@@ -0,0 +1,17 @@
---
title: "namespace"
linkTitle: "namespace"
type: docs
description: >
Adds namespace to all resources.
---
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: my-namespace
```
Will override the existing namespace if it is set on a resource, or add it
if it is not set on a resource.

View File

@@ -0,0 +1,18 @@
---
title: "nameSuffix"
linkTitle: "nameSuffix"
type: docs
description: >
Appends the value to the names of all resources and references.
---
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
nameSuffix: -v2
```
A deployment named `wordpress` would become `wordpress-v2`.
**Note:** The suffix is appended before the content hash if the resource type is ConfigMap or Secret.

View File

@@ -0,0 +1,38 @@
---
title: "patches"
linkTitle: "patches"
type: docs
description: >
Patch resources
---
Each entry in this list should resolve to patch object, which includes a patch and a target selector.
The patch can be either a strategic merge patch or a JSON patch. It can be either a patch file, or an inline
string. The target selects resources by group, version, kind, name, namespace, labelSelector and
annotationSelector. Any resource which matches all the specified fields has the patch applied.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patches:
- path: patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: deploy.*
labelSelector: "env=dev"
annotationSelector: "zone=west"
- patch: |-
- op: replace
path: /some/existing/path
value: new value
target:
kind: MyKind
labelSelector: "env=dev"
```
The `name` and `namespace` fields of the patch target selector are
automatically anchored regular expressions. This means that the value `myapp`
is equivalent to `^myapp$`.

View File

@@ -0,0 +1,56 @@
---
title: "patchesStrategicMerge"
linkTitle: "patchesStrategicMerge"
type: docs
description: >
Patch resources using the strategic merge patch standard.
---
Each entry in this list should be either a relative
file path or an inline content
resolving to a partial or complete resource
definition.
The names in these (possibly partial) resource
files must match names already loaded via the
`resources` field. These entries are used to
_patch_ (modify) the known resources.
Small patches that do one thing are best, e.g. modify
a memory request/limit, change an env var in a
ConfigMap, etc. Small patches are easy to review and
easy to mix together in overlays.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patchesStrategicMerge:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml
```
The patch content can be a inline string as well.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patchesStrategicMerge:
- |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nignx:latest
```
Note that kustomize does not support more than one patch
for the same object that contain a _delete_ directive. To remove
several fields / slice elements from an object create a single
patch that performs all the needed deletions.

View File

@@ -0,0 +1,71 @@
---
title: "patchesJson6902"
linkTitle: "patchesJson6902"
type: docs
description: >
Patch resources using the [json 6902 standard](https://tools.ietf.org/html/rfc6902)
---
Each entry in this list should resolve to a kubernetes object and a JSON patch that will be applied
to the object.
The JSON patch is documented at https://tools.ietf.org/html/rfc6902
target field points to a kubernetes object within the same kustomization
by the object's group, version, kind, name and namespace.
path field is a relative file path of a JSON patch file.
The content in this patch file can be either in JSON format as
```json
[
{"op": "add", "path": "/some/new/path", "value": "value"},
{"op": "replace", "path": "/some/existing/path", "value": "new value"}
]
```
or in YAML format as
```yaml
- op: add
path: /some/new/path
value: value
- op: replace
path: /some/existing/path
value: new value
```
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patchesJson6902:
- target:
version: v1
kind: Deployment
name: my-deployment
path: add_init_container.yaml
- target:
version: v1
kind: Service
name: my-service
path: add_service_annotation.yaml
```
The patch content can be an inline string as well:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patchesJson6902:
- target:
version: v1
kind: Deployment
name: my-deployment
patch: |-
- op: add
path: /some/new/path
value: value
- op: replace
path: /some/existing/path
value: "new value"
```

View File

@@ -0,0 +1,43 @@
---
title: "replicas"
linkTitle: "replicas"
type: docs
description: >
Change the number of replicas for a resource.
---
Given this kubernetes Deployment fragment:
```
# deployment.yaml
kind: Deployment
metadata:
name: deployment-name
spec:
replicas: 3
```
one can change the number of replicas to 5
by adding the following to your kustomization:
```
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
replicas:
- name: deployment-name
count: 5
```
This field accepts a list, so many resources can
be modified at the same time.
As this declaration does not take in a `kind:` nor a `group:`
it will match any `group` and `kind` that has a matching name and
that is one of:
- `Deployment`
- `ReplicationController`
- `ReplicaSet`
- `StatefulSet`
For more complex use cases, revert to using a patch.

View File

@@ -0,0 +1,34 @@
---
title: "resources"
linkTitle: "resources"
type: docs
description: >
Resources to include.
---
Each entry in this list must be a path to a _file_, or a path (or URL) referring to another
kustomization _directory_, e.g.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- myNamespace.yaml
- sub-dir/some-deployment.yaml
- ../../commonbase
- github.com/kubernetes-sigs/kustomize/examples/multibases?ref=v1.0.6
- deployment.yaml
- github.com/kubernets-sigs/kustomize/examples/helloWorld?ref=test-branch
```
Resources will be read and processed in depth-first order.
Files should contain k8s resources in YAML form. A file may contain multiple resources separated by
the document marker `---`. File paths should be specified _relative_ to the directory holding the
kustomization file containing the `resources` field.
[hashicorp URL]: https://github.com/hashicorp/go-getter#url-format
Directory specification can be relative, absolute, or part of a URL. URL specifications should
follow the [hashicorp URL] format. The directory must contain a `kustomization.yaml` file.

View File

@@ -0,0 +1,44 @@
---
title: "secretGenerator"
linkTitle: "secretGenerator"
type: docs
description: >
Generate Secret resources.
---
Each entry in the argument list results in the creation of one Secret resource (it's a generator of N secrets).
This works like the [configMapGenerator](/kustomize/api-reference/kustomization/configmapgenerator).
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: app-tls
files:
- secret/tls.cert
- secret/tls.key
type: "kubernetes.io/tls"
- name: app-tls-namespaced
# you can define a namespace to generate
# a secret in, defaults to: "default"
namespace: apps
files:
- tls.crt=catsecret/tls.cert
- tls.key=secret/tls.key
type: "kubernetes.io/tls"
- name: env_file_secret
envs:
- env.txt
type: Opaque
- name: secret-with-annotation
files:
- app-config.yaml
type: Opaque
options:
annotations:
app_config: "true"
labels:
app.kubernetes.io/name: "app2"
```

View File

@@ -0,0 +1,85 @@
---
title: "vars"
linkTitle: "vars"
type: docs
description: >
Substitute name references.
---
Vars are used to capture text from one resource's field
and insert that text elsewhere - a reflection feature.
For example, suppose one specifies the name of a k8s Service
object in a container's command line, and the name of a
k8s Secret object in a container's environment variable,
so that the following would work:
```yaml
containers:
- image: myimage
command: ["start", "--host", "$(MY_SERVICE_NAME)"]
env:
- name: SECRET_TOKEN
value: $(SOME_SECRET_NAME)
```
To do so, add an entry to `vars:` as follows:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
vars:
- name: SOME_SECRET_NAME
objref:
kind: Secret
name: my-secret
apiVersion: v1
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-service
apiVersion: v1
fieldref:
fieldpath: metadata.name
- name: ANOTHER_DEPLOYMENTS_POD_RESTART_POLICY
objref:
kind: Deployment
name: my-deployment
apiVersion: apps/v1
fieldref:
fieldpath: spec.template.spec.restartPolicy
```
A var is a tuple of variable name, object
reference and field reference within that object.
That's where the text is found.
The field reference is optional; it defaults to
`metadata.name`, a normal default, since kustomize
is used to generate or modify the names of
resources.
At time of writing, only string type fields are
supported. No ints, bools, arrays etc. It's not
possible to, say, extract the name of the image in
container number 2 of some pod template.
A variable reference, i.e. the string '$(FOO)',
can only be placed in particular fields of
particular objects as specified by kustomize's
configuration data.
The default config data for vars is at [/api/konfig/builtinpluginconsts/varreference.go](/konfig/builtinpluginconsts/varreference.go)
Long story short, the default targets are all
container command args and env value fields.
Vars should _not_ be used for inserting names in
places where kustomize is already handling that
job. E.g., a Deployment may reference a ConfigMap
by name, and if kustomize changes the name of a
ConfigMap, it knows to change the name reference
in the Deployment.

View File

@@ -0,0 +1,7 @@
---
title: "Kustomize Blog"
linkTitle: "Blog"
menu:
main:
weight: 80
---

View File

@@ -0,0 +1,6 @@
---
title: "New Releases"
linkTitle: "Releases"
weight: 20
---

View File

@@ -0,0 +1,22 @@
---
title: "v1.0.1"
linkTitle: "v1.0.1"
date: 2018-05-21
description: >
Kustomize v1.0.1
---
Initial release after move from github.com/kubernetes/kubectl to github.com/kubernetes-sigs/kustomize.
History
* May 2018: v1.0 after move to github.com/kubernetes-sigs/kubectl
from github.com/kubernetes/kubectl.
Has kustomization file, bases, overlays, basic transforms.
* Apr 2018: s/kinflate/kustomize/, s/manifest/kustomization/
* Oct 2017: s/kexpand/kinflate/
* Sep 2017: kexpand [starts](https://github.com/kubernetes/kubectl/pull/65)
in github.com/kubernetes/kubectl
* Aug 2017: [DAM] authored by Brian Grant
[DAM]: https://docs.google.com/document/d/1cLPGweVEYrVqQvBLJg6sxV-TrE5Rm2MNOBA_cxZP2WU

View File

@@ -0,0 +1,137 @@
---
title: "v2.0.0"
linkTitle: "v2.0.0"
date: 2019-02-05
description: >
Kustomize v2.0.0
---
[security concern]: https://docs.google.com/document/d/1FYgLVdq-siB_Cef9yuQBmit0PbrE8lsyTBdGI2eA2y8/edit
After security review, a field used in secret
generation (see below) was removed from the
definition of a kustomization file with no
mechanism to convert it to a new form. Also, the
set of files accessible from a kustomization file
has been further constrained.
Per the [versioning policy](/kustomize/faq/versioningpolicy),
backward incompatible changes trigger an increment
of the major version number, hence we go
from 1.0.11 to 2.0.0. We're taking this major
version increment opportunity to remove some
already deprecated fields, and the code paths
associated with them.
## Backward Incompatible Changes
### Kustomization Path Constraints
A kustomization file can specify paths to other
files, including resources, patches, configmap
generation data, secret generation data and
bases. In the case of a base, the path can be a
git URL instead.
In 1.x, these paths had to be relative to the
current kustomization directory (the location of
the kustomization file used in the `build`
command).
In 2.0, bases can continue to specify, via
relative paths, kustomizations outside the current
kustomization directory. But non-base paths are
constrained to terminate in or below the current
kustomization directory. Further, bases specified
via a git URL may not reference files outside of
the directory used to clone the repository.
### Kustomization Field Removals
#### patches
`patches` was deprecated and replaced by
`patchesStrategicMerge` when `patchesJson6902` was
introduced. In Kustomize 2.0.0, `patches` is
removed. Please use `patchesStrategicMerge`
instead.
#### imageTags
`imageTags` is replaced by `images` since `images`
can provide more features to change image names,
registries, tags and digests.
#### secretGenerator/commands
`commands` is removed from SecretGenerator due to
a [security concern]. One can use `files` or
`literals`, similar to ConfigMapGenerator, to
generate a secret.
```
secretGenerator:
- name: app-tls
files:
- secret/tls.cert
- secret/tls.key
type: "kubernetes.io/tls"
```
## Compatible Changes (New Features)
As this release is triggered by a security change,
there are no major new features to announce. A few
things that are worth mentioning in this release
are:
* More than _40_ issues closed since 1.0.11
release (including many extensions to
transformation rules).
* Users can run `kustomize edit fix` to migrate a
kustomization file working with previous
versions to one working with 2.0.0. For example,
a kustomization.yaml with following content
```
patches:
- deployment-patch.yaml
imageTags:
- name: postgres
newTag: v1
```
will be converted to
```
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patchesStrategicMerge:
- deployment-patch.yaml
images:
- name: postgres
newTag: v1
```
* Kustomization filename
In previous versions, the name of a
kustomization file had to be
`kustomization.yaml`.
Kustomize allows `kustomization.yaml`,
`kustomization.yml` and
`Kustomization`. In a directory, only one of
those filenames is allowed. If there are more
than one found, Kustomize will exit with an
error. Please select the best filename for your
use cases.
* Cancelled plans to deprecate applying prefix/suffix to namespace.
The deprecation warning
```
Adding nameprefix and namesuffix to Namespace resource will be deprecated in next release.
```
was removed.

View File

@@ -0,0 +1,249 @@
---
title: "v2.1.0"
linkTitle: "v2.1.0"
date: 2019-06-18
description: >
Kustomize v2.1.0
---
[Go modules]: https://github.com/golang/go/wiki/Modules
[generator options]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/generatorOptions.md
[imgModules]: /kustomize/images/goModules.png
[imgPlugins]: /kustomize/images/plugins.png
[imgPruning]: /kustomize/images/pruning.png
[imgSorted]: /kustomize/images/sorted.png
[imgWheels]: /kustomize/images/abandonedTrainingWheels.png
[kustomization]: glossary#kustomization
[_kustomization_]: /kustomize/api-reference/glossary#kustomization
[base]: /kustomize/api-reference/glossary#base
[bases]: /kustomize/api-reference/glossary#base
[_base_]: /kustomize/api-reference/glossary#base
[kustomize inventory object documentation]: https://github.com/kubernetes-sigs/kustomize/tree/master/docs/inventory_object.md
[kustomize plugin documentation]: plugins
[root]: /kustomize/api-reference/glossary#kustomization-root
[transformer configs]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/transformerconfigs
[v1.0.9]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v1.0.9
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v1.0.9releases/tag/v2.0.3
[v2.1.0]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v1.0.9releases/tag/v2.1.0
[versioning policy]: /kustomize/faq/versioningpolicy
Go modules, resource ordering respected, generator and transformer plugins, eased
loading restrictions, the notion of inventory, eased replica count modification.
About ~90 issues closed since [v2.0.3] in ~400 commits.
Download [here][v2.1.0].
## Go modules
![gopher with boxes][imgModules]
Kustomize now defines its dependencies in a top
level `go.mod` file. This is the first step
towards a package structure intentially exported
as one or more [Go modules] for use in other
programs (kubectl, kubebuilder, etc.) and in
kustomize plugins (see below).
## Resource ordering
![sort order retained][imgSorted]
Kustomize now retains the depth-first order of
resources as read, a frequently requested
feature.
This means resource order can be controlled
by editting kustomization files. This is
also vital to applying user-defined
transformations (plugins) in a particular
order.
Nothing needs to be done to activate this;
it happens automatically.
The `build` command now accepts a `--reorder`
flag with values `legacy` and `none`,
with a default value of `legacy`.
`legacy` means apply an ordering based on
GVK, that currently emits `Namespace` objects
first, and `ValidatingWebhookConfiguration`
objects last. This means that despite
automatic retention of load order, your
`build` output won't change by default.
`none` means _don't_ reorder the resources before
output. Specify this to see output order
respect input order.
## Generator and transformer plugins
![kid putting knife in electrical outlet][imgPlugins]
Since the beginning (as `kinflate` back in Sep
2017), kustomize has read or generated resources,
applied a series of pipelined transformation to
them, and emitted the result to `stdout`.
At that time, the only way to change the behavior
of a generator (e.g. a secret generator), or
change the behavior of a transformer (e.g. a name
changer, or json patcher), was to modify source
code and put out a release.
[v1.0.9] introduced [generator options] as a means
to change the behavior of the only two generators
available at the time - Secret and ConfigMap
generators. It also introduced
[transformer configs] as a way to fine tune the
targets of transformations (e.g. to which fields
_selectors_ should be added). Most of the feature
requests for kustomize revolve around changing the
behavior of the builtin generators and
transformers.
[v2.1.0] adds an _alpha_ plugin framework, that
encourages users to write their own generators or
transformers, _declaring them as kubernetes
objects just like everything else_, and apply them
as part of the `kustomize build` process.
To inform the API exposed to plugins, and to
confirm that the plugin framework can offer plugin
authors the same capabilities as builtin
operations, all the builtin generators and
tranformers have been converted to plugin form
(with one exceptions awaiting Go module
refinements). This means that adding, say, a
`secretGenerator` or `commonAnnotations` directive
to your kustomization will (in [v2.1.0]) trigger
execution of
[code committed as a plugin](https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin).
For more information, see the
[kustomize plugin documentation].
## Remove load restrictions
![removed training wheels][imgWheels]
The following usage:
```
kustomize build --load_restrictor none $target
```
allows a `kustomization.yaml` file used in this
build to refer to files outside its own directory
(i.e. outside its [root]).
This is an opt-in to suppress a security feature
that denies this precise behavior.
This feature should only be used to allow multiple
overlays (e.g. prod, staging and dev) to share a
patch file. To share _resources_, use a relative
path or URL to a kustomization directory in the
`resources` directive.
## Inventory generation for pruning
![pruning dead branches][imgPruning]
_Alpha_
Users can add an `inventory` stanza to their
kustomization file, to add a special _inventory
object_ to the `build` result.
This object applies to the cluster along with
everything else in the build result and can be
used by other clients to intelligently _prune_
orphaned cluster resources.
For more information see the
[kustomize inventory object documentation].
## Field changes / deprecations
### `resources` expanded, `bases` deprecated
The `resources` field has been generalized; it now
accepts what formerly could only be specified in
the `bases` field.
This change was made to allow users fine control
over resource processing order. With a distinct
`bases` field, bases had to be loaded separately
from resources as a group. Now, base loading may
be interleaved as desired with the loading of
resource files from the current
directory. [Resource ordering](#resource-ordering)
had to be respected before this feature could be
introduced.
The `bases` field is now deprecated, and will be
deleted in some future major release. Manage the
deprecation simply moving the arguments of the
`bases` field to the `resources` field in the
desired order, e.g.
> ```
> resources:
> - someResouceFile.yaml
> - someOtherResourceFile.yaml
> bases:
> - ../../someBaseDir
> ```
could become
> ```
> resources:
> - someResouceFile.yaml
> - ../../someBaseDir
> - someOtherResourceFile.yaml
> ```
The `kustomized edit fix` command will do this for
you, though it will always put the bases at the
end.
As an aside, the `resources`, `generators` and
`transformers` fields now all accept the same
argument format.
> Each field's argument is a _string list_,
> where each entry is either a _resource_ (a
> relative path to a YAML file) or a
> [_kustomization_] (a path or URL
> pointing to a directory with a kustomization
> file). A kustomization directory used in this
> context is called a [_base_].
The fact that the `generators` and `transformers`
field accept [bases] and the fact that generator
and transformer configuration objects are just
normal k8s resources means that one can generate
or transform a generator or a transformer (see
[TestTransformerTransformers]).
[TestTransformerTransformers]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/internal/target/transformerplugin_test.go
### `replicas` field
The common task of patching a deployment to edit
the number of replicas is now made easier
with the new [replicas](/kustomize/api-reference/kustomization/replicas) field.
### `envs` field
An `envs` sub-field has been added to both
`configMapGenerator` and `secretGenerator`,
replacing the now deprecated (and singular)
`env` field. The new field accepts lists, just
like its sibling fields `files` and `literals`.
Optionally use `kustomize edit fix` to merge
singular `env` field into a plural field.

View File

@@ -0,0 +1,75 @@
---
title: "v3.0.0"
linkTitle: "v3.0.0"
date: 2019-07-03
description: >
Kustomize v3.0.0
---
This release is basically [v2.1.0](v2.1.0.md),
with many post-v2.1.0 bugs fixed (in about 150
commits) and a `v3` in Go package paths.
[plugin]: /docs/plugins
The major version increment to `v3` puts a new
floor on a stable API for [plugin] developers
(both _Go_ plugin developers and _exec_ plugin
developers who happen to use Go).
### Why so soon after v2.1.0?
[semantic versioning]: https://semver.org
[Go modules doc]: https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher
[versioning policy]: /kustomize/faq/versioningpolicy
We made a mistake - v2.1.0 should have been
v3.0.0. Per the [Go modules doc] (which have
improved a great deal recently), a release that's
already tagged v2 or higher should increment the
major version when performing their first Go
module-based release.
This advice applies to kustomize, since it was
already at major version 2 when it began using Go
modules to state _its own_ dependencies in v2.1.0.
But the more important reason for `v3` is a change
to the kustomize [versioning policy], forced by
the introduction of plugins.
Historically, kustomize's [versioning policy]
didn't involve Go modules and addressed _only_ the
command line tool's behavior and the fields in a
kustomization file. The underlying packages were
an implementation detail, not under semantic
versioning, because they weren't intended for
export (and should have all been under
`internal`). Thus although the v2.1.0 CLI is
backward compatible with v2.0.3, the underlying
package APIs are not.
[minimal version selection]: https://research.swtch.com/vgo-mvs
With Go modules, the `go` tool must assume that Go
packages respect [semantic versioning], so it can
perform [minimal version selection].
With the introduction of alpha plugins, kustomize
sub-packages - in particular `loader` and
`resmap` - become part of an API formally exposed
to plugin authors, and so must be semantically
versioned. This allows plugins defined in other
repositories to clarify that they depend on
kustomize v3.0.0, and not see confusing errors
arising from incompatibilities between v2.1.0 and
v2.0.3. Hence, the jump to v3.
Aside - the set of kustomize packages outside
`internal` is too large, and over time, informed
by package use, this API surface must shrink.
Such shrinkage will trigger a major version
increment.

View File

@@ -0,0 +1,132 @@
---
title: "v3.1.0"
linkTitle: "v3.1.0"
date: 2019-07-26
description: >
Kustomize v3.1.0
---
## Extended patches
Since this version, Kustomize allows applying one patch to multiple resources. This works for both Strategic Merge Patch and JSON Patch. Take a look at [patch multiple objects](https://github.com/kubernetes-sigs/kustomize/tree/master/examples/patchMultipleObjects.md).
## Improved Resource Matching
Multiple improvements have been made to allow the user to leverage "namespace"
instead/or with "name suffix/prefix" to segregate resources.
### Patch resolution improvement
The following example demonstrates how using the namespace field in the patch definition,
will let the user define two different patches against two different Deployment having the
same "deploy1" name but in different namespaces in the same Kustomize context/folder.
Unless the `namespace:` field has been specified in the kustomization.yaml, no namespace
value will be handled as Kubernetes `default` namespace.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
namespace: main
spec:
template:
spec:
containers:
- name: nginx
env:
- name: ANOTHERENV
value: TESTVALUE
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
namespace: production
spec:
template:
spec:
containers:
- name: main
env:
- name: ANOTHERENV
value: PRODVALUE
```
### Variable resolution improvement
It is possible to add namespace field to the variable declaration. In the following example,
two `Service` objects with the same `elasticsearch` name have been declared.
Specifying the namespace in the objRef of the corresponding varriables, allows Kustomize to
resovlve thoses variables.
If the namespace is not specified, Kustomize will handle it has a "wildcard" value.
Extract of kustomization.yaml:
```yaml
vars:
- name: elasticsearch-test-protocol
objref:
kind: Service
name: elasticsearch
namespace: test
apiVersion: v1
fieldref:
fieldpath: spec.ports[0].protocol
- name: elasticsearch-dev-protocol
objref:
kind: Service
name: elasticsearch
namespace: dev
apiVersion: v1
fieldref:
fieldpath: spec.ports[0].protocol
```
### Simultaneous change of names and namespaces
Kustomize is now able to deal with simultaneous changes of name and namespace.
Special attention has been paid the handling of:
- ClusterRoleBinding/RoleBinding "subjects" field,
- ValidatingWebhookConfiguration "webhooks" field.
The user should be able to use a kustomization.yaml as shown in the example bellow
even if ClusterRoleBind,RoleBinding and ValidatingWebookConfiguration are part of the
resources he needs to declare.
Extract of kustomization.yaml:
```yaml
namePrefix: pfx-
nameSuffix: -sfx
namespace: testnamespace
resources:
...
```
### Resource and Kustomize Context matching.
Kustomize is now able to support more aggregation patterns.
If for instance, the top level of kustomization.yaml, is simply
combining sub-components, (as in the following example), Kustomize has improved
resource matching capabilities. This removes some of the constraints which were
present on the utilization of prefix/suffix and namespace transformers in the
individual components.
```yaml
resources:
- ../component1
- ../component2
- ../component3
```
## Other improvements
- Image transformation has been improved. This allows the user to update the sha256 of
an image with another sha256.
- Multiple default transformer configuration entries have been added, removing the need for the
user to add them as part of the `configurations:` section of the kustomization.yaml.
- `kustomize` help command has been tidied up.

View File

@@ -0,0 +1,34 @@
---
title: "v3.2.0"
linkTitle: "v3.2.0"
date: 2019-09-17
description: >
Kustomize v3.2.0
---
## Inline Patch
Since this version, Kustomize allows inline patches in all three of `patchesStrategicMerge`, `patchesJson6902` and `patches`. Take a look at [inline patch](https://github.com/kubernetes-sigs/kustomize/tree/master/examples/examples/inlinePatch.md).
## New Subcommand
Since this version, one can create a kustomization.yaml file in a directory through a `create` subcommand.
Create a new overlay from the base ../base
```
kustomize create --resources ../base
```
Create a new kustomization detecing resources in the current directory
```
kustomize create --autodetect
```
Once can also add all resources in the current directory recursively by
```
kustomize create --autodetect --recursive
```
### New Example Generator
A new example generator of using go-getter to download resources is added. Take a look at [go-getter generator](https://github.com/kubernetes-sigs/kustomize/tree/master/examples/goGetterGeneratorPlugin.md).

View File

@@ -0,0 +1,19 @@
---
title: "v3.2.1"
linkTitle: "v3.2.1"
date: 2019-09-26
description: >
Kustomize v3.2.1
---
This is a patch release, with no new features from 3.2.0.
It reflects a change in dependence.
The kustomize binary is now built as a client, with no special
consideration, of the set of public packages represented by the Go
module at [https://github.com/kubernetes-sigs/kustomize].
kustomize the binary is now a client of the kustomize API
represented by the public package surface presented by
`https://github.com/kubernetes-sigs/kustomize/v{whatever}`

View File

@@ -0,0 +1,121 @@
---
title: "v3.3.0"
linkTitle: "v3.3.0"
date: 2019-10-24
description: >
Kustomize v3.3.0
---
[versioning policy documentation]: /site/content/en/faq/versioningPolicy.md
[release process documentation]: /releasing
## Summary of changes
### First release of the Go API-only module.
Many of the PRs since the last vrelease were
around restructuring the _sigs.k8s.io/kustomize_
repository into three Go modules instead of just one.
The reasons for this are detailed in the [versioning
policy documentation], and what it means for releasing
is explained in the [release process documentation].
The tl;dr is that the top level module
`sigs.k8s.io/kustomize` now defines the kustomize Go
API, and the _kustomize_ CLI sits below it in an
independent module `sigs.k8s.io/kustomize/kustomize`.
The modules release independently, though in practice a
new release of the kustomize Go API will likely be
followed quickly by a new release of the `kustomize`
executable.
This is a necessary step to creating a much smaller
kustomize Go API surface that has some hope of
conforming to semantic versioning and being of some use
to clients.
The kustomize CLI will see the same kustomize Go API as
any other client.
The new semver-able API will begin with `v4.0.0` (not
yet released) and be a clean break with `v3` etc.
### Change log since v3.2.0
```
3c9d828f - Have kustomize CLI depend on kustomize Go API v3.3.0 (Jeffrey Regan)
5d800f0b - Merge pull request #1595 from monopole/threeReleases (Jeff Regan)
4eb2d5bc - Three builders. (Jeffrey Regan)
988af1ff - Update README.md (Jeff Regan)
1617183e - Merge pull request #1590 from monopole/releaseProcessUpdate (Kubernetes Prow Robot)
ee727464 - update release process doc (jregan)
c9e7dc3b - Merge pull request #1589 from monopole/moreTestsAroundKustFileName (Jeff Regan)
07e0e46a - improve tests for alternative kustomization file names (Jeffrey Regan)
404d2d63 - Merge pull request #1587 from monopole/reducePgmconfig (Jeff Regan)
baa0296a - Reduce size of pgmconfig package (Jeffrey Regan)
0f665ac1 - Merge pull request #1544 from ptux/add-transformer-href (Jeff Regan)
14b0a650 - Merge pull request #1581 from monopole/refactorFs (Jeff Regan)
2d58f8b8 - Break the dep between fs and pgmconfig. (Jeffrey Regan)
9a43ca53 - Merge pull request #1578 from nlamirault/fix/build-plugins-doc (Jeff Regan)
5372fc6f - Merge pull request #1579 from monopole/fsPackageCleanup (Jeff Regan)
86bc3440 - Merge pull request #1513 from nimohunter/fix_empty_list_item (Kubernetes Prow Robot)
a014f7d4 - Merge pull request #1561 from beautytiger/dev-190925 (Jeff Regan)
9a94bcb8 - Improve fs package and doc in prep to officially go public (Jeffrey Regan)
07634ef0 - Merge pull request #1575 from monopole/versioning (Jeff Regan)
995f88d6 - Update versioning notes. (jregan)
334a6467 - Fix: documentation link for plugins (Nicolas Lamirault)
08963ba5 - improve test code coverage in transformers (Guangming Wang)
326fb689 - Merge pull request #1570 from bzub/1234-go_plugin_doc (Jeff Regan)
970ce67c - Update goPluginCaveats.md (Jeff Regan)
98d18930 - Update INSTALL.md (Jeff Regan)
d89b448c - Fix git tag recovery in cloud build. (Jeff Regan)
17bf9d32 - Update releasing README. (Jeff Regan)
a99aff1d - Merge pull request #1571 from monopole/updateCloudBuildProcess (Kubernetes Prow Robot)
a694ac7b - Update cloud build process for kustomize. (Jeffrey Regan)
b5b11ef6 - Fix compile kustomize example. (bzub)
fa1af6f5 - Merge pull request #1473 from richardmarshall/execpluginhash (Jeff Regan)
9288dec0 - Fix failing BashedConfigMapTest (Jeff Regan)
1a45dd0b - Merge pull request #1566 from monopole/releaseNotes3.2.1 (Kubernetes Prow Robot)
592c5acf - docs: Exec plugin generator options (Richard Marshall)
ac9424fa - tests: Add unit tests for update resource options (Richard Marshall)
79fbe7c4 - Support resource generator options in exec plugins (Richard Marshall)
f69d526f - v3.2.1 release notes (Jeff Regan)
07a95a60 - Merge pull request #1565 from monopole/tweakBinaryDepsBeforeTagging (Jeff Regan)
032b3857 - Pin the kustomize binary's dependence on kustomize libs. (jregan)
81062959 - Merge pull request #1564 from monopole/moveKustomizeBinaryToOwnModule (Kubernetes Prow Robot)
b82a8fd3 - Move the kustomize binary to its own module. (Jeffrey Regan)
2d0c22d6 - Merge pull request #1562 from keleustes/tools (Kubernetes Prow Robot)
aa342def - Pin tool versions using go modules (Ian Howell)
10786ec0 - Merge pull request #1554 from keleustes/readme (Kubernetes Prow Robot)
7c705687 - Update README.md to include Kubernetes 1.16 (Jerome Brette)
e8933d97 - Merge pull request #1560 from monopole/precommitTuneup (Jeff Regan)
9d7b6544 - Make pre-commit more portable and less tricky. (jregan)
7a0946a9 - Merge pull request #1558 from monopole/dependOnNewPluginatorModule (Jeff Regan)
def4f045 - Depend on new pluginator location. (Jeffrey Regan)
2f2408f1 - Merge pull request #1559 from monopole/compressCopyright (Jeff Regan)
3b9bcc48 - Compress copyright in the commands package. (Jeffrey Regan)
d0429ff4 - Merge pull request #1557 from monopole/pluginatorModule (Jeff Regan)
33deefc3 - Copy pluginator to its own module. (Jeffrey Regan)
9b3de82b - Merge pull request #1506 from Liujingfang1/release (Jeff Regan)
d217074f - Merge pull request #1550 from keleustes/apiversion (Kubernetes Prow Robot)
1d90ba7c - Fix typo in apiVersion yaml declaration (Jerome Brette)
eeeb4c36 - Merge pull request #1547 from keleustes/extensions (Kubernetes Prow Robot)
b1faa989 - Update Ingress apiVersion to networking.k8s.io/v1beta1 (Jerome Brette)
d8250c9e - move test case (nimohunter)
c9500466 - add transformer href (Wang(わん))
0c32691e - Merge pull request #1537 from jaypipes/gomod-install-note (Kubernetes Prow Robot)
88b1d627 - Merge pull request #1541 from rtnpro/patch-1 (Jeff Regan)
aec82066 - Update INSTALL.md (Jeff Regan)
20c2b53a - Merge pull request #1542 from monopole/tweakFilePathsInTest (Jeff Regan)
274b5c3b - Tweak file path handling and logging in test. (Jeffrey Regan)
b1fdaa23 - Fix typo in transformerconfigs README (Ratnadeep Debnath)
b5d5e70b - empty list or map item return error (nimohunter)
2e829853 - empty list or map item return error (nimohunter)
55941f57 - add note about GO111MODULE for source install (Jay Pipes)
9e226001 - empty list or map item return error (nimohunter)
77b63f96 - add release note for v3.2.0 (jingfangliu)
```

View File

@@ -0,0 +1,10 @@
---
title: "Contributing"
linkTitle: "Contributing"
type: docs
menu:
main:
weight: 99
---
Follow are resources for Kustomize contributors.

View File

@@ -0,0 +1,57 @@
---
title: "Filing Bugs"
linkTitle: "Filing Bugs"
type: docs
weight: 10
description: >
How to file bugs against Kustomize
---
[krusty package]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/krusty
[reusable custom transformer test]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/krusty/customconfigreusable_test.go
File issues as desired, but if you've found a problem
with how `kustomize build` works, please report
* the output of `kustomize version`,
* the input (the content of `kustomization.yaml`
and any files it refers to),
* the expected YAML output.
## If you have `go` installed
kustomize has a simple test harness in the [krusty
package] for specifying a kustomization's input and the
expected output.
Copy one of those tests, e.g. this [reusable custom
transformer test], to a new test file in the
krusty package.
Insert the inputs you want to use, and run it as
you'd run the reusable custom transformer test:
```
(cd api; go test -run TestReusableCustomTransformers ./krusty)
```
The output will demonstrate the bug or missing feature.
Record this output in the test file in a call to
`AssertActualEqualsExpected`, per all the other tests
in the [krusty package]. This makes the test pass,
albeit with output demonstrating behavior you
presumably want to change.
Send the new test in a PR, along with commentary (in
the test) on what you'd prefer to see.
The person who fixes the bug then has a clear bug
reproduction and a test to modify when the bug is
fixed.
Any bug fix first requires a test demonstrating the bug
(so we have permanent regression coverage), so if the
_bug reporter_ does this, it saves time and avoids
misunderstandings.

View File

@@ -0,0 +1,22 @@
---
title: "Community Engagment"
linkTitle: "Community"
type: docs
weight: 20
description: >
Joining SIG-CLI and the Kubernetes community
---
[CLI special interest group]: https://github.com/kubernetes/community/tree/master/sig-cli#cli-special-interest-group
[contributor roles]: https://github.com/kubernetes/community/blob/master/community-membership.md#community-membership
[mailing list]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli
[bi-weekly meetings]: https://docs.google.com/document/d/1r0YElcXt6G5mOWxwZiXgGu_X6he3F--wKwg-9UBc29I/edit?usp=sharing
Kustomize is a sub project of the Kubernetes [CLI special interest group] and follows the Kubernetes
project [contributor roles].
If you are interested in contributing towards Kustomize or getting more involved with the community,
reach out on the [mailing list] or join one of the [bi-weekly meetings] (alternating Wednesdays at
9:00am Pacific Time).

View File

@@ -0,0 +1,62 @@
---
title: "Writing Docs"
linkTitle: "Writing Docs"
type: docs
weight: 30
description: >
How to make Kustomize docs contributions
---
Kustomize uses [Docsy](https://www.docsy.dev) for the site, and was
forked from the [docsy-example](https://github.com/google/docsy-example)
## Prerequisites
- [Install hugo](https://gohugo.io/getting-started/installing/#fetch-from-github)
- Clone kustomize
- `git clone git@github.com:kubernetes-sigs/kustomize && cd kustomize/`
## Development
The docs are in the `site` directory
```shell script
cd site/
```
To view the docs run
```shell script
hugo serve
```
```shell script
...
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/kustomize/ (bind address 127.0.0.1)
```
and visit the URL that is printed
## Publishing
The `site` content is compiled by Hugo into the `docs` folder using the hugo command:
```shell script
hugo
```
```shell script
| EN
-------------------+-----
Pages | 99
Paginator pages | 0
Non-page files | 0
Static files | 47
Processed images | 0
Aliases | 2
Sitemaps | 1
Cleaned | 0
```
Add the `site` and `docs` folders to a commit, and create a PR.

View File

@@ -0,0 +1,57 @@
---
title: "Writing Code"
linkTitle: "Writing Code"
type: docs
weight: 40
description: >
How Kustomize is implemented
---
Call stack when running `kustomize build`, with links to code.
## Run build
* [RunBuild](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/kustomize/internal/commands/build/build.go#L121)
* [MakeKustomizer](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/krusty/kustomizer.go#L32)
* [Run](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/krusty/kustomizer.go#L47): performs a kustomization. It uses its internal filesystem reference to read the file at the given path argument, interpret it as a kustomization.yaml file, perform the kustomization it represents, and return the resulting resources.
* Create factories
* [tranformer.NewFactoryImpl](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/k8sdeps/transformer/factory.go#L17)
* [resmap.NewFactory](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/resmap/factory.go#L21)
* [resource.NewFactory](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/resource/factory.go#L23)
* [kustruct.NewKunstructuredFactoryImpl](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/k8sdeps/kunstruct/factory.go#L28)
* [loader.NewLoader](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/loader/loader.go#L19)
* [validator.NewKustValidator](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/k8sdeps/validator/validators.go#L23)
* [NewKustTarget](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L38)
* [Load](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L54)
* [MakeCustomizeResMap](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L109): details in next section
* [emitResources](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/kustomize/internal/commands/build/build.go#L143)
## Make resource map
* [makeCustomizeResMap](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L117)
* [AccumulateTarget](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L196): returns a new ResAccumulator, holding customized resources and the data/rules used to do so. The name back references and vars are not yet fixed.
* [accummulateResources](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L302): fills the given resourceAccumulator with resources read from the given list of paths.
* Merge config from builtin and CRDs
* [runGenerators](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L239)
* [configureBuiltinGenerators](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget_configplugin.go#L28)
* ConfigMapGenerator
* SecretGenerator
* [configureExternalGenerators]()
* Iterate all generators
* [runTransfomers](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L274)
* [configureBuiltinTransformers](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget_configplugin.go#L44)
* PatchStrategicMergeTransformer
* PatchTransformer
* NamespaceTransformer
* PrefixSuffixTransformer
* LabelTransformer
* AnnotationsTransformer
* PatchJson6902Transformer
* ReplicaCountTransformer
* ImageTagTransformer
* [configureExternalTransformers](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L291)
* [MergeVars](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/accumulator/resaccumulator.go#L64)
* The following steps must be done last, not as part of the recursion implicit in AccumulateTarget.
* [addHashesToNames](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/target/kusttarget.go#L153)
* [FixBackReferences](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/accumulator/resaccumulator.go#L160): Given that names have changed (prefixs/suffixes added), fix all the back references to those names.
* [ResolveVars](https://github.com/kubernetes-sigs/kustomize/blob/c7d78970fb86782dbdded3a93944b774f826071f/api/internal/accumulator/resaccumulator.go#L141)

View File

@@ -0,0 +1,46 @@
---
title: "MacOS Dev Guide"
linkTitle: "MacOS Dev Guide"
type: docs
weight: 50
description: >
How to develop on MacOS
---
First install the tools to build and run tests
### Install go 1.13
[Instructions](https://golang.org/doc/install)
Add `go` to your PATH
### Install kubeval
[Instructions](https://github.com/instrumenta/kubeval)
```sh
go get github.com/instrumenta/kubeval
```
Add `kubeval` to your PATH
### Install gnu tools
[Instructions](https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/)
```sh
brew install coreutils wget gnu-sed tree
```
Add the new tools to your PATH
## Make everything
Verify your install by running `make`:
```sh
make
```
Be default, this runs all tests needed to qualify a pull request.

View File

@@ -0,0 +1,61 @@
---
title: "Windows Dev Guide"
linkTitle: "Windows Dev Guide"
type: docs
weight: 60
description: >
How to develop on Windows
---
This is the PowerShell script to run all go tests for Kustomize on a windows based platform which mimics /build/pre-commit.sh
## Pre-Reqs:
- PowerShell installed
- PowerShell Core is supported
- go installed
- golangci-lint installed
- mdrip installed
This script should output to the current console and return an exit code if all tests are successful(0) or any failed(1).
### If you are tryin to run these tests locally you can follow these instructions.
Assume:
- Running a stock Windows 10 system
- Local Admin rights.
- You can open [PowerShell as administrator](http://lmgtfy.com/?iie=1&q=How+to+open+powershell+as+administrator)
- You should be knowledgeable enough to pull source for packages into your GO ```src``` directory
- Yes, this means you also need to know a bit about **git** usually
#### Step 1 - Install Go
- [Install Go](https://golang.org/dl/) - please use the msi
- If you use chocolatey - it's using the zip not msi and assumptions on where go is located are made for you.
#### Step 2 - Install Go Packages
- Open new PowerShell Administrative window
- Install golangci-lint
- ```go get -u github.com/golangci/golangci-lint/cmd/golangci-lint```
- Install mdrip
- ```go get github.com/monopole/mdrip```
You should now be able to issue these commands and see comparable responses
```
C:\...> golangci-lint --help
Smart, fast linters runner. Run it in cloud for every GitHub pull request on https://golangci.com
...
C:\...> mdrip --help
Usage: C:\_go\bin\mdrip.exe {fileName}...
...
```
#### Step 3 - Get Source and Test
- In your GoRoot src
- ```Example: C:\_go\src```
- Navigate to the Kustomize `travis` directory
- ```Example: C:\_go\src\sigs.k8s.io\kustomize\travis```
- Now Execute:
- ```.\Invoke-PreCommit.ps1```
This should run all pre-commit tests thus defined in the script.

View File

@@ -0,0 +1,65 @@
---
title: "FAQ"
linkTitle: "FAQ"
type: docs
menu:
main:
weight: 70
---
## security: file 'foo' is not in or below 'bar'
v2.0 added a security check that prevents
kustomizations from reading files outside their own
directory root.
This was meant to help protect the person inclined to
download kustomization directories from the web and use
them without inspection to control their production
cluster
(see [#693](https://github.com/kubernetes-sigs/kustomize/issues/693),
[#700](https://github.com/kubernetes-sigs/kustomize/pull/700),
[#995](https://github.com/kubernetes-sigs/kustomize/pull/995) and
[#998](https://github.com/kubernetes-sigs/kustomize/pull/998))
Resources (including configmap and secret generators)
can _still be shared_ via the recommended best practice
of placing them in a directory with their own
kustomization file, and referring to this directory as a
[`base`](/kustomize/api-reference/glossary#base) from any kustomization that
wants to use it. This encourages modularity and
relocatability.
To disable this, use v3, and the `load_restrictor` flag:
```
kustomize build --load_restrictor none $target
```
## Some field is not transformed by kustomize
Example: [#1319](https://github.com/kubernetes-sigs/kustomize/issues/1319), [#1322](https://github.com/kubernetes-sigs/kustomize/issues/1322), [#1347](https://github.com/kubernetes-sigs/kustomize/issues/1347) and etc.
The fields transformed by kustomize is configured explicitly in [defaultconfig](https://github.com/kubernetes-sigs/kustomize/tree/master/api/konfig/builtinpluginconsts/defaultconfig.go). The configuration itself can be customized by including `configurations` in `kustomization.yaml`, e.g.
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configurations:
- kustomizeconfig.yaml
```
The configuration directive allows customization of the following transformers:
```yaml
commonAnnotations: []
commonLabels: []
nameprefix: []
namespace: []
varreference: []
namereference: []
images: []
replicas: []
```
To persist the changes to default configuration, submit a PR like [#1338](https://github.com/kubernetes-sigs/kustomize/pull/1338), [#1348](https://github.com/kubernetes-sigs/kustomize/pull/1348) and etc.

View File

@@ -0,0 +1,163 @@
---
title: "Eschewed Features"
linkTitle: "Eschewed Features"
type: docs
weight: 99
description: >
Eschewed Features
---
The maintainers established this list to
place bounds on the kustomize feature
set. The bounds can be changed with
a consensus on the risks.
For a bigger picture about why kustomize
does some things and not others, see the
glossary entry for [DAM].
## Removal directives
`kustomize` supports configurations that can be reasoned about as
_compositions_ or _mixins_ - concepts that are widely accepted as
a best practice in various programming languages.
To this end, `kustomize` offers various _addition_ directives.
One may add labels, annotations, patches, resources, bases, etc.
Corresponding _removal_ directives are not offered.
Removal semantics would introduce many possibilities for
inconsistency, and the need to add code to detect, report and
reject it. It would also allow, and possibly encourage,
unnecessarily complex configuration layouts.
When faced with a situation where removal is desirable, it's
always possible to remove things from a base like labels and
annotations, and/or split multi-resource manifests into individual
resource files - then add things back as desired via the
[kustomization].
If the underlying base is outside of one's control, an [OTS
workflow] is the recommended best practice. Fork the base, remove
what you don't want and commit it to your private fork, then use
kustomize on your fork. As often as desired, use _git rebase_ to
capture improvements from the upstream base.
## Unstructured edits
_Structured edits_ are changes controlled by
knowledge of the k8s API, and YAML or JSON syntax.
Most edits performed by kustomize can be expressed as
[JSON patches] or [SMP patches].
Those can be verbose, so common patches,
like adding labels or annotatations, get dedicated
transformer plugins - `LabelTransformer`,
`AnnotationsTransformer`, etc.
These accept relatively simple YAML configuration
allowing easy targeting of any number of resources.
Another class of edits take data from one specific
object's field and use it in another (e.g. a service
object's name found and copied into a container's
command line). These reflection-style edits
are called _replacements_.
The above edits create valid output given valid input,
and can provide syntactically and semantically
informed error messages if inputs are invalid.
_Unstructured edits_, edits that don't limit
themselves to a syntax or object structure,
come in many forms. A common one in the
configuration domain is the template or
parameterization approach.
In this technique, the source
material is sprinkled with strings of the
form `${VAR}`. A scanner replaces them
with a value taken from a map using `VAR`
as the map key. It's trivial to implement.
kustomize eschews parameterization, because
- The source yaml gets polluted with `$VARs`
and can no longed be applied as is
to the cluster (it _must_ be processed).
- The source material is no longer structured,
making it unusable with any YAML processor.
It's no longer _data_, it's now logic that
must be compiled.
- Errors in the output are disconnected from
the edit that caused it.
- The input becomes [unintelligible] as the project
scales in any number of dimensions (resource
count, cluster count, environment count, etc.)
Kustomizations are meant to be sharable and stackable.
Imagine tracing down a problem rooted in a
clever set of stacked regexp replacements
performed by various overlays on some remote base.
We've used such systems, and never want to again.
Other tools (sed, jinja, erb, envsubst, kafka, helm, ksonnet,
etc.) provide varying degrees of unstructured editting
and/or embedded languages, and can be used instead
of, or in a pipe with, kustomize. If you want to
go all-in on _configuration as a language_, consider [cue].
kustomize is going to stick to YAML in / YAML out.
## Build-time side effects from CLI args or env variables
`kustomize` supports the best practice of storing one's
entire configuration in a version control system.
Changing `kustomize build` configuration output as a result
of additional arguments or flags to `build`, or by
consulting shell environment variable values in `build`
code, would frustrate that goal.
`kustomize` insteads offers [kustomization] file `edit`
commands. Like any shell command, they can accept
environment variable arguments.
For example, to set the tag used on an image to match an
environment variable, run
```
kustomize edit set image nginx:$MY_NGINX_VERSION
```
as part of some encapsulating work flow executed before
`kustomize build`.
## Globs in kustomization files
`kustomize` supports the best practice of storing one's
entire configuration in a version control system.
Globbing the local file system for files not explicitly
declared in the [kustomization] file at `kustomize build` time
would violate that goal.
Allowing globbing in a kustomization file would also introduce
the same problems as allowing globbing in [java import]
declarations or BUILD/Makefile dependency rules.
`kustomize` will instead provide kustomization file editting
commands that accept globbed arguments, expand them at _edit
time_ relative to the local file system, and store the resulting
explicit names into the kustomization file.
[base]: /kustomize/api-reference/glossary#base
[DAM]: /kustomize/api-reference/glossary#declarative-application-management
[java import]: https://www.codebyamir.com/blog/pitfalls-java-import-wildcards
[JSON patches]: /kustomize/api-reference/glossary#patchjson6902
[kustomization]: /kustomize/api-reference/glossary#kustomization
[OTS workflow]: /kustomize/api-reference/glossary#off-the-shelf-configuration
[SMP patches]: /kustomize/api-reference/glossary#patchstrategicmerge
[parameterization pitfall discussion]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/declarative-application-management.md#parameterization-pitfalls
[unintelligible]: https://github.com/helm/charts/blob/e002378c13e91bef4a3b0ba718c191ec791ce3f9/stable/artifactory/templates/artifactory-deployment.yaml
[cue]: https://cuelang.org/

View File

@@ -0,0 +1,272 @@
---
title: "Versioning Policy"
linkTitle: "Versioning Policy"
weight: 99
type: docs
---
Running `kustomize` means one is running a
particular version of a program (a CLI), using a
particular version of underlying packages (a Go
API), and reading a particular version of a
[kustomization] file.
> If you're having trouble with `go get`, please
> read [Go API Versioning](#go-api-versioning)
> and be patient.
## CLI Program Versioning
The command `kustomize version` prints a three
field version tag (e.g. `v3.0.0`) that aspires to
[semantic versioning].
This notion of semver applies only to the CLI;
the command names, their arguments and their flags.
The major version changes when some backward
incompatibility appears in how the commands
behave.
### Installation
See the [installation docs](INSTALL.md).
## Go API Versioning
The public methods in the public packages
of module `sigs.k8s.io/kustomize/api` constitute
the _kustomize Go API_.
#### Version sigs.k8s.io/kustomize/v3 and earlier
[import path]: https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher
In `kustomize/v3` (and preceding major versions), the
kustomize program and the API live the same Go
module at `sigs.k8s.io/kustomize`, at [import path]
`sigs.k8s.io/kustomize/v3`.
This has been fine for the CLI, but it presents a
problem for the Go API.
[minimal version selection]: https://research.swtch.com/vgo-mvs
The process around Go modules, in particular the
notion of [minimal version selection], demands
that the module respect semver.
Almost all the code in module
`sigs.k8s.io/kustomize/v3` is exposed (not in a
directory named `internal`). Even a minor
refactor changing a method name or argument type
in some deeply buried (but still public) method is
a backward incompatible change. As a result, Go
API semver hasn't been followed. This was a mistake.
Some options are
- continue to ignore Go API semver and stick to
CLI semver (eliminating the usefullness of
minimal version selection),
- obey semver, and increment the module's major
version number with every release (drastically
reducing the usefullness of minimal version
selection - since virtually all releases will
be major),
- slow down change in the huge API in favor of
stability, yet somehow continue to deliver
features,
- drastically reduce the API surface, stabilize on
semver there, and refactor as needed inside
`internal`.
The last option seems the most appealing.
#### The first stable API version is coming
The first stable API version will launch
as the Go module
```
sigs.k8s.io/kustomize/api
```
The _kustomize_ program itself (`main.go`
and CLI specific code) will have moved out of
`sigs.k8s.io/kustomize` and into the new module
`sigs.k8s.io/kustomize/kustomize`. This is a
submodule in the same repo, and it will retain its
current notion of semver (e.g. a backward
incompatible change in command behavior will
trigger a major version bump). This module will
not export packages; it's just home to a `main`
package.
The `sigs.k8s.io/kustomize/api` module will
obey semver with a sustainable public
surface, informed by current usage. Clients
should import packages from this module, i.e.
from import paths prefixed by
`sigs.k8s.io/kustomize/api/` at first,
and later by `sigs.k8s.io/kustomize/api/v2/`.
The kustomize binary
itself is an API client requiring this module.
The clients and API will evolve independently.
## Kustomization File Versioning
The kustomization file is a struct that is part of
the kustomize Go API (the `sigs.k8s.io/kustomize`
module), but it also evolves as a k8s API object -
it has an `apiVersion` field containing its
own version number.
### Field Change Policy
- A field's meaning cannot be changed.
- A field may be deprecated, then removed.
- Deprecation means triggering a _minor_ (semver)
version bump in the kustomize Go API, and
defining a migration path in a non-fatal error
message.
- Removal means triggering a _major_ (semver)
version bump in the kustomize Go API, and fatal
error if field encountered (as with any unknown
field). Likewise a change in `apiVersion`.
### The `edit fix` Command
This `kustomize` command reads a Kustomization
file, converts deprecated fields to new
fields, and writes it out again in the latest
format.
This is a type version upgrade mechanism that
works within _major_ API revisions. There is no
downgrade capability, as there's no use case for
it (see discussion below).
### Examples
With the 2.0.0 release, there were three field
removals:
- `imageTag` was deprecated when `images` was
introduced, because the latter offers more
general features for image data manipulation.
`imageTag` was removed in v2.0.0.
- `patches` was deprecated and replaced by
`patchesStrategicMerge` when `patchesJson6902`
was introduced, to make a clearer
distinction between patch specification formats.
`patches` was removed in v2.0.0.
- `secretGenerator/commands` was removed
due to security concerns in v2.0.0
with no deprecation period.
The `edit fix` command in a v2.0.x binary
will no longer recognize these fields.
## Relationship to the k8s API
### Review of k8s API versioning
The k8s API has specific [conventions] and a
process for making [changes].
The presence of an `apiVersion` field in a k8s
native type signals:
- its reliability level (alpha vs beta vs
generally available),
- the existence of code to provide default values
to fields not present in a serialization,
- the existence of code to provide both forward
and backward conversion between different
versions of types.
The k8s API promises a lossless _conversion_
between versions over a specific range. This
means that a recent client can write an object
bearing the newest possible value for its version,
the server will accept it and store it in
"versionless" JSON form in storage, and can
convert it to a range of older versions should
an older client request data.
For native k8s types, this all requires writing Go
code in the kubernetes core repo, to provide
defaulting and conversions.
For CRDs, there's a [proposal] on how to manage
versioning (e.g. a remote service can offer type
defaulting and conversions).
### Differences
- A k8s API server is able to go _forward_ and
_backward_ in versioning, to work with older
clients, over [some range].
- The `kustomize edit fix` command only moves
_forward_ within a _major_ API
version.
At the time of writing, the YAML in a
kustomization file does not represent a [k8s API]
object, and the kustomize command and associated
library is neither a server of, nor a client to,
the k8s API.
### Additional Kustomization file rules
In addition to the [field change policy] described
above, kustomization files conform to
the following rules.
#### Eschew classic k8s fields
Field names with dedicated meaning in k8s
(`metadata`, `spec`, `status`, etc.) aren't used.
This is enforced via code review.
#### Default values for k8s `kind` and `apiVersion`
In `v3` or below, the two [special] k8s
resource fields [`kind`] and [`apiVersion`] may
be omitted from the kustomization file.
If either field is present, they both must be.
If present, the value of `kind` must be:
> ```
> kind: Kustomization
> ```
If missing, the value of `apiVersion` defaults to
> ```
> apiVersion: kustomize.config.k8s.io/v1beta1
> ```
[field change policy]: #field-change-policy
[some range]: https://kubernetes.io/docs/reference/using-api/deprecation-policy
[proposal]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/customresources-versioning.md
[beta-level rules]: https://github.com/kubernetes/community/blob/master/contributors/devel/api_changes.md#alpha-beta-and-stable-versions
[changes]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api_changes.md
[adapt]: /types/kustomization.go#L166
[special]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#resources
[k8s API]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md
[conventions]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
[release process]: https://github.com/kubernetes-sigs/kustomize/tree/master/releasing/README.md
[kustomization]: /kustomize/api-reference/glossary#kustomization
[`kind`]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds
[`apiVersion`]: https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning
[semantic versioning]: https://semver.org

View File

@@ -0,0 +1,11 @@
---
title: "Guides"
linkTitle: "Guides"
type: docs
weight: 2
menu:
main:
weight: 20
description: >
Reference for Kustomize CLI commands
---

View File

@@ -0,0 +1,81 @@
---
title: "Bespoke Application"
linkTitle: "Bespoke Application"
type: docs
weight: 1
description: >
Workflow for bespoke applications
---
In this workflow, all configuration (resource YAML) files are owned by the user.
No content is incorporated from version control repositories owned by others.
![bespoke config workflow image][workflowBespoke]
#### 1) create a directory in version control
Speculate some overall cluster application called _ldap_;
we want to keep its configuration in its own repo.
> ```
> git init ~/ldap
> ```
#### 2) create a [base]
> ```
> mkdir -p ~/ldap/base
> ```
In this directory, create and commit a [kustomization]
file and a set of [resources].
#### 3) create [overlays]
> ```
> mkdir -p ~/ldap/overlays/staging
> mkdir -p ~/ldap/overlays/production
> ```
Each of these directories needs a [kustomization]
file and one or more [patches].
The _staging_ directory might get a patch
that turns on an experiment flag in a configmap.
The _production_ directory might get a patch
that increases the replica count in a deployment
specified in the base.
#### 4) bring up [variants]
Run kustomize, and pipe the output to [apply].
> ```
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
> ```
You can also use [kubectl-v1.14.0] to apply your [variants].
> ```
> kubectl apply -k ~/ldap/overlays/staging
> kubectl apply -k ~/ldap/overlays/production
> ```
[OTS]: /kustomize/api-reference/glossary#off-the-shelf-configuration
[apply]: /kustomize/api-reference/glossary#apply
[applying]: /kustomize/api-reference/glossary#apply
[base]: /kustomize/api-reference/glossary#base
[fork]: https://guides.github.com/activities/forking/
[variants]: /kustomize/api-reference/glossary#variant
[kustomization]: /kustomize/api-reference/glossary#kustomization
[off-the-shelf]: /kustomize/api-reference/glossary#off-the-shelf-configuration
[overlays]: /kustomize/api-reference/glossary#overlay
[patch]: /kustomize/api-reference/glossary#patch
[patches]: /kustomize/api-reference/glossary#patch
[rebase]: https://git-scm.com/docs/git-rebase
[resources]: /kustomize/api-reference/glossary#resource
[workflowBespoke]: /kustomize/images/workflowBespoke.jpg
[workflowOts]: /kustomize/images/workflowOts.jpg
[kubectl-v1.14.0]:https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement/

View File

@@ -0,0 +1,83 @@
---
title: "Off The Shelf Application"
linkTitle: "Off The Shelf Application"
type: docs
weight: 2
description: >
Workflow for off the shelf applications
---
In this workflow, all files are owned by the user and maintained in a repository under their control, but
they are based on an [off-the-shelf] configuration that is periodically consulted for updates.
![off-the-shelf config workflow image][workflowOts]
#### 1) find and [fork] an [OTS] config
#### 2) clone it as your [base]
The [base] directory is maintained in a repo whose upstream is an [OTS] configuration, in this case
some user's `ldap` repo:
> ```
> mkdir ~/ldap
> git clone https://github.com/$USER/ldap ~/ldap/base
> cd ~/ldap/base
> git remote add upstream git@github.com:$USER/ldap
> ```
#### 3) create [overlays]
As in the bespoke case above, create and populate an _overlays_ directory.
The [overlays] are siblings to each other and to the [base] they depend on.
> ```
> mkdir -p ~/ldap/overlays/staging
> mkdir -p ~/ldap/overlays/production
> ```
The user can maintain the `overlays` directory in a
distinct repository.
#### 4) bring up [variants]
> ```
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
> ```
You can also use [kubectl-v1.14.0] to apply your [variants].
> ```
> kubectl apply -k ~/ldap/overlays/staging
> kubectl apply -k ~/ldap/overlays/production
> ```
#### 5) (optionally) capture changes from upstream
The user can periodically [rebase] their [base] to
capture changes made in the upstream repository.
> ```
> cd ~/ldap/base
> git fetch upstream
> git rebase upstream/master
> ```
[OTS]: /kustomize/api-reference/glossary#off-the-shelf-configuration
[apply]: /kustomize/api-reference/glossary#apply
[applying]: /kustomize/api-reference/glossary#apply
[base]: /kustomize/api-reference/glossary#base
[fork]: https://guides.github.com/activities/forking/
[variants]: /kustomize/api-reference/glossary#variant
[kustomization]: /kustomize/api-reference/glossary#kustomization
[off-the-shelf]: /kustomize/api-reference/glossary#off-the-shelf-configuration
[overlays]: /kustomize/api-reference/glossary#overlay
[patch]: /kustomize/api-reference/glossary#patch
[patches]: /kustomize/api-reference/glossary#patch
[rebase]: https://git-scm.com/docs/git-rebase
[resources]: /kustomize/api-reference/glossary#resource
[workflowBespoke]: /kustomize/images/workflowBespoke.jpg
[workflowOts]: /kustomize/images/workflowOts.jpg
[kubectl-v1.14.0]:https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement/

View File

@@ -0,0 +1,375 @@
---
title: "Kustomize Plugins"
linkTitle: "Kustomize Plugins"
type: docs
weight: 98
description: >
Kustomize plugins guide
---
Kustomize offers a plugin framework allowing people to write their own resource _generators_
and _transformers_.
[generator options]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/generatorOptions.md
[transformer configs]: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/transformerconfigs
Write a plugin when changing [generator options]
or [transformer configs] doesn't meet your needs.
[12-factor]: https://12factor.net
* A _generator_ plugin could be a helm chart
inflator, or a plugin that emits all the
components (deployment, service, scaler,
ingress, etc.) needed by someone's [12-factor]
application, based on a smaller number of free
variables.
* A _transformer_ plugin might perform special
container command line edits, or any other
transformation beyond those provided by the
builtin (`namePrefix`, `commonLabels`, etc.)
transformers.
## Specification in `kustomization.yaml`
Start by adding a `generators` and/or `transformers`
field to your kustomization.
Each field accepts a string list:
> ```
> generators:
> - relative/path/to/some/file.yaml
> - relative/path/to/some/kustomization
> - /absolute/path/to/some/kustomization
> - https://github.com/org/repo/some/kustomization
>
> transformers:
> - {as above}
> ```
The value of each entry in a `generators` or
`transformers` list must be a relative path to a
YAML file, or a path or URL to a [kustomization].
This is the same format as demanded by the
`resources` field.
[kustomization]: /kustomize/api-reference/glossary#kustomization
YAML files are read from disk directly. Paths or
URLs leading to kustomizations trigger an
in-process kustomization run. Each of the
resulting objects is now further interpreted by
kustomize as a _plugin configuration_ object.
## Configuration
A kustomization file could have the following lines:
```
generators:
- chartInflator.yaml
```
Given this, the kustomization process would expect
to find a file called `chartInflator.yaml` in the
kustomization [root](/kustomize/api-reference/glossary#kustomization-root).
This is the plugin's configuration file;
it contains a YAML configuration object.
The file `chartInflator.yaml` could contain:
```
apiVersion: someteam.example.com/v1
kind: ChartInflator
metadata:
name: notImportantHere
chartName: minecraft
```
__The `apiVersion` and `kind` fields are
used to locate the plugin.__
[k8s object]: /kustomize/api-reference/glossary#kubernetes-style-object
Thus, these fields are required. They are also
required because a kustomize plugin configuration
object is also a [k8s object].
To get the plugin ready to generate or transform,
it is given the entire contents of the
configuration file.
[NameTransformer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin/prefixsuffixtransformer/PrefixSuffixTransformer_test.go
[ChartInflator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/chartinflator/ChartInflator_test.go
[plugins]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin
For more examples of plugin configuration YAML,
browse the unit tests below the [plugins] root,
e.g. the tests for [ChartInflator] or
[NameTransformer].
## Placement
Each plugin gets its own dedicated directory named
[`XDG_CONFIG_HOME`]: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
```
$XDG_CONFIG_HOME/kustomize/plugin
/${apiVersion}/LOWERCASE(${kind})
```
The default value of [`XDG_CONFIG_HOME`] is
`$HOME/.config`.
The one-plugin-per-directory requirement eases
creation of a plugin bundle (source, tests, plugin
data files, etc.) for sharing.
In the case of a [Go plugin](#go-plugins), it also
allows one to provide a `go.mod` file for the
single plugin, easing resolution of package
version dependency skew.
When loading, kustomize will first look for an
_executable_ file called
```
$XDG_CONFIG_HOME/kustomize/plugin
/${apiVersion}/LOWERCASE(${kind})/${kind}
```
If this file is not found or is not executable,
kustomize will look for a file called `${kind}.so`
in the same directory and attempt to load it as a
[Go plugin](#go-plugins).
If both checks fail, the plugin load fails the overall
`kustomize build`.
## Execution
Plugins are only used during a run of the
`kustomize build` command.
Generator plugins are run after processing the
`resources` field (which itself can be viewed as a
generator, simply reading objects from disk).
The full set of resources is then passed into the
transformation pipeline, wherein builtin
transformations like `namePrefix` and
`commonLabel` are applied (if they were specified
in the kustomization file), followed by the
user-specified transformers in the `transformers`
field.
The order specified in the `transformers` field is
respected, as transformers cannot be expected to
be commutative.
#### No Security
Kustomize plugins do not run in any kind of
kustomize-provided sandbox. There's no notion
of _"plugin security"_.
A `kustomize build` that tries to use plugins but
omits the flag
> `--enable_alpha_plugins`
will not load plugins and will fail with a
warning about plugin use.
The use of this flag is an opt-in acknowledging
the unstable (alpha) plugin API, the absence of
plugin provenance, and the fact that a plugin
is not part of kustomize.
To be clear, some kustomize plugin downloaded
from the internet might wonderfully transform
k8s config in a desired manner, while also
quietly doing anything the user could do to the
system running `kustomize build`.
## Authoring
There are two kinds of plugins, [exec](#exec-plugins) and [Go](#go-plugins).
### Exec plugins
A _exec plugin_ is any executable that accepts a
single argument on its command line - the name of
a YAML file containing its configuration (the file name
provided in the kustomization file).
> TODO: restrictions on plugin to allow the _same exec
> plugin_ to be targeted by both the
> `generators` and `transformers` fields.
>
> - first arg could be the fixed string
> `generate` or `transform`,
> (the name of the configuration file moves to
> the 2nd arg), or
> - or by default an exec plugin behaves as a tranformer
> unless a flag `-g` is provided, switching the
> exec plugin to behave as a generator.
[helm chart inflator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/chartinflator
[bashed config map]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/bashedconfigmap
[sed transformer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/sedtransformer
[hashicorp go-getter]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/gogetter
#### Examples
* [helm chart inflator] - A generator that inflates a helm chart.
* [bashed config map] - Super simple configMap generation from bash.
* [sed transformer] - Define your unstructured edits using a
plugin like this one.
* [hashicorp go-getter] - Download kustomize layes and build it to generate resources
A generator plugin accepts nothing on `stdin`, but emits
generated resources to `stdout`.
A transformer plugin accepts resource YAML on `stdin`,
and emits those resources, presumably transformed, to
`stdout`.
kustomize uses an exec plugin adapter to provide
marshalled resources on `stdin` and capture
`stdout` for further processing.
#### Generator Options
A generator exec plugin can adjust the generator options for the resources it emits by setting one of the following internal annotations.
> NOTE: These annotations are local to kustomize and will not be included in the final output.
**`kustomize.config.k8s.io/needs-hash`**
Resources can be marked as needing to be processed by the internal hash transformer by including the `needs-hash` annotation. When set valid values for the annotation are `"true"` and `"false"` which respectively enable or disable hash suffixing for the resource. Omitting the annotation is equivalent to setting the value `"false"`.
If this annotation is set on a resource not supported by the hash transformer the build will fail.
Example:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-test
annotations:
kustomize.config.k8s.io/needs-hash: "true"
data:
foo: bar
```
**`kustomize.config.k8s.io/behavior`**
The `behavior` annotation will influence how conflicts are handled for resources emitted by the plugin. Valid values include "create", "merge", and "replace" with "create" being the default.
Example:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-test
annotations:
kustomize.config.k8s.io/behavior: "merge"
data:
foo: bar
```
### Go plugins
Be sure to read [Go plugin caveats](goPluginCaveats.md).
[Go plugin]: https://golang.org/pkg/plugin/
A `.go` file can be a [Go plugin] if it declares
'main' as it's package, and exports a symbol to
which useful functions are attached.
It can further be used as a _kustomize_ plugin if
the symbol is named 'KustomizePlugin' and the
attached functions implement the `Configurable`,
`Generator` and `Transformer` interfaces.
A Go plugin for kustomize looks like this:
> ```
> package main
>
> import (
> "sigs.k8s.io/kustomize/api/ifc"
> "sigs.k8s.io/kustomize/api/resmap"
> ...
> )
>
> type plugin struct {...}
>
> var KustomizePlugin plugin
>
> func (p *plugin) Config(
> ldr ifc.Loader,
> rf *resmap.Factory,
> c []byte) error {...}
>
> func (p *plugin) Generate() (resmap.ResMap, error) {...}
>
> func (p *plugin) Transform(m resmap.ResMap) error {...}
> ```
Use of the identifiers `plugin`, `KustomizePlugin`
and implementation of the method signature
`Config` is required.
Implementing the `Generator` or `Transformer`
method allows (respectively) the plugin's config
file to be added to the `generators` or
`transformers` field in the kustomization file.
Do one or the other or both as desired.
[secret generator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/secretsfromdatabase
[service generator]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/someservicegenerator
[string prefixer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/stringprefixer
[date prefixer]: https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/someteam.example.com/v1/dateprefixer
[sops encoded secrets]: https://github.com/monopole/sopsencodedsecrets
#### Examples
* [service generator] - generate a service from a name and port argument.
* [string prefixer] - uses the value in `metadata/name` as the prefix.
This particular example exists to show how a plugin can
transform the behavior of a plugin. See the
`TestTransformedTransformers` test in the `target` package.
* [date prefixer] - prefix the current date to resource names, a simple
example used to modify the string prefixer plugin just mentioned.
* [secret generator] - generate secrets from a toy database.
* [sops encoded secrets] - a more complex secret generator.
* [All the builtin plugins](https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin).
User authored plugins are
on the same footing as builtin operations.
A Go plugin can be both a generator and a
transformer. The `Generate` method will run along
with all the other generators before the
`Transform` method runs.
Here's a build command that sensibly assumes the
plugin source code sits in the directory where
kustomize expects to find `.so` files:
```
d=$XDG_CONFIG_HOME/kustomize/plugin\
/${apiVersion}/LOWERCASE(${kind})
go build -buildmode plugin \
-o $d/${kind}.so $d/${kind}.go
```

View File

@@ -0,0 +1,724 @@
---
title: "Builtin Plugins"
linkTitle: "Builtin Plugins"
type: docs
description: >
Builtin Plugins
---
# Builtin Plugins
A list of kustomize's builtin plugins - both
generators and transformers.
For each plugin, an example is given for
* implicitly triggering
the plugin via a dedicated kustomization
file field (e.g. the `AnnotationsTransformer` is
triggered by the `commonAnnotations` field).
* explicitly triggering the plugin
via the `generators` or `transformers` field
(by providing a config file specifying the
plugin).
The former method is convenient but limited in
power as most of the plugins arguments must
be defaulted. The latter method allows for
complete plugin argument specification.
[types.GeneratorOptions]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/generatoroptions.go
[types.SecretArgs]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/secretargs.go
[types.ConfigMapArgs]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/configmapargs.go
[config.FieldSpec]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go
[types.ObjectMeta]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/objectmeta.go
[types.Selector]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/selector.go
[types.Replica]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/replica.go
[types.PatchStrategicMerge]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/patchstrategicmerge.go
[types.PatchTarget]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/patchtarget.go
[image.Image]: https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/image.go
## _AnnotationTransformer_
### Usage via `kustomization.yaml`
#### field name: `commonAnnotations`
Adds annotions (non-identifying metadata) to add
all resources. Like labels, these are key value
pairs.
```
commonAnnotations:
oncallPager: 800-555-1212
```
### Usage via plugin
#### Arguments
> Annotations map\[string\]string
>
> FieldSpecs \[\][config.FieldSpec]
#### Example
> ```
> apiVersion: builtin
> kind: AnnotationsTransformer
> metadata:
> name: not-important-to-example
> annotations:
> app: myApp
> greeting/morning: a string with blanks
> fieldSpecs:
> - path: metadata/annotations
> create: true
> ```
## _ConfigMapGenerator_
### Usage via `kustomization.yaml`
#### field name: `configMapGenerator`
Each entry in this list results in the creation of
one ConfigMap resource (it's a generator of n maps).
The example below creates three ConfigMaps. One with the names and contents of
the given files, one with key/value as data, and a third which sets an
annotation and label via `options` for that single ConfigMap.
Each configMapGenerator item accepts a parameter of
`behavior: [create|replace|merge]`.
This allows an overlay to modify or
replace an existing configMap from the parent.
Also, each entry has an `options` field, that has the
same subfields as the kustomization file's `generatorOptions` field.
This `options` field allows one to add labels and/or
annotations to the generated instance, or to individually
disable the name suffix hash for that instance.
Labels and annotations added here will not be overwritten
by the global options associated with the kustomization
file `generatorOptions` field. However, due to how
booleans behave, if the global `generatorOptions` field
specifies `disableNameSuffixHash: true`, this will
trump any attempt to locally override it.
```
# These labels are added to all configmaps and secrets.
generatorOptions:
labels:
fruit: apple
configMapGenerator:
- name: my-java-server-props
behavior: merge
files:
- application.properties
- more.properties
- name: my-java-server-env-vars
literals:
- JAVA_HOME=/opt/java/jdk
- JAVA_TOOL_OPTIONS=-agentlib:hprof
options:
disableNameSuffixHash: true
labels:
pet: dog
- name: dashboards
files:
- mydashboard.json
options:
annotations:
dashboard: "1"
labels:
app.kubernetes.io/name: "app1"
```
It is also possible to
[define a key](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#define-the-key-to-use-when-creating-a-configmap-from-a-file)
to set a name different than the filename.
The example below creates a ConfigMap
with the name of file as `myFileName.ini`
while the _actual_ filename from which the
configmap is created is `whatever.ini`.
```
configMapGenerator:
- name: app-whatever
files:
- myFileName.ini=whatever.ini
```
### Usage via plugin
#### Arguments
> [types.ConfigMapArgs]
#### Example
> ```
> apiVersion: builtin
> kind: ConfigMapGenerator
> metadata:
> name: mymap
> envs:
> - devops.env
> - uxteam.env
> literals:
> - FRUIT=apple
> - VEGETABLE=carrot
> ```
## _ImageTagTransformer_
### Usage via `kustomization.yaml`
#### field name: `images`
Images modify the name, tags and/or digest for images
without creating patches. E.g. Given this
kubernetes Deployment fragment:
```
containers:
- name: mypostgresdb
image: postgres:8
- name: nginxapp
image: nginx:1.7.9
- name: myapp
image: my-demo-app:latest
- name: alpine-app
image: alpine:3.7
```
one can change the `image` in the following ways:
- `postgres:8` to `my-registry/my-postgres:v1`,
- nginx tag `1.7.9` to `1.8.0`,
- image name `my-demo-app` to `my-app`,
- alpine's tag `3.7` to a digest value
all with the following *kustomization*:
```
images:
- name: postgres
newName: my-registry/my-postgres
newTag: v1
- name: nginx
newTag: 1.8.0
- name: my-demo-app
newName: my-app
- name: alpine
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
```
### Usage via plugin
#### Arguments
> ImageTag [image.Image]
>
> FieldSpecs \[\][config.FieldSpec]
#### Example
> ```
> apiVersion: builtin
> kind: ImageTagTransformer
> metadata:
> name: not-important-to-example
> imageTag:
> name: nginx
> newTag: v2
> ```
## _LabelTransformer_
### Usage via `kustomization.yaml`
#### field name: `commonLabels`
Adds labels to all resources and selectors
```
commonLabels:
someName: someValue
owner: alice
app: bingo
```
### Usage via plugin
#### Arguments
> Labels map\[string\]string
>
> FieldSpecs \[\][config.FieldSpec]
#### Example
> ```
> apiVersion: builtin
> kind: LabelTransformer
> metadata:
> name: not-important-to-example
> labels:
> app: myApp
> env: production
> fieldSpecs:
> - path: metadata/labels
> create: true
> ```
## _NamespaceTransformer_
### Usage via `kustomization.yaml`
#### field name: `namespace`
Adds namespace to all resources
```
namespace: my-namespace
```
Adds namespace to all resources
```
namespace: my-namespace
```
### Usage via plugin
#### Arguments
> [types.ObjectMeta]
>
> FieldSpecs \[\][config.FieldSpec]
#### Example
> ```
> apiVersion: builtin
> kind: NamespaceTransformer
> metadata:
> name: not-important-to-example
> namespace: test
> fieldSpecs:
> - path: metadata/namespace
> create: true
> - path: subjects
> kind: RoleBinding
> group: rbac.authorization.k8s.io
> - path: subjects
> kind: ClusterRoleBinding
> group: rbac.authorization.k8s.io
> ```
## _PatchesJson6902_
### Usage via `kustomization.yaml`
#### field name: `patchesJson6902`
Each entry in this list should resolve to
a kubernetes object and a JSON patch that will be applied
to the object.
The JSON patch is documented at https://tools.ietf.org/html/rfc6902
target field points to a kubernetes object within the same kustomization
by the object's group, version, kind, name and namespace.
path field is a relative file path of a JSON patch file.
The content in this patch file can be either in JSON format as
```
[
{"op": "add", "path": "/some/new/path", "value": "value"},
{"op": "replace", "path": "/some/existing/path", "value": "new value"}
]
```
or in YAML format as
```
- op: add
path: /some/new/path
value: value
- op: replace
path: /some/existing/path
value: new value
```
```
patchesJson6902:
- target:
version: v1
kind: Deployment
name: my-deployment
path: add_init_container.yaml
- target:
version: v1
kind: Service
name: my-service
path: add_service_annotation.yaml
```
The patch content can be an inline string as well:
```
patchesJson6902:
- target:
version: v1
kind: Deployment
name: my-deployment
patch: |-
- op: add
path: /some/new/path
value: value
- op: replace
path: /some/existing/path
value: "new value"
```
### Usage via plugin
#### Arguments
> Target [types.PatchTarget]
>
> Path string
>
> JsonOp string
#### Example
> ```
> apiVersion: builtin
> kind: PatchJson6902Transformer
> metadata:
> name: not-important-to-example
> target:
> group: apps
> version: v1
> kind: Deployment
> name: my-deploy
> path: jsonpatch.json
> ```
## _PatchesStrategicMerge_
### Usage via `kustomization.yaml`
#### field name: `patchesStrategicMerge`
Each entry in this list should be either a relative
file path or an inline content
resolving to a partial or complete resource
definition.
The names in these (possibly partial) resource
files must match names already loaded via the
`resources` field. These entries are used to
_patch_ (modify) the known resources.
Small patches that do one thing are best, e.g. modify
a memory request/limit, change an env var in a
ConfigMap, etc. Small patches are easy to review and
easy to mix together in overlays.
```
patchesStrategicMerge:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml
```
The patch content can be a inline string as well.
```
patchesStrategicMerge:
- |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nignx:latest
```
Note that kustomize does not support more than one patch
for the same object that contain a _delete_ directive. To remove
several fields / slice elements from an object create a single
patch that performs all the needed deletions.
### Usage via plugin
#### Arguments
> Paths \[\][types.PatchStrategicMerge]
>
> Patches string
#### Example
> ```
> apiVersion: builtin
> kind: PatchStrategicMergeTransformer
> metadata:
> name: not-important-to-example
> paths:
> - patch.yaml
> ```
## _PatchTransformer_
### Usage via `kustomization.yaml`
#### field name: `patches`
Each entry in this list should resolve to an Patch
object, which includes a patch and a target selector.
The patch can be either a strategic merge patch or a
JSON patch. it can be either a patch file or an inline
string. The target selects
resources by group, version, kind, name, namespace,
labelSelector and annotationSelector. A resource
which matches all the specified fields is selected
to apply the patch.
```
patches:
- path: patch.yaml
target:
group: apps
version: v1
kind: Deployment
name: deploy.*
labelSelector: "env=dev"
annotationSelector: "zone=west"
- patch: |-
- op: replace
path: /some/existing/path
value: new value
target:
kind: MyKind
labelSelector: "env=dev"
```
The `name` and `namespace` fields of the patch target selector are
automatically anchored regular expressions. This means that the value `myapp`
is equivalent to `^myapp$`.
### Usage via plugin
#### Arguments
> Path string
>
> Patch string
>
> Target \*[types.Selector]
#### Example
> ```
> apiVersion: builtin
> kind: PatchTransformer
> metadata:
> name: not-important-to-example
> patch: '[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "nginx:latest"}]'
> target:
> name: .*Deploy
> kind: Deployment
> ```
## _PrefixSuffixTransformer_
### Usage via `kustomization.yaml`
#### field names: `namePrefix`, `nameSuffix`
Prepends or postfixes the value to the names
of all resources.
E.g. a deployment named `wordpress` could
become `alices-wordpress` or `wordpress-v2`
or `alices-wordpress-v2`.
```
namePrefix: alices-
nameSuffix: -v2
```
The suffix is appended before the content hash if
the resource type is ConfigMap or Secret.
### Usage via plugin
#### Arguments
> Prefix string
>
> Suffix string
>
> FieldSpecs \[\][config.FieldSpec]
#### Example
> ```
> apiVersion: builtin
> kind: PrefixSuffixTransformer
> metadata:
> name: not-important-to-example
> prefix: baked-
> suffix: -pie
> fieldSpecs:
> - path: metadata/name
> ```
## _ReplicaCountTransformer_
### Usage via `kustomization.yaml`
#### field name: `replicas`
Replicas modified the number of replicas for a resource.
E.g. Given this kubernetes Deployment fragment:
```
kind: Deployment
metadata:
name: deployment-name
spec:
replicas: 3
```
one can change the number of replicas to 5
by adding the following to your kustomization:
```
replicas:
- name: deployment-name
count: 5
```
This field accepts a list, so many resources can
be modified at the same time.
As this declaration does not take in a `kind:` nor a `group:`
it will match any `group` and `kind` that has a matching name and
that is one of:
- `Deployment`
- `ReplicationController`
- `ReplicaSet`
- `StatefulSet`
For more complex use cases, revert to using a patch.
### Usage via plugin
#### Arguments
> Replica [types.Replica]
>
> FieldSpecs \[\][config.FieldSpec]
#### Example
> ```
> apiVersion: builtin
> kind: ReplicaCountTransformer
> metadata:
> name: not-important-to-example
> replica:
> name: myapp
> count: 23
> fieldSpecs:
> - path: spec/replicas
> create: true
> kind: Deployment
> - path: spec/replicas
> create: true
> kind: ReplicationController
> ```
## _SecretGenerator_
### Usage via `kustomization.yaml`
#### field name: `secretGenerator`
Each entry in the argument list
results in the creation of
one Secret resource
(it's a generator of n secrets).
This works like the `configMapGenerator` field
described above.
```
secretGenerator:
- name: app-tls
files:
- secret/tls.cert
- secret/tls.key
type: "kubernetes.io/tls"
- name: app-tls-namespaced
# you can define a namespace to generate
# a secret in, defaults to: "default"
namespace: apps
files:
- tls.crt=catsecret/tls.cert
- tls.key=secret/tls.key
type: "kubernetes.io/tls"
- name: env_file_secret
envs:
- env.txt
type: Opaque
- name: secret-with-annotation
files:
- app-config.yaml
type: Opaque
options:
annotations:
app_config: "true"
labels:
app.kubernetes.io/name: "app2"
```
### Usage via plugin
#### Arguments
> [types.ObjectMeta]
>
> [types.SecretArgs]
#### Example
> ```
> apiVersion: builtin
> kind: SecretGenerator
> metadata:
> name: my-secret
> namespace: whatever
> behavior: merge
> envs:
> - a.env
> - b.env
> files:
> - obscure=longsecret.txt
> literals:
> - FRUIT=apple
> - VEGETABLE=carrot
> ```

View File

@@ -0,0 +1,234 @@
---
title: "Exec plugin on linux"
linkTitle: "Exec plugin on linux"
type: docs
description: >
Exec plugin on linux in 60 seconds
---
This is a (no reading allowed!) 60 second copy/paste guided
example. Full plugin docs [here](README.md).
This demo writes and uses a somewhat ridiculous
_exec_ plugin (written in bash) that generates a
`ConfigMap`.
This is a guide to try it without damaging your
current setup.
#### requirements
* linux, git, curl, Go 1.13
## Make a place to work
```
DEMO=$(mktemp -d)
```
## Create a kustomization
Make a kustomization directory to
hold all your config:
```
MYAPP=$DEMO/myapp
mkdir -p $MYAPP
```
Make a deployment config:
```
cat <<'EOF' >$MYAPP/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: the-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: the-container
image: monopole/hello:1
command: ["/hello",
"--port=8080",
"--date=$(THE_DATE)",
"--enableRiskyFeature=$(ENABLE_RISKY)"]
ports:
- containerPort: 8080
env:
- name: THE_DATE
valueFrom:
configMapKeyRef:
name: the-map
key: today
- name: ALT_GREETING
valueFrom:
configMapKeyRef:
name: the-map
key: altGreeting
- name: ENABLE_RISKY
valueFrom:
configMapKeyRef:
name: the-map
key: enableRisky
EOF
```
Make a service config:
```
cat <<EOF >$MYAPP/service.yaml
kind: Service
apiVersion: v1
metadata:
name: the-service
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 8666
targetPort: 8080
EOF
```
Now make a config file for the plugin
you're about to write.
This config file is just another k8s resource
object. The values of its `apiVersion` and `kind`
fields are used to _find_ the plugin code on your
filesystem (more on this later).
```
cat <<'EOF' >$MYAPP/cmGenerator.yaml
apiVersion: myDevOpsTeam
kind: SillyConfigMapGenerator
metadata:
name: whatever
argsOneLiner: Bienvenue true
EOF
```
Finally, make a kustomization file
referencing all of the above:
```
cat <<EOF >$MYAPP/kustomization.yaml
commonLabels:
app: hello
resources:
- deployment.yaml
- service.yaml
generators:
- cmGenerator.yaml
EOF
```
Review the files
```
ls -C1 $MYAPP
```
## Make a home for plugins
Plugins must live in a particular place for
kustomize to find them.
This demo will use the ephemeral directory:
```
PLUGIN_ROOT=$DEMO/kustomize/plugin
```
The plugin config defined above in
`$MYAPP/cmGenerator.yaml` specifies:
> ```
> apiVersion: myDevOpsTeam
> kind: SillyConfigMapGenerator
> ```
This means the plugin must live in a directory
named:
```
MY_PLUGIN_DIR=$PLUGIN_ROOT/myDevOpsTeam/sillyconfigmapgenerator
mkdir -p $MY_PLUGIN_DIR
```
The directory name is the plugin config's
_apiVersion_ followed by its lower-cased _kind_.
A plugin gets its own directory to hold itself,
its tests and any supplemental data files it
might need.
## Create the plugin
There are two kinds of plugins, _exec_ and _Go_.
Make an _exec_ plugin, installing it to the
correct directory and file name. The file name
must match the plugin's _kind_ (in this case,
`SillyConfigMapGenerator`):
```
cat <<'EOF' >$MY_PLUGIN_DIR/SillyConfigMapGenerator
#!/bin/bash
# Skip the config file name argument.
shift
today=`date +%F`
echo "
kind: ConfigMap
apiVersion: v1
metadata:
name: the-map
data:
today: $today
altGreeting: "$1"
enableRisky: "$2"
"
EOF
```
By definition, an _exec_ plugin must be executable:
```
chmod a+x $MY_PLUGIN_DIR/SillyConfigMapGenerator
```
## Install kustomize
Per the [instructions](/kustomize/installation):
```
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
mkdir -p $DEMO/bin
mv kustomize $DEMO/bin
```
## Review the layout
```
tree $DEMO
```
## Build your app, using the plugin:
```
XDG_CONFIG_HOME=$DEMO $DEMO/bin/kustomize build --enable_alpha_plugins $MYAPP
```
Above, if you had set
> ```
> PLUGIN_ROOT=$HOME/.config/kustomize/plugin
> ```
there would be no need to use `XDG_CONFIG_HOME` in the
_kustomize_ command above.

View File

@@ -0,0 +1,123 @@
---
title: "Go plugin Caveats"
linkTitle: "Go plugin Caveats"
type: docs
description: >
Go plugin Caveats
---
[plugin package]: https://golang.org/pkg/plugin
[Go modules]: https://github.com/golang/go/wiki/Modules
[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
[tensorflow plugin]: https://www.tensorflow.org/guide/extend/op
A _Go plugin_ is a compilation artifact described
by the Go [plugin package]. It is built with
special flags and cannot run on its own.
It must be loaded into a running Go program.
> A normal program written in Go might be usable
> as _exec plugin_, but is not a _Go plugin_.
Go plugins allow kustomize extensions that run
without the cost marshalling/unmarshalling all
resource data to/from a subprocess for each plugin
run. The Go plugin API assures a certain level of
consistency to avoid confusing downstream
transformers.
Go plugins work as described in the [plugin
package], but fall short of common notions
associated with the word _plugin_.
## The skew problem
Go plugin compilation creates an [ELF] formatted
`.so` file, which by definition has no information
about the provenance of the object code.
Skew between the compilation conditions (versions
of package dependencies, `GOOS`, `GOARCH`) of the
main program ELF and the plugin ELF will cause
plugin load failure, with non-helpful error
messages.
Exec plugins also lack provenance, but won't fail
due to compilation skew.
In either case, the only sensible way to share a
plugin is as some kind of _bundle_ (a git repo
URL, a git archive file, a tar file, etc.)
containing source code, tests and associated data,
unpackable under
`$XDG_CONFIG_HOME/kustomize/plugin`.
In the case of a Go plugin, an _end user_
accepting a shared plugin _must compile both
kustomize and the plugin_.
This means a one-time run of
```
# Or whatever is appropriate at time of reading
GOPATH=${whatever} GO111MODULE=on go get sigs.k8s.io/kustomize/api
```
and then a normal development cycle using
```
go build -buildmode plugin \
-o ${wherever}/${kind}.so ${wherever}/${kind}.go
```
with paths and the release version tag (e.g. `v3.0.0`)
adjusted as needed.
For comparison, consider what one
must do to write a [tensorflow plugin].
## Why support Go plugins?
### Safety
The Go plugin developer sees the same API offered
to native kustomize operations, assuring certain
semantics, invariants, checks, etc. An exec
plugin sub-process dealing with this via
stdin/stdout will have an easier time screwing
things up for downstream transformers and
consumers.
Minor point: if the plugin reads files via
the kustomize-provided file `Loader` interface, it
will be constrained by kustomize file loading
restrictions. Of course, nothing but a code audit
prevents a Go plugin from importing the `io` package
and doing whatever it wants.
### Debugging
A Go plugin developer can debug the plugin _in
situ_, setting breakpoints inside the plugin and
elsewhere while running a plugin in feature tests.
To get the best of both worlds (shareability and safety),
a developer can write an `.go` program that functions
as an _exec plugin_, but can be processed by `go generate`
to emit a _Go plugin_ (or vice versa).
### Unit of contribution
All the builtin generators and transformers
are themselves Go plugins. This means that
the kustomize maintainers can promote a contributed
plugin to a builtin without needing code changes
(beyond those mandated by normal code review).
### Ecosystems grow through use
Tooling could ease Go plugin _sharing_, but this
requires some critical mass of Go plugin
_authoring_, which in turn is hampered by
confusion around sharing. [Go modules], once they
are more widely adopted, will solve the
biggest plugin sharing difficulty: ambiguous
plugin vs host dependencies.

View File

@@ -0,0 +1,375 @@
---
title: "Go plugin example"
linkTitle: "Go plugin example"
type: docs
description: >
Go plugin example
---
# Go Plugin Guided Example for Linux
[SopsEncodedSecrets repository]: https://github.com/monopole/sopsencodedsecrets
[Go plugin]: https://golang.org/pkg/plugin
[Go plugin caveats]: goPluginCaveats.md
This is a (no reading allowed!) 60 second copy/paste guided
example.
Full plugin docs [here](README.md).
Be sure to read the [Go plugin caveats].
This demo uses a Go plugin, `SopsEncodedSecrets`,
that lives in the [sopsencodedsecrets repository].
This is an inprocess [Go plugin], not an
sub-process exec plugin that happens to be written
in Go (which is another option for Go authors).
This is a guide to try it without damaging your
current setup.
#### requirements
* linux, git, curl, Go 1.13
For encryption
* gpg
Or
* Google cloud (gcloud) install
* a Google account with KMS permission
## Make a place to work
```shell
# Keeping these separate to avoid cluttering the DEMO dir.
DEMO=$(mktemp -d)
tmpGoPath=$(mktemp -d)
```
## Install kustomize
Need v3.0.0 for what follows, and you must _compile_
it (not download the binary from the release page):
```shell
GOPATH=$tmpGoPath go install sigs.k8s.io/kustomize/kustomize
```
## Make a home for plugins
A kustomize plugin is fully determined by
its configuration file and source code.
[required fields]: https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
Kustomize plugin configuration files are formatted
as kubernetes resource objects, meaning
`apiVersion`, `kind` and `metadata` are [required
fields] in these config files.
The kustomize program reads the config file
(because the config file name appears in the
`generators` or `transformers` field in the
kustomization file), then locates the Go plugin's
object code at the following location:
> ```shell
> $XDG_CONFIG_HOME/kustomize/plugin/$apiVersion/$lKind/$kind.so
> ```
where `lKind` holds the lowercased kind. The
plugin is then loaded and fed its config, and the
plugin's output becomes part of the overall
`kustomize build` process.
The same plugin might be used multiple times in
one kustomize build, but with different config
files. Also, kustomize might customize config
data before sending it to the plugin, for whatever
reason. For these reasons, kustomize owns the
mapping between plugins and config data; it's not
left to plugins to find their own config.
This demo will house the plugin it uses at the
ephemeral directory
```shell
PLUGIN_ROOT=$DEMO/kustomize/plugin
```
and ephemerally set `XDG_CONFIG_HOME` on a command
line below.
### What apiVersion and kind?
At this stage in the development of kustomize
plugins, plugin code doesn't know or care what
`apiVersion` or `kind` appears in the config file
sent to it.
The plugin could check these fields, but it's the
remaining fields that provide actual configuration
data, and at this point the successful parsing of
these other fields are the only thing that matters
to a plugin.
This demo uses a plugin called _SopsEncodedSecrets_,
and it lives in the [SopsEncodedSecrets repository].
Somewhat arbitrarily, we'll chose to install
this plugin with
```shell
apiVersion=mygenerators
kind=SopsEncodedSecrets
```
### Define the plugin's home dir
By convention, the ultimate home of the plugin
code and supplemental data, tests, documentation,
etc. is the lowercase form of its kind.
```shell
lKind=$(echo $kind | awk '{print tolower($0)}')
```
### Download the SopsEncodedSecrets plugin
In this case, the repo name matches the lowercase
kind already, so we just clone the repo and get
the proper directory name automatically:
```shell
mkdir -p $PLUGIN_ROOT/${apiVersion}
cd $PLUGIN_ROOT/${apiVersion}
git clone git@github.com:monopole/sopsencodedsecrets.git
```
Remember this directory:
```shell
MY_PLUGIN_DIR=$PLUGIN_ROOT/${apiVersion}/${lKind}
```
### Try the plugin's own test
Plugins may come with their own tests.
This one does, and it hopefully passes:
```shell
cd $MY_PLUGIN_DIR
go test SopsEncodedSecrets_test.go
```
Build the object code for use by kustomize:
```shell
cd $MY_PLUGIN_DIR
GOPATH=$tmpGoPath go build -buildmode plugin -o ${kind}.so ${kind}.go
```
This step may succeed, but kustomize might
ultimately fail to load the plugin because of
dependency [skew].
[skew]: /docs/plugins/README.md#caveats
[used in this demo]: #install-kustomize
On load failure
* be sure to build the plugin with the same
version of Go (_go1.13_) on the same `$GOOS`
(_linux_) and `$GOARCH` (_amd64_) used to build
the kustomize being [used in this demo].
* change the plugin's dependencies in its `go.mod`
to match the versions used by kustomize (check
kustomize's `go.mod` used in its tagged commit).
Lacking tools and metadata to allow this to be
automated, there won't be a Go plugin ecosystem.
Kustomize has adopted a Go plugin architecture as
to ease accept new generators and transformers
(just write a plugin), and to be sure that native
operations (also constructed and tested as
plugins) are compartmentalized, orderable and
reusable instead of bizarrely woven throughout the
code as a individual special cases.
## Create a kustomization
Make a kustomization directory to
hold all your config:
```shell
MYAPP=$DEMO/myapp
mkdir -p $MYAPP
```
Make a config file for the SopsEncodedSecrets plugin.
Its `apiVersion` and `kind` allow the plugin to be
found:
```shell
cat <<EOF >$MYAPP/secGenerator.yaml
apiVersion: ${apiVersion}
kind: ${kind}
metadata:
name: mySecretGenerator
name: forbiddenValues
namespace: production
file: myEncryptedData.yaml
keys:
- ROCKET
- CAR
EOF
```
This plugin expects to find more data in
`myEncryptedData.yaml`; we'll get to that shortly.
Make a kustomization file referencing the plugin
config:
```shell
cat <<EOF >$MYAPP/kustomization.yaml
commonLabels:
app: hello
generators:
- secGenerator.yaml
EOF
```
Now generate the real encrypted data.
### Assure you have an encryption tool installed
We're going to use [sops](https://github.com/mozilla/sops) to encode a file. Choose either GPG or Google Cloud KMS as the secret provider to continue.
#### GPG
Try this:
```shell
gpg --list-keys
```
If it returns a list, presumably you've already created keys. If not, try import test keys from sops for dev.
```shell
curl https://raw.githubusercontent.com/mozilla/sops/master/pgp/sops_functional_tests_key.asc | gpg --import
SOPS_PGP_FP="1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A"
```
#### Google Cloude KMS
Try this:
```shell
gcloud kms keys list --location global --keyring sops
```
If it succeeds, presumably you've already created keys and placed them in a keyring called sops. If not, do this:
```shell
gcloud kms keyrings create sops --location global
gcloud kms keys create sops-key --location global \
--keyring sops --purpose encryption
```
Extract your keyLocation for use below:
```shell
keyLocation=$(\
gcloud kms keys list --location global --keyring sops |\
grep GOOGLE | cut -d " " -f1)
echo $keyLocation
```
### Install `sops`
```shell
GOPATH=$tmpGoPath go install go.mozilla.org/sops/cmd/sops
```
### Create data encrypted with your private key
Create raw data to encrypt:
```shell
cat <<EOF >$MYAPP/myClearData.yaml
VEGETABLE: carrot
ROCKET: saturn-v
FRUIT: apple
CAR: dymaxion
EOF
```
Encrypt the data into file the plugin wants to read:
With PGP
```shell
$tmpGoPath/bin/sops --encrypt \
--pgp $SOPS_PGP_FP \
$MYAPP/myClearData.yaml >$MYAPP/myEncryptedData.yaml
```
Or GCP KMS
```shell
$tmpGoPath/bin/sops --encrypt \
--gcp-kms $keyLocation \
$MYAPP/myClearData.yaml >$MYAPP/myEncryptedData.yaml
```
Review the files
```shell
tree $DEMO
```
This should look something like:
> ```shell
> /tmp/tmp.0kIE9VclPt
> ├── kustomize
> │   └── plugin
> │   └── mygenerators
> │   └── sopsencodedsecrets
> │   ├── go.mod
> │   ├── go.sum
> │   ├── LICENSE
> │   ├── README.md
> │   ├── SopsEncodedSecrets.go
> │   ├── SopsEncodedSecrets.so
> │   └── SopsEncodedSecrets_test.go
> └── myapp
> ├── kustomization.yaml
> ├── myClearData.yaml
> ├── myEncryptedData.yaml
> └── secGenerator.yaml
> ```
## Build your app, using the plugin:
```shell
XDG_CONFIG_HOME=$DEMO $tmpGoPath/bin/kustomize build --enable_alpha_plugins $MYAPP
```
This should emit a kubernetes secret, with
encrypted data for the names `ROCKET` and `CAR`.
Above, if you had set
> ```shell
> PLUGIN_ROOT=$HOME/.config/kustomize/plugin
> ```
there would be no need to use `XDG_CONFIG_HOME` in the
_kustomize_ command above.

View File

@@ -0,0 +1,9 @@
---
title: "Installation"
linkTitle: "Installation"
weight: 20
type: docs
menu:
main:
weight: 10
---

View File

@@ -0,0 +1,21 @@
---
title: "Binaries"
linkTitle: "Binaries"
weight: 3
type: docs
description: >
Install Kustomize by downloading precompiled binaries.
---
Binaries at various versions for linux, MacOs and Windows are published on the [release page].
The follow [script] detects your OS and downloads the appropriate kustomize binary to your
current working directory.
```
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
```
[releases page]: https://github.com/kubernetes-sigs/kustomize/releases
[script]: https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh

View File

@@ -0,0 +1,17 @@
---
title: "Chocolatey"
linkTitle: "Chocolatey"
weight: 4
type: docs
description: >
Install Kustomize for Windows using Chocolatey
---
```
choco install kustomize
```
For support on the chocolatey package
and prior releases, see:
- [Choco Package](https://chocolatey.org/packages/kustomize)
- [Package Source](https://github.com/kenmaglio/choco-kustomize)

View File

@@ -0,0 +1,21 @@
---
title: "Homebrew / MacPorts"
linkTitle: "Homebrew / MacPorts"
weight: 3
type: docs
description: >
Install Kustomize for MacOS using Homebrew or MacPorts
---
For [Homebrew](https://brew.sh) users:
```
brew install kustomize
```
For [MacPorts](https://www.macports.org) users:
```
sudo port install kustomize
```

View File

@@ -0,0 +1,43 @@
---
title: "Go Source"
linkTitle: "Go Source"
weight: 2
type: docs
description: >
Install Kustomize from the Go source code
---
Requires [Go] to be installed.
## Install the kustomize CLI from source without cloning the repo
```
GOBIN=$(pwd)/ GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3
```
## Install the kustomize CLI from local source with cloning the repo
```
# Need go 1.13 or higher
unset GOPATH
# see https://golang.org/doc/go1.13#modules
unset GO111MODULES
# clone the repo
git clone git@github.com:kubernetes-sigs/kustomize.git
# get into the repo root
cd kustomize
# Optionally checkout a particular tag if you don't
# want to build at head
git checkout kustomize/v3.2.3
# build the binary
(cd kustomize; go install .)
# run it
~/go/bin/kustomize version
```
[Go]: https://golang.org

View File

@@ -0,0 +1,4 @@
---
type: "search-index"
url: "index.json"
---

View File

@@ -0,0 +1,6 @@
---
title: Search Results
layout: search
---

17
site/deploy.sh Normal file
View File

@@ -0,0 +1,17 @@
#Copyright 2018 Google LLC
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
#
rm -rf public/
HUGO_ENV="production" hugo --gc || exit 1
s3deploy -source=public/ -region=eu-west-1 -bucket=bep.is -distribution-id=E8OKNT7W9ZYZ2 -path temp/td

15
site/go.mod Normal file
View File

@@ -0,0 +1,15 @@
module sigs.k8s.io/kustomize/site
go 1.13
require (
github.com/gobuffalo/envy v1.9.0 // indirect
github.com/gohugoio/hugo v0.68.3
github.com/golang/protobuf v1.3.2 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/spf13/cobra v1.0.0 // indirect
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
google.golang.org/grpc v1.23.0 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
)

499
site/go.sum Normal file
View File

@@ -0,0 +1,499 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
cloud.google.com/go v0.39.0 h1:UgQP9na6OTfp4dsAiz/eFpFA1C6tPdH5wiRdi19tuMw=
cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
contrib.go.opencensus.io/exporter/stackdriver v0.11.0/go.mod h1:hA7rlmtavV03FGxzWXAPBUnZeZBhWN/QYQAuMtxc9Bk=
contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
contrib.go.opencensus.io/resource v0.0.0-20190131005048-21591786a5e0/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=
github.com/Azure/azure-amqp-common-go v1.1.3/go.mod h1:FhZtXirFANw40UXI2ntweO+VOkfaw8s6vZxUiRhLYW8=
github.com/Azure/azure-amqp-common-go v1.1.4/go.mod h1:FhZtXirFANw40UXI2ntweO+VOkfaw8s6vZxUiRhLYW8=
github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-pipeline-go v0.1.9 h1:u7JFb9fFTE6Y/j8ae2VK33ePrRqJqoCM/IWkQdAZ+rg=
github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v27.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-service-bus-go v0.4.1/go.mod h1:d9ho9e/06euiTwGpKxmlbpPhFUsfCsq6a4tZ68r51qI=
github.com/Azure/azure-storage-blob-go v0.6.0 h1:SEATKb3LIHcaSIX+E6/K4kJpwfuozFEsmt5rS56N6CE=
github.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y=
github.com/Azure/go-autorest v11.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v11.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 h1:+tu3HOoMXB7RXEINRVIpxJCT+KdYiI7LAEAUrOw3dIU=
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190418212003-6ac0b49e7197/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-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/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
github.com/alecthomas/chroma v0.7.1 h1:G1i02OhUbRi2nJxcNkwJaY/J1gHXj9tt72qN6ZouLFQ=
github.com/alecthomas/chroma v0.7.1/go.mod h1:gHw09mkX1Qp80JlYbmN9L3+4R5o6DJJ3GRShh+AICNc=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
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/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.18.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.19.16/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.27.1 h1:MXnqY6SlWySaZAqNnXThOvjRFdiiOuKtC6i7baFdNdU=
github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo=
github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
github.com/bep/gitmap v1.1.1 h1:Nf8ySnC3I7/xPjuWeCwzukUFv185iTUQ6nOvLy9gCJA=
github.com/bep/gitmap v1.1.1/go.mod h1:g9VRETxFUXNWzMiuxOwcudo6DfZkW9jOsOW0Ft4kYaY=
github.com/bep/golibsass v0.5.0 h1:b+Uxsk826Q35OmbenSmU65P+FJJQoVs2gI2mk1ba28s=
github.com/bep/golibsass v0.5.0/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA=
github.com/bep/tmc v0.5.1 h1:CsQnSC6MsomH64gw0cT5f+EwQDcvZz4AazKunFwTpuI=
github.com/bep/tmc v0.5.1/go.mod h1:tGYHN8fS85aJPhDLgXETVKp+PR382OvFi2+q2GkGsq0=
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/disintegration/gift v1.2.1 h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc=
github.com/disintegration/gift v1.2.1/go.mod h1:Jh2i7f7Q2BM7Ezno3PhfezbR1xpUg9dUg3/RlKGr4HI=
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
github.com/frankban/quicktest v1.7.2 h1:2QxQoC1TS09S7fhCPsrvqYdvP1H5M1P1ih5ABm3BTYk=
github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gobuffalo/envy v1.9.0 h1:eZR0DuEgVLfeIb1zIKt3bT4YovIMf9O9LXQeCZLXpqE=
github.com/gobuffalo/envy v1.9.0/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w=
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/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gohugoio/hugo v0.68.3 h1:dLzfE2XLP3K4zD0muTGAhbhHaI/+pvXR+ZVCc8oKWvs=
github.com/gohugoio/hugo v0.68.3/go.mod h1:jj7XAfCteXVxl6peDyGGiH60XPfWIvDy05qHFzNRQbo=
github.com/gohugoio/testmodBuilder/mods v0.0.0-20190520184928-c56af20f2e95 h1:sgew0XCnZwnzpWxTt3V8LLiCO7OQi3C6dycaE67wfkU=
github.com/gohugoio/testmodBuilder/mods v0.0.0-20190520184928-c56af20f2e95/go.mod h1:bOlVlCa1/RajcHpXkrUXPSHB/Re1UnlXxD1Qp8SKOd8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
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/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/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/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/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/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.2-0.20191028172631-481baca67f93 h1:VvBteXw2zOXEgm0o3PgONTWf+bhUGsCaiNn3pbkU9LA=
github.com/google/go-cmp v0.3.2-0.20191028172631-481baca67f93/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE=
github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.2.2 h1:fSIRzE/K12IaNgV6X0173X/oLrTwHKRiMcFZhiDrN3s=
github.com/google/wire v0.2.2/go.mod h1:7FHVg6mFpFQrjeUZrm+BaD50N5jnDKm50uVPTpyYOmU=
github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww=
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
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/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/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/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jdkato/prose v1.1.1 h1:r6CwY09U97IZNgNQEHoeCh2nvg2e8WCOGjPH/b7lowI=
github.com/jdkato/prose v1.1.1/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/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/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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
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/kyokomi/emoji v2.1.0+incompatible h1:+DYU2RgpI6OHG4oQkM5KlqD3Wd3UPEsX8jamTo1Mp6o=
github.com/kyokomi/emoji v2.1.0+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magefile/mage v1.9.0 h1:t3AU2wNwehMCW97vuqQLtw6puppWXHO+O2MHo5a50XE=
github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/markbates/inflect v1.0.0 h1:gTffXSQCc+WaIvBcI/IItJQMOemietXr5EIKLXDYqI4=
github.com/markbates/inflect v1.0.0/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88=
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/mmark v1.3.6 h1:t47x5vThdwgLJzofNsbsAl7gmIiJ7kbDQN5BxwBmwvY=
github.com/miekg/mmark v1.3.6/go.mod h1:w7r9mkTvpS55jlfyn22qJ618itLryxXBhA7Jp3FIlkw=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y=
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/muesli/smartcrop v0.3.0 h1:JTlSkmxWg/oQ1TcLDoypuirdE8Y/jzNirQeLkxpA6Oc=
github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nicksnyder/go-i18n v1.10.0 h1:5AzlPKvXBH4qBzmZ09Ua9Gipyruv6uApMcrNZdo96+Q=
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
github.com/niklasfasching/go-org v1.0.0 h1:lDh8zKtmbaQupKQhLyVp1clG+JojkVoVBH9bT7c9O70=
github.com/niklasfasching/go-org v1.0.0/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.5.1 h1:asQ0uD7BN9RU5Im41SEEZTwCi/zAXdMOLS3npYaos2g=
github.com/rogpeppe/go-internal v1.5.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6 h1:tlXG832s5pa9x9Gs3Rp2rTvEqjiDEuETUOSfBEiTcns=
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
github.com/sanity-io/litter v1.2.0 h1:DGJO0bxH/+C2EukzOSBmAlxmkhVMGqzvcx/rvySYw9M=
github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
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.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/fsync v0.9.0 h1:f9CEt3DOB2mnHxZaftmEOFWjABEvKM/xpf3cUwJrGOY=
github.com/spf13/fsync v0.9.0/go.mod h1:fNtJEfG3HiltN3y4cPOz6MLjos9+2pIEqLIgszqhp/0=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
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.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
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/testify v0.0.0-20161117074351-18a02ba4a312/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/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tdewolff/minify/v2 v2.6.1 h1:UJLhbs2Q/iDrqA79EEyKE48uYHeAMPVdiUzdtKsatJ8=
github.com/tdewolff/minify/v2 v2.6.1/go.mod h1:l9hbQnH096st77OkscoRUvKdd23oUM6pDZpYx381sPo=
github.com/tdewolff/parse/v2 v2.3.14 h1:Tzam5YoUXx7gybFEfR/zcuR74PXADnrfUqYUXL+K5oA=
github.com/tdewolff/parse/v2 v2.3.14/go.mod h1:+V2lSZ93xpH2Csfs/vtNY1Fjr8kcFMsZKjyLoSkZbM0=
github.com/tdewolff/test v1.0.4 h1:ih38SXuQJ32Hng5EtSW32xqEsVeMnPp6nNNRPhBBDE8=
github.com/tdewolff/test v1.0.4/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark-highlighting v0.0.0-20200218065240-d1af22c1126f h1:5295skDVJn90SXIYI22jOMeR9XbnuN76y/V1m9N8ITQ=
github.com/yuin/goldmark-highlighting v0.0.0-20200218065240-d1af22c1126f/go.mod h1:9yW2CHuRSORvHgw7YfybB09PqUZTbzERyW3QFvd8+0Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.0.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
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/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
gocloud.dev v0.15.0 h1:Tl8dkOHWVZiYBYPxG2ouhpfmluoQGt3mY323DaAHaC8=
gocloud.dev v0.15.0/go.mod h1:ShXCyJaGrJu9y/7a6+DSCyBb9MFGZ1P5wwPa0Wu6w34=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52 h1:2fktqPPvDiVEEVT/vSTeoUPXfmRxRaGy6GU8jypvEn0=
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/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-20181023162649-9b4f9f5ad519/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-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190424112056-4829fb13d2c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/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-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0/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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/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-20181031143558-9b800f95dbbc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107144601-ef85f5a75ddf h1:9cZxTVBvFZgOnVi/DobY3JsafbPFPnP2rtN81d4wPpw=
golang.org/x/sys v0.0.0-20200107144601-ef85f5a75ddf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/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-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.3.2/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.5.0 h1:lj9SyhMzyoa38fgFF0oO2T6pjs5IzkLPKfVtxpyCRMM=
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw=
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69 h1:4rNOqY4ULrKzS6twXa619uQgI7h9PaVd4ZhjFQ7C5zs=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
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-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
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.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
pack.ag/amqp v0.8.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
pack.ag/amqp v0.11.0/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=

26
site/layouts/404.html Normal file
View File

@@ -0,0 +1,26 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
{{ define "main"}}
<main id="main">
<div>
<h1 id="title">Not found</h1>
<p>Oops! This page doesn't exist. Try going back to our <a href="{{ "/" | relURL }}">home page</a>.</p>
<p>You can learn how to make a 404 page like this in <a href="https://gohugo.io/templates/404/">Custom 404 Pages</a>.</p>
</div>
</main>
{{ end }}

View File

@@ -0,0 +1,17 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script src="{{ .Site.BaseURL }}/js/asciinema-player.js"></script>

View File

@@ -0,0 +1,17 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="stylesheet" type="text/css" href="{{ .Site.BaseURL }}/css/asciinema-player.css" />

View File

@@ -0,0 +1,45 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>
<asciinema-player
src="{{ .Site.BaseURL }}/casts/{{ with .Get "key" | safeURL}}{{ . }}{{ end }}.cast"
{{ if .Get "autoplay" }}autoplay="{{ .Get "autoplay" }}"{{ end }}
{{ if .Get "preload" }}preload="{{ .Get "preload" }}"{{ end }}
{{ if .Get "loop" }}loop="{{ .Get "loop" }}"{{ end }}
start-at="{{ if .Get "start-at" }}{{ .Get "start-at" }}{{ else }}0{{ end }}"
speed="{{ if .Get "speed" }}{{ .Get "speed" }}{{ else }}1{{ end }}"
{{ if .Get "idle-time-limit" }}idle-time-limit="{{ .Get "idle-time-limit" }}"{{ end }}
{{ if .Get "poster" }}poster="{{ .Get "poster" | safeURL }}"{{ end }}
{{ if .Get "font-size" }}font-size="{{ .Get "font-size" }}"{{ end }}
{{ if .Get "theme" }}theme="{{ .Get "theme" | safeURL }}"{{ end }}
{{ if .Get "title" }}title="{{ .Get "title" | safeURL }}"{{ end }}
{{ if .Get "author" }}author="{{ .Get "author" | safeURL }}"{{ end }}
{{ if .Get "author-url" }}author-url="{{ .Get "author-url" | safeURL }}"{{ end }}
{{ if .Get "author-img-url" }}author-img-url="{{ .Get "author-img-url" | safeURL }}"{{ end }}
></asciinema-player>
<script>
let c=document.getElementsByClassName("td-content")
if (c && c.length > 0) {
let w = c[0].clientWidth
let p=document.getElementsByTagName('asciinema-player')
if (p && p.length > 0) {
p.cols = w
}
}
</script>
</p>

View File

@@ -0,0 +1,32 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
{{ $original := .Get "src" }}
<div id="ohpen_swagger_ui"></div>
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: {{ $original }},
dom_id: '#ohpen_swagger_ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
]
})
window.ui = ui
}
</script>

View File

@@ -0,0 +1,20 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
{{ $src := .Get "src" }}
<object data="{{ .Site.BaseURL }}/{{ $src }}" type="application/pdf" width="{{ .Get "width" }}}" height="{{ .Get "height" }}">
alt : <a href="{{ .Site.BaseURL }}/{{ $src }}">$src.pdf</a>
</object>

View File

@@ -0,0 +1,18 @@
<!--
Copyright 2019 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
{{ $src := .Get "src" }}
<img src="{{ .Site.BaseURL }}/{{ $src }}.svg" />

View File

@@ -0,0 +1,49 @@
# Change Log
All notable changes will be documented in this file.
`readdir-enhanced` adheres to [Semantic Versioning](http://semver.org/).
## [v2.2.0](https://github.com/BigstickCarpet/readdir-enhanced/tree/v2.2.0) (2018-01-09)
- Refactored the codebase to use ES6 syntax (Node v4.x compatible)
- You can now provide [your own implementation](https://github.com/BigstickCarpet/readdir-enhanced#custom-fs-methods) for the [filesystem module](https://nodejs.org/api/fs.html) that's used by `readdir-enhanced`. Just set the `fs` option to your implementation. Thanks to [@mrmlnc](https://github.com/mrmlnc) for the idea and [the PR](https://github.com/BigstickCarpet/readdir-enhanced/pull/10)!
- [Better error handling](https://github.com/BigstickCarpet/readdir-enhanced/commit/0d330b68524bafbdeae11566a3e8af1bc3f184bf), especially around user-specified logic, such as `options.deep`, `options.filter`, and `options.fs`
[Full Changelog](https://github.com/BigstickCarpet/readdir-enhanced/compare/v2.1.0...v2.2.0)
## [v2.1.0](https://github.com/BigstickCarpet/readdir-enhanced/tree/v2.1.0) (2017-12-01)
- The `fs.Stats` objects now include a `depth` property, which indicates the number of subdirectories beneath the base path. Thanks to [@mrmlnc](https://github.com/mrmlnc) for [the PR](https://github.com/BigstickCarpet/readdir-enhanced/pull/8)!
[Full Changelog](https://github.com/BigstickCarpet/readdir-enhanced/compare/v2.0.0...v2.1.0)
## [v2.0.0](https://github.com/BigstickCarpet/readdir-enhanced/tree/v2.0.0) (2017-11-15)
- Dropped support for Node v0.x, which is no longer actively maintained. Please upgrade to Node 4 or newer.
[Full Changelog](https://github.com/BigstickCarpet/readdir-enhanced/compare/v1.5.0...v2.0.0)
## [v1.5.0](https://github.com/BigstickCarpet/readdir-enhanced/tree/v1.5.0) (2017-04-10)
The [`deep` option](README.md#deep) can now be set to a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp), a [glob pattern](https://github.com/isaacs/node-glob#glob-primer), or a function, which allows you to customize which subdirectories get crawled. Of course, you can also still still set the `deep` option to `true` to crawl _all_ subdirectories, or a number if you just want to limit the recursion depth.
[Full Changelog](https://github.com/BigstickCarpet/readdir-enhanced/compare/v1.4.0...v1.5.0)
## [v1.4.0](https://github.com/BigstickCarpet/readdir-enhanced/tree/v1.4.0) (2016-08-26)
The [`filter` option](README.md#filter) can now be set to a regular expression or a glob pattern string, which simplifies filtering based on file names. Of course, you can still set the `filter` option to a function if you need to perform more advanced filtering based on the [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) of each file.
[Full Changelog](https://github.com/BigstickCarpet/readdir-enhanced/compare/v1.3.4...v1.4.0)
## [v1.3.4](https://github.com/BigstickCarpet/readdir-enhanced/tree/v1.3.4) (2016-08-26)
As of this release, `readdir-enhanced` is fully tested on all major Node versions (0.x, 4.x, 5.x, 6.x) on [linux](https://travis-ci.org/BigstickCarpet/readdir-enhanced) and [Windows](https://ci.appveyor.com/project/BigstickCarpet/readdir-enhanced/branch/master), with [nearly 100% code coverage](https://coveralls.io/github/BigstickCarpet/readdir-enhanced?branch=master). I do all of my local development and testing on MacOS, so that's covered too.
[Full Changelog](https://github.com/BigstickCarpet/readdir-enhanced/compare/v1.0.1...v1.3.4)

23
site/node_modules/@mrmlnc/readdir-enhanced/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2016 James Messinger
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
.

347
site/node_modules/@mrmlnc/readdir-enhanced/README.md generated vendored Normal file
View File

@@ -0,0 +1,347 @@
Enhanced `fs.readdir()`
=======================
> :warning: This is «fork» for original `readdir-enhanced` package but with some monkey fixes.
[![Build Status](https://api.travis-ci.org/BigstickCarpet/readdir-enhanced.svg?branch=master)](https://travis-ci.org/BigstickCarpet/readdir-enhanced)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/bigstickcarpet/readdir-enhanced?svg=true&branch=master&failingText=Windows%20build%20failing&passingText=Windows%20build%20passing)](https://ci.appveyor.com/project/BigstickCarpet/readdir-enhanced/branch/master)
[![Coverage Status](https://coveralls.io/repos/github/BigstickCarpet/readdir-enhanced/badge.svg?branch=master)](https://coveralls.io/github/BigstickCarpet/readdir-enhanced?branch=master)
[![Codacy Score](https://api.codacy.com/project/badge/Grade/178a817b6c864de7813fef457c0ed5ae)](https://www.codacy.com/public/jamesmessinger/readdir-enhanced)
[![Inline docs](http://inch-ci.org/github/BigstickCarpet/readdir-enhanced.svg?branch=master&style=shields)](http://inch-ci.org/github/BigstickCarpet/readdir-enhanced)
[![Dependencies](https://david-dm.org/BigstickCarpet/readdir-enhanced.svg)](https://david-dm.org/BigstickCarpet/readdir-enhanced)
[![npm](https://img.shields.io/npm/v/readdir-enhanced.svg?maxAge=43200)](https://www.npmjs.com/package/readdir-enhanced)
[![License](https://img.shields.io/npm/l/readdir-enhanced.svg?maxAge=2592000)](LICENSE)
`readdir-enhanced` is a [backward-compatible](#backward-compatible) drop-in replacement for [`fs.readdir()`](https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback) and [`fs.readdirSync()`](https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options) with tons of extra features ([filtering](#filter), [recursion](#deep), [absolute paths](#basepath), [stats](#stats), and more) as well as additional APIs for Promises, Streams, and EventEmitters.
Pick Your API
-----------------
`readdir-enhanced` has multiple APIs, so you can pick whichever one you prefer. There are three main APIs:
- **Synchronous API**<br>
aliases: `readdir.sync`, `readdir.readdirSync`<br>
Blocks the thread until all directory contents are read, and then returns all the results.
- **Async API**<br>
aliases: `readdir`, `readdir.async`, `readdir.readdirAsync`<br>
Reads the starting directory contents asynchronously and buffers all the results until all contents have been read. Supports callback or Promise syntax (see example below).
- **Streaming API**<br>
aliases: `readdir.stream`, `readdir.readdirStream`<br>
The streaming API reads the starting directory asynchronously and returns the results in real-time as they are read. The results can be [piped](https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options) to other Node.js streams, or you can listen for specific events via the [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) interface. (see example below)
```javascript
var readdir = require('readdir-enhanced');
var through2 = require('through2');
// Synchronous API
var files = readdir.sync('my/directory');
// Callback API
readdir.async('my/directory', function(err, files) { ... });
// Promises API
readdir.async('my/directory')
.then(function(files) { ... })
.catch(function(err) { ... });
// EventEmitter API
readdir.stream('my/directory')
.on('data', function(path) { ... })
.on('file', function(path) { ... })
.on('directory', function(path) { ... })
.on('symlink', function(path) { ... })
.on('error', function(err) { ... });
// Streaming API
var stream = readdir.stream('my/directory')
.pipe(through2.obj(function(data, enc, next) {
console.log(data);
this.push(data);
next();
});
```
<a id="options"></a>
Enhanced Features
-----------------
`readdir-enhanced` adds several features to the built-in `fs.readdir()` function. All of the enhanced features are opt-in, which makes `readdir-enhanced` [fully backward compatible by default](#backward-compatible). You can enable any of the features by passing-in an `options` argument as the second parameter.
<a id="deep"></a>
### Recursion
By default, `readdir-enhanced` will only return the top-level contents of the starting directory. But you can set the `deep` option to recursively traverse the subdirectories and return their contents as well.
#### Crawl ALL subdirectories
The `deep` option can be set to `true` to traverse the entire directory structure.
```javascript
var readdir = require('readdir-enhanced');
readdir('my/directory', {deep: true}, function(err, files) {
console.log(files);
// => subdir1
// => subdir1/file.txt
// => subdir1/subdir2
// => subdir1/subdir2/file.txt
// => subdir1/subdir2/subdir3
// => subdir1/subdir2/subdir3/file.txt
});
```
#### Crawl to a specific depth
The `deep` option can be set to a number to only traverse that many levels deep. For example, calling `readdir('my/directory', {deep: 2})` will return `subdir1/file.txt` and `subdir1/subdir2/file.txt`, but it _won't_ return `subdir1/subdir2/subdir3/file.txt`.
```javascript
var readdir = require('readdir-enhanced');
readdir('my/directory', {deep: 2}, function(err, files) {
console.log(files);
// => subdir1
// => subdir1/file.txt
// => subdir1/subdir2
// => subdir1/subdir2/file.txt
// => subdir1/subdir2/subdir3
});
```
#### Crawl subdirectories by name
For simple use-cases, you can use a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) or a [glob pattern](https://github.com/isaacs/node-glob#glob-primer) to crawl only the directories whose path matches the pattern. The path is relative to the starting directory by default, but you can customize this via [`options.basePath`](#basepath).
> **NOTE:** Glob patterns [_always_ use forward-slashes](https://github.com/isaacs/node-glob#windows), even on Windows. This _does not_ apply to regular expressions though. Regular expressions should use the appropraite path separator for the environment. Or, you can match both types of separators using `[\\/]`.
```javascript
var readdir = require('readdir-enhanced');
// Only crawl the "lib" and "bin" subdirectories
// (notice that the "node_modules" subdirectory does NOT get crawled)
readdir('my/directory', {deep: /lib|bin/}, function(err, files) {
console.log(files);
// => bin
// => bin/cli.js
// => lib
// => lib/index.js
// => node_modules
// => package.json
});
```
#### Custom recursion logic
For more advanced recursion, you can set the `deep` option to a function that accepts an [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object and returns a truthy value if the starting directory should be crawled.
> **NOTE:** The [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object that's passed to the function has additional `path` and `depth` properties. The `path` is relative to the starting directory by default, but you can customize this via [`options.basePath`](#basepath). The `depth` is the number of subdirectories beneath the base path (see [`options.deep`](#deep)).
```javascript
var readdir = require('readdir-enhanced');
// Crawl all subdirectories, except "node_modules"
function ignoreNodeModules (stats) {
return stats.path.indexOf('node_modules') === -1;
}
readdir('my/directory', {deep: ignoreNodeModules}, function(err, files) {
console.log(files);
// => bin
// => bin/cli.js
// => lib
// => lib/index.js
// => node_modules
// => package.json
});
```
<a id="filter"></a>
### Filtering
The `filter` option lets you limit the results based on any criteria you want.
#### Filter by name
For simple use-cases, you can use a [regular expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) or a [glob pattern](https://github.com/isaacs/node-glob#glob-primer) to filter items by their path. The path is relative to the starting directory by default, but you can customize this via [`options.basePath`](#basepath).
> **NOTE:** Glob patterns [_always_ use forward-slashes](https://github.com/isaacs/node-glob#windows), even on Windows. This _does not_ apply to regular expressions though. Regular expressions should use the appropraite path separator for the environment. Or, you can match both types of separators using `[\\/]`.
```javascript
var readdir = require('readdir-enhanced');
// Find all .txt files
readdir('my/directory', {filter: '*.txt'});
// Find all package.json files
readdir('my/directory', {filter: '**/package.json', deep: true});
// Find everything with at least one number in the name
readdir('my/directory', {filter: /\d+/});
```
#### Custom filtering logic
For more advanced filtering, you can specify a filter function that accepts an [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object and returns a truthy value if the item should be included in the results.
> **NOTE:** The [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) object that's passed to the filter function has additional `path` and `depth` properties. The `path` is relative to the starting directory by default, but you can customize this via [`options.basePath`](#basepath). The `depth` is the number of subdirectories beneath the base path (see [`options.deep`](#deep)).
```javascript
var readdir = require('readdir-enhanced');
// Only return file names containing an underscore
function myFilter(stats) {
return stats.isFile() && stats.path.indexOf('_') >= 0;
}
readdir('my/directory', {filter: myFilter}, function(err, files) {
console.log(files);
// => __myFile.txt
// => my_other_file.txt
// => img_1.jpg
// => node_modules
});
```
<a id="basepath"></a>
### Base Path
By default all `readdir-enhanced` functions return paths that are relative to the starting directory. But you can use the `basePath` option to customize this. The `basePath` will be prepended to all of the returned paths. One common use-case for this is to set `basePath` to the absolute path of the starting directory, so that all of the returned paths will be absolute.
```javascript
var readdir = require('readdir-enhanced');
var path = require('path');
// Get absolute paths
var absPath = path.resolve('my/dir');
readdir('my/directory', {basePath: absPath}, function(err, files) {
console.log(files);
// => /absolute/path/to/my/directory/file1.txt
// => /absolute/path/to/my/directory/file2.txt
// => /absolute/path/to/my/directory/subdir
});
// Get paths relative to the working directory
readdir('my/directory', {basePath: 'my/directory'}, function(err, files) {
console.log(files);
// => my/directory/file1.txt
// => my/directory/file2.txt
// => my/directory/subdir
});
```
<a id="sep"></a>
### Path Separator
By default, `readdir-enhanced` uses the correct path separator for your OS (`\` on Windows, `/` on Linux & MacOS). But you can set the `sep` option to any separator character(s) that you want to use instead. This is usually used to ensure consistent path separators across different OSes.
```javascript
var readdir = require('readdir-enhanced');
// Always use Windows path separators
readdir('my/directory', {sep: '\\', deep: true}, function(err, files) {
console.log(files);
// => subdir1
// => subdir1\file.txt
// => subdir1\subdir2
// => subdir1\subdir2\file.txt
// => subdir1\subdir2\subdir3
// => subdir1\subdir2\subdir3\file.txt
});
```
<a id="fs"></a>
### Custom FS methods
By default, `readdir-enhanced` uses the default [Node.js FileSystem module](https://nodejs.org/api/fs.html) for methods like `fs.stat`, `fs.readdir` and `fs.lstat`. But in some situations, you can want to use your own FS methods (FTP, SSH, remote drive and etc). So you can provide your own implementation of FS methods by setting `options.fs` or specific methods, such as `options.fs.stat`.
```javascript
var readdir = require('readdir-enhanced');
function myCustomReaddirMethod(dir, callback) {
callback(null, ['__myFile.txt']);
}
var options = {
fs: {
readdir: myCustomReaddirMethod
}
};
readdir('my/directory', options, function(err, files) {
console.log(files);
// => __myFile.txt
});
```
<a id="stats"></a>
Get `fs.Stats` objects instead of strings
------------------------
All of the `readdir-enhanced` functions listed above return an array of strings (paths). But in some situations, the path isn't enough information. So, `readdir-enhanced` provides alternative versions of each function, which return an array of [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) objects instead of strings. The `fs.Stats` object contains all sorts of useful information, such as the size, the creation date/time, and helper methods such as `isFile()`, `isDirectory()`, `isSymbolicLink()`, etc.
> **NOTE:** The [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) objects that are returned also have additional `path` and `depth` properties. The `path` is relative to the starting directory by default, but you can customize this via [`options.basePath`](#basepath). The `depth` is the number of subdirectories beneath the base path (see [`options.deep`](#deep)).
To get `fs.Stats` objects instead of strings, just add the word "Stat" to the function name. As with the normal functions, each one is aliased (e.g. `readdir.async.stat` is the same as `readdir.readdirAsyncStat`), so you can use whichever naming style you prefer.
```javascript
var readdir = require('readdir-enhanced');
// Synchronous API
var stats = readdir.sync.stat('my/directory');
var stats = readdir.readdirSyncStat('my/directory');
// Async API
readdir.async.stat('my/directory', function(err, stats) { ... });
readdir.readdirAsyncStat('my/directory', function(err, stats) { ... });
// Streaming API
readdir.stream.stat('my/directory')
.on('data', function(stat) { ... })
.on('file', function(stat) { ... })
.on('directory', function(stat) { ... })
.on('symlink', function(stat) { ... });
readdir.readdirStreamStat('my/directory')
.on('data', function(stat) { ... })
.on('file', function(stat) { ... })
.on('directory', function(stat) { ... })
.on('symlink', function(stat) { ... });
```
<a id="backward-compatible"></a>
Backward Compatible
--------------------
`readdir-enhanced` is fully backward-compatible with Node.js' built-in `fs.readdir()` and `fs.readdirSync()` functions, so you can use it as a drop-in replacement in existing projects without affecting existing functionality, while still being able to use the enhanced features as needed.
```javascript
var readdir = require('readdir-enhanced');
var readdirSync = readdir.sync;
// Use it just like Node's built-in fs.readdir function
readdir('my/directory', function(err, files) { ... });
// Use it just like Node's built-in fs.readdirSync function
var files = readdirSync('my/directory');
```
Contributing
--------------------------
I welcome any contributions, enhancements, and bug-fixes. [File an issue](https://github.com/BigstickCarpet/readdir-enhanced/issues) on GitHub and [submit a pull request](https://github.com/BigstickCarpet/readdir-enhanced/pulls).
#### Building
To build the project locally on your computer:
1. __Clone this repo__<br>
`git clone https://github.com/bigstickcarpet/readdir-enhanced.git`
2. __Install dependencies__<br>
`npm install`
3. __Run the tests__<br>
`npm test`
License
--------------------------
`readdir-enhanced` is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want.

View File

@@ -0,0 +1,29 @@
'use strict';
module.exports = asyncForEach;
/**
* Simultaneously processes all items in the given array.
*
* @param {array} array - The array to iterate over
* @param {function} iterator - The function to call for each item in the array
* @param {function} done - The function to call when all iterators have completed
*/
function asyncForEach (array, iterator, done) {
if (array.length === 0) {
// NOTE: Normally a bad idea to mix sync and async, but it's safe here because
// of the way that this method is currently used by DirectoryReader.
done();
return;
}
// Simultaneously process all items in the array.
let pending = array.length;
array.forEach(item => {
iterator(item, () => {
if (--pending === 0) {
done();
}
});
});
}

View File

@@ -0,0 +1,48 @@
'use strict';
module.exports = readdirAsync;
const maybe = require('call-me-maybe');
const DirectoryReader = require('../directory-reader');
let asyncFacade = {
fs: require('fs'),
forEach: require('./for-each'),
async: true
};
/**
* Returns the buffered output from an asynchronous {@link DirectoryReader},
* via an error-first callback or a {@link Promise}.
*
* @param {string} dir
* @param {object} [options]
* @param {function} [callback]
* @param {object} internalOptions
*/
function readdirAsync (dir, options, callback, internalOptions) {
if (typeof options === 'function') {
callback = options;
options = undefined;
}
return maybe(callback, new Promise(((resolve, reject) => {
let results = [];
internalOptions.facade = asyncFacade;
let reader = new DirectoryReader(dir, options, internalOptions);
let stream = reader.stream;
stream.on('error', err => {
reject(err);
stream.pause();
});
stream.on('data', result => {
results.push(result);
});
stream.on('end', () => {
resolve(results);
});
})));
}

54
site/node_modules/@mrmlnc/readdir-enhanced/lib/call.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
'use strict';
let call = module.exports = {
safe: safeCall,
once: callOnce,
};
/**
* Calls a function with the given arguments, and ensures that the error-first callback is _always_
* invoked exactly once, even if the function throws an error.
*
* @param {function} fn - The function to invoke
* @param {...*} args - The arguments to pass to the function. The final argument must be a callback function.
*/
function safeCall (fn, args) {
// Get the function arguments as an array
args = Array.prototype.slice.call(arguments, 1);
// Replace the callback function with a wrapper that ensures it will only be called once
let callback = call.once(args.pop());
args.push(callback);
try {
fn.apply(null, args);
}
catch (err) {
callback(err);
}
}
/**
* Returns a wrapper function that ensures the given callback function is only called once.
* Subsequent calls are ignored, unless the first argument is an Error, in which case the
* error is thrown.
*
* @param {function} fn - The function that should only be called once
* @returns {function}
*/
function callOnce (fn) {
let fulfilled = false;
return function onceWrapper (err) {
if (!fulfilled) {
fulfilled = true;
return fn.apply(this, arguments);
}
else if (err) {
// The callback has already been called, but now an error has occurred
// (most likely inside the callback function). So re-throw the error,
// so it gets handled further up the call stack
throw err;
}
};
}

View File

@@ -0,0 +1,380 @@
'use strict';
const Readable = require('stream').Readable;
const EventEmitter = require('events').EventEmitter;
const path = require('path');
const normalizeOptions = require('./normalize-options');
const stat = require('./stat');
const call = require('./call');
/**
* Asynchronously reads the contents of a directory and streams the results
* via a {@link stream.Readable}.
*/
class DirectoryReader {
/**
* @param {string} dir - The absolute or relative directory path to read
* @param {object} [options] - User-specified options, if any (see {@link normalizeOptions})
* @param {object} internalOptions - Internal options that aren't part of the public API
* @class
*/
constructor (dir, options, internalOptions) {
this.options = options = normalizeOptions(options, internalOptions);
// Indicates whether we should keep reading
// This is set false if stream.Readable.push() returns false.
this.shouldRead = true;
// The directories to read
// (initialized with the top-level directory)
this.queue = [{
path: dir,
basePath: options.basePath,
posixBasePath: options.posixBasePath,
depth: 0
}];
// The number of directories that are currently being processed
this.pending = 0;
// The data that has been read, but not yet emitted
this.buffer = [];
this.stream = new Readable({ objectMode: true });
this.stream._read = () => {
// Start (or resume) reading
this.shouldRead = true;
// If we have data in the buffer, then send the next chunk
if (this.buffer.length > 0) {
this.pushFromBuffer();
}
// If we have directories queued, then start processing the next one
if (this.queue.length > 0) {
if (this.options.facade.sync) {
while (this.queue.length > 0) {
this.readNextDirectory();
}
}
else {
this.readNextDirectory();
}
}
this.checkForEOF();
};
}
/**
* Reads the next directory in the queue
*/
readNextDirectory () {
let facade = this.options.facade;
let dir = this.queue.shift();
this.pending++;
// Read the directory listing
call.safe(facade.fs.readdir, dir.path, (err, items) => {
if (err) {
// fs.readdir threw an error
this.emit('error', err);
return this.finishedReadingDirectory();
}
try {
// Process each item in the directory (simultaneously, if async)
facade.forEach(
items,
this.processItem.bind(this, dir),
this.finishedReadingDirectory.bind(this, dir)
);
}
catch (err2) {
// facade.forEach threw an error
// (probably because fs.readdir returned an invalid result)
this.emit('error', err2);
this.finishedReadingDirectory();
}
});
}
/**
* This method is called after all items in a directory have been processed.
*
* NOTE: This does not necessarily mean that the reader is finished, since there may still
* be other directories queued or pending.
*/
finishedReadingDirectory () {
this.pending--;
if (this.shouldRead) {
// If we have directories queued, then start processing the next one
if (this.queue.length > 0 && this.options.facade.async) {
this.readNextDirectory();
}
this.checkForEOF();
}
}
/**
* Determines whether the reader has finished processing all items in all directories.
* If so, then the "end" event is fired (via {@Readable#push})
*/
checkForEOF () {
if (this.buffer.length === 0 && // The stuff we've already read
this.pending === 0 && // The stuff we're currently reading
this.queue.length === 0) { // The stuff we haven't read yet
// There's no more stuff!
this.stream.push(null);
}
}
/**
* Processes a single item in a directory.
*
* If the item is a directory, and `option.deep` is enabled, then the item will be added
* to the directory queue.
*
* If the item meets the filter criteria, then it will be emitted to the reader's stream.
*
* @param {object} dir - A directory object from the queue
* @param {string} item - The name of the item (name only, no path)
* @param {function} done - A callback function that is called after the item has been processed
*/
processItem (dir, item, done) {
let stream = this.stream;
let options = this.options;
let itemPath = dir.basePath + item;
let posixPath = dir.posixBasePath + item;
let fullPath = path.join(dir.path, item);
// If `options.deep` is a number, and we've already recursed to the max depth,
// then there's no need to check fs.Stats to know if it's a directory.
// If `options.deep` is a function, then we'll need fs.Stats
let maxDepthReached = dir.depth >= options.recurseDepth;
// Do we need to call `fs.stat`?
let needStats =
!maxDepthReached || // we need the fs.Stats to know if it's a directory
options.stats || // the user wants fs.Stats objects returned
options.recurseFn || // we need fs.Stats for the recurse function
options.filterFn || // we need fs.Stats for the filter function
EventEmitter.listenerCount(stream, 'file') || // we need the fs.Stats to know if it's a file
EventEmitter.listenerCount(stream, 'directory') || // we need the fs.Stats to know if it's a directory
EventEmitter.listenerCount(stream, 'symlink'); // we need the fs.Stats to know if it's a symlink
// If we don't need stats, then exit early
if (!needStats) {
if (this.filter(itemPath, posixPath)) {
this.pushOrBuffer({ data: itemPath });
}
return done();
}
// Get the fs.Stats object for this path
stat(options.facade.fs, fullPath, (err, stats) => {
if (err) {
// fs.stat threw an error
this.emit('error', err);
return done();
}
try {
// Add the item's path to the fs.Stats object
// The base of this path, and its separators are determined by the options
// (i.e. options.basePath and options.sep)
stats.path = itemPath;
// Add depth of the path to the fs.Stats object for use this in the filter function
stats.depth = dir.depth;
if (this.shouldRecurse(stats, posixPath, maxDepthReached)) {
// Add this subdirectory to the queue
this.queue.push({
path: fullPath,
basePath: itemPath + options.sep,
posixBasePath: posixPath + '/',
depth: dir.depth + 1,
});
}
// Determine whether this item matches the filter criteria
if (this.filter(stats, posixPath)) {
this.pushOrBuffer({
data: options.stats ? stats : itemPath,
file: stats.isFile(),
directory: stats.isDirectory(),
symlink: stats.isSymbolicLink(),
});
}
done();
}
catch (err2) {
// An error occurred while processing the item
// (probably during a user-specified function, such as options.deep, options.filter, etc.)
this.emit('error', err2);
done();
}
});
}
/**
* Pushes the given chunk of data to the stream, or adds it to the buffer,
* depending on the state of the stream.
*
* @param {object} chunk
*/
pushOrBuffer (chunk) {
// Add the chunk to the buffer
this.buffer.push(chunk);
// If we're still reading, then immediately emit the next chunk in the buffer
// (which may or may not be the chunk that we just added)
if (this.shouldRead) {
this.pushFromBuffer();
}
}
/**
* Immediately pushes the next chunk in the buffer to the reader's stream.
* The "data" event will always be fired (via {@link Readable#push}).
* In addition, the "file", "directory", and/or "symlink" events may be fired,
* depending on the type of properties of the chunk.
*/
pushFromBuffer () {
let stream = this.stream;
let chunk = this.buffer.shift();
// Stream the data
try {
this.shouldRead = stream.push(chunk.data);
}
catch (err) {
this.emit('error', err);
}
// Also emit specific events, based on the type of chunk
chunk.file && this.emit('file', chunk.data);
chunk.symlink && this.emit('symlink', chunk.data);
chunk.directory && this.emit('directory', chunk.data);
}
/**
* Determines whether the given directory meets the user-specified recursion criteria.
* If the user didn't specify recursion criteria, then this function will default to true.
*
* @param {fs.Stats} stats - The directory's {@link fs.Stats} object
* @param {string} posixPath - The item's POSIX path (used for glob matching)
* @param {boolean} maxDepthReached - Whether we've already crawled the user-specified depth
* @returns {boolean}
*/
shouldRecurse (stats, posixPath, maxDepthReached) {
let options = this.options;
if (maxDepthReached) {
// We've already crawled to the maximum depth. So no more recursion.
return false;
}
else if (!stats.isDirectory()) {
// It's not a directory. So don't try to crawl it.
return false;
}
else if (options.recurseGlob) {
// Glob patterns are always tested against the POSIX path, even on Windows
// https://github.com/isaacs/node-glob#windows
return options.recurseGlob.test(posixPath);
}
else if (options.recurseRegExp) {
// Regular expressions are tested against the normal path
// (based on the OS or options.sep)
return options.recurseRegExp.test(stats.path);
}
else if (options.recurseFn) {
try {
// Run the user-specified recursion criteria
return options.recurseFn.call(null, stats);
}
catch (err) {
// An error occurred in the user's code.
// In Sync and Async modes, this will return an error.
// In Streaming mode, we emit an "error" event, but continue processing
this.emit('error', err);
}
}
else {
// No recursion function was specified, and we're within the maximum depth.
// So crawl this directory.
return true;
}
}
/**
* Determines whether the given item meets the user-specified filter criteria.
* If the user didn't specify a filter, then this function will always return true.
*
* @param {string|fs.Stats} value - Either the item's path, or the item's {@link fs.Stats} object
* @param {string} posixPath - The item's POSIX path (used for glob matching)
* @returns {boolean}
*/
filter (value, posixPath) {
let options = this.options;
if (options.filterGlob) {
// Glob patterns are always tested against the POSIX path, even on Windows
// https://github.com/isaacs/node-glob#windows
return options.filterGlob.test(posixPath);
}
else if (options.filterRegExp) {
// Regular expressions are tested against the normal path
// (based on the OS or options.sep)
return options.filterRegExp.test(value.path || value);
}
else if (options.filterFn) {
try {
// Run the user-specified filter function
return options.filterFn.call(null, value);
}
catch (err) {
// An error occurred in the user's code.
// In Sync and Async modes, this will return an error.
// In Streaming mode, we emit an "error" event, but continue processing
this.emit('error', err);
}
}
else {
// No filter was specified, so match everything
return true;
}
}
/**
* Emits an event. If one of the event listeners throws an error,
* then an "error" event is emitted.
*
* @param {string} eventName
* @param {*} data
*/
emit (eventName, data) {
let stream = this.stream;
try {
stream.emit(eventName, data);
}
catch (err) {
if (eventName === 'error') {
// Don't recursively emit "error" events.
// If the first one fails, then just throw
throw err;
}
else {
stream.emit('error', err);
}
}
}
}
module.exports = DirectoryReader;

View File

@@ -0,0 +1,85 @@
'use strict';
const readdirSync = require('./sync');
const readdirAsync = require('./async');
const readdirStream = require('./stream');
module.exports = exports = readdirAsyncPath;
exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath;
exports.readdirAsyncStat = exports.async.stat = readdirAsyncStat;
exports.readdirStream = exports.stream = readdirStreamPath;
exports.readdirStreamStat = exports.stream.stat = readdirStreamStat;
exports.readdirSync = exports.sync = readdirSyncPath;
exports.readdirSyncStat = exports.sync.stat = readdirSyncStat;
/**
* Synchronous readdir that returns an array of string paths.
*
* @param {string} dir
* @param {object} [options]
* @returns {string[]}
*/
function readdirSyncPath (dir, options) {
return readdirSync(dir, options, {});
}
/**
* Synchronous readdir that returns results as an array of {@link fs.Stats} objects
*
* @param {string} dir
* @param {object} [options]
* @returns {fs.Stats[]}
*/
function readdirSyncStat (dir, options) {
return readdirSync(dir, options, { stats: true });
}
/**
* Aynchronous readdir (accepts an error-first callback or returns a {@link Promise}).
* Results are an array of path strings.
*
* @param {string} dir
* @param {object} [options]
* @param {function} [callback]
* @returns {Promise<string[]>}
*/
function readdirAsyncPath (dir, options, callback) {
return readdirAsync(dir, options, callback, {});
}
/**
* Aynchronous readdir (accepts an error-first callback or returns a {@link Promise}).
* Results are an array of {@link fs.Stats} objects.
*
* @param {string} dir
* @param {object} [options]
* @param {function} [callback]
* @returns {Promise<fs.Stats[]>}
*/
function readdirAsyncStat (dir, options, callback) {
return readdirAsync(dir, options, callback, { stats: true });
}
/**
* Aynchronous readdir that returns a {@link stream.Readable} (which is also an {@link EventEmitter}).
* All stream data events ("data", "file", "directory", "symlink") are passed a path string.
*
* @param {string} dir
* @param {object} [options]
* @returns {stream.Readable}
*/
function readdirStreamPath (dir, options) {
return readdirStream(dir, options, {});
}
/**
* Aynchronous readdir that returns a {@link stream.Readable} (which is also an {@link EventEmitter})
* All stream data events ("data", "file", "directory", "symlink") are passed an {@link fs.Stats} object.
*
* @param {string} dir
* @param {object} [options]
* @returns {stream.Readable}
*/
function readdirStreamStat (dir, options) {
return readdirStream(dir, options, { stats: true });
}

View File

@@ -0,0 +1,177 @@
'use strict';
const path = require('path');
const globToRegExp = require('glob-to-regexp');
module.exports = normalizeOptions;
let isWindows = /^win/.test(process.platform);
/**
* @typedef {Object} FSFacade
* @property {fs.readdir} readdir
* @property {fs.stat} stat
* @property {fs.lstat} lstat
*/
/**
* Validates and normalizes the options argument
*
* @param {object} [options] - User-specified options, if any
* @param {object} internalOptions - Internal options that aren't part of the public API
*
* @param {number|boolean|function} [options.deep]
* The number of directories to recursively traverse. Any falsy value or negative number will
* default to zero, so only the top-level contents will be returned. Set to `true` or `Infinity`
* to traverse all subdirectories. Or provide a function that accepts a {@link fs.Stats} object
* and returns a truthy value if the directory's contents should be crawled.
*
* @param {function|string|RegExp} [options.filter]
* A function that accepts a {@link fs.Stats} object and returns a truthy value if the data should
* be returned. Or a RegExp or glob string pattern, to filter by file name.
*
* @param {string} [options.sep]
* The path separator to use. By default, the OS-specific separator will be used, but this can be
* set to a specific value to ensure consistency across platforms.
*
* @param {string} [options.basePath]
* The base path to prepend to each result. If empty, then all results will be relative to `dir`.
*
* @param {FSFacade} [options.fs]
* Synchronous or asynchronous facades for Node.js File System module
*
* @param {object} [internalOptions.facade]
* Synchronous or asynchronous facades for various methods, including for the Node.js File System module
*
* @param {boolean} [internalOptions.emit]
* Indicates whether the reader should emit "file", "directory", and "symlink" events
*
* @param {boolean} [internalOptions.stats]
* Indicates whether the reader should emit {@link fs.Stats} objects instead of path strings
*
* @returns {object}
*/
function normalizeOptions (options, internalOptions) {
if (options === null || options === undefined) {
options = {};
}
else if (typeof options !== 'object') {
throw new TypeError('options must be an object');
}
let recurseDepth, recurseFn, recurseRegExp, recurseGlob, deep = options.deep;
if (deep === null || deep === undefined) {
recurseDepth = 0;
}
else if (typeof deep === 'boolean') {
recurseDepth = deep ? Infinity : 0;
}
else if (typeof deep === 'number') {
if (deep < 0 || isNaN(deep)) {
throw new Error('options.deep must be a positive number');
}
else if (Math.floor(deep) !== deep) {
throw new Error('options.deep must be an integer');
}
else {
recurseDepth = deep;
}
}
else if (typeof deep === 'function') {
recurseDepth = Infinity;
recurseFn = deep;
}
else if (deep instanceof RegExp) {
recurseDepth = Infinity;
recurseRegExp = deep;
}
else if (typeof deep === 'string' && deep.length > 0) {
recurseDepth = Infinity;
recurseGlob = globToRegExp(deep, { extended: true, globstar: true });
}
else {
throw new TypeError('options.deep must be a boolean, number, function, regular expression, or glob pattern');
}
let filterFn, filterRegExp, filterGlob, filter = options.filter;
if (filter !== null && filter !== undefined) {
if (typeof filter === 'function') {
filterFn = filter;
}
else if (filter instanceof RegExp) {
filterRegExp = filter;
}
else if (typeof filter === 'string' && filter.length > 0) {
filterGlob = globToRegExp(filter, { extended: true, globstar: true });
}
else {
throw new TypeError('options.filter must be a function, regular expression, or glob pattern');
}
}
let sep = options.sep;
if (sep === null || sep === undefined) {
sep = path.sep;
}
else if (typeof sep !== 'string') {
throw new TypeError('options.sep must be a string');
}
let basePath = options.basePath;
if (basePath === null || basePath === undefined) {
basePath = '';
}
else if (typeof basePath === 'string') {
// Append a path separator to the basePath, if necessary
if (basePath && basePath.substr(-1) !== sep) {
basePath += sep;
}
}
else {
throw new TypeError('options.basePath must be a string');
}
// Convert the basePath to POSIX (forward slashes)
// so that glob pattern matching works consistently, even on Windows
let posixBasePath = basePath;
if (posixBasePath && sep !== '/') {
posixBasePath = posixBasePath.replace(new RegExp('\\' + sep, 'g'), '/');
/* istanbul ignore if */
if (isWindows) {
// Convert Windows root paths (C:\) and UNCs (\\) to POSIX root paths
posixBasePath = posixBasePath.replace(/^([a-zA-Z]\:\/|\/\/)/, '/');
}
}
// Determine which facade methods to use
let facade;
if (options.fs === null || options.fs === undefined) {
// The user didn't provide their own facades, so use our internal ones
facade = internalOptions.facade;
}
else if (typeof options.fs === 'object') {
// Merge the internal facade methods with the user-provided `fs` facades
facade = Object.assign({}, internalOptions.facade);
facade.fs = Object.assign({}, internalOptions.facade.fs, options.fs);
}
else {
throw new TypeError('options.fs must be an object');
}
return {
recurseDepth,
recurseFn,
recurseRegExp,
recurseGlob,
filterFn,
filterRegExp,
filterGlob,
sep,
basePath,
posixBasePath,
facade,
emit: !!internalOptions.emit,
stats: !!internalOptions.stats,
};
}

74
site/node_modules/@mrmlnc/readdir-enhanced/lib/stat.js generated vendored Normal file
View File

@@ -0,0 +1,74 @@
'use strict';
const call = require('./call');
module.exports = stat;
/**
* Retrieves the {@link fs.Stats} for the given path. If the path is a symbolic link,
* then the Stats of the symlink's target are returned instead. If the symlink is broken,
* then the Stats of the symlink itself are returned.
*
* @param {object} fs - Synchronous or Asynchronouse facade for the "fs" module
* @param {string} path - The path to return stats for
* @param {function} callback
*/
function stat (fs, path, callback) {
let isSymLink = false;
call.safe(fs.lstat, path, (err, lstats) => {
if (err) {
// fs.lstat threw an eror
return callback(err);
}
try {
isSymLink = lstats.isSymbolicLink();
}
catch (err2) {
// lstats.isSymbolicLink() threw an error
// (probably because fs.lstat returned an invalid result)
return callback(err2);
}
if (isSymLink) {
// Try to resolve the symlink
symlinkStat(fs, path, lstats, callback);
}
else {
// It's not a symlink, so return the stats as-is
callback(null, lstats);
}
});
}
/**
* Retrieves the {@link fs.Stats} for the target of the given symlink.
* If the symlink is broken, then the Stats of the symlink itself are returned.
*
* @param {object} fs - Synchronous or Asynchronouse facade for the "fs" module
* @param {string} path - The path of the symlink to return stats for
* @param {object} lstats - The stats of the symlink
* @param {function} callback
*/
function symlinkStat (fs, path, lstats, callback) {
call.safe(fs.stat, path, (err, stats) => {
if (err) {
// The symlink is broken, so return the stats for the link itself
return callback(null, lstats);
}
try {
// Return the stats for the resolved symlink target,
// and override the `isSymbolicLink` method to indicate that it's a symlink
stats.isSymbolicLink = () => true;
}
catch (err2) {
// Setting stats.isSymbolicLink threw an error
// (probably because fs.stat returned an invalid result)
return callback(err2);
}
callback(null, stats);
});
}

View File

@@ -0,0 +1,25 @@
'use strict';
module.exports = readdirStream;
const DirectoryReader = require('../directory-reader');
let streamFacade = {
fs: require('fs'),
forEach: require('../async/for-each'),
async: true
};
/**
* Returns the {@link stream.Readable} of an asynchronous {@link DirectoryReader}.
*
* @param {string} dir
* @param {object} [options]
* @param {object} internalOptions
*/
function readdirStream (dir, options, internalOptions) {
internalOptions.facade = streamFacade;
let reader = new DirectoryReader(dir, options, internalOptions);
return reader.stream;
}

View File

@@ -0,0 +1,22 @@
'use strict';
module.exports = syncForEach;
/**
* A facade that allows {@link Array.forEach} to be called as though it were asynchronous.
*
* @param {array} array - The array to iterate over
* @param {function} iterator - The function to call for each item in the array
* @param {function} done - The function to call when all iterators have completed
*/
function syncForEach (array, iterator, done) {
array.forEach(item => {
iterator(item, () => {
// Note: No error-handling here because this is currently only ever called
// by DirectoryReader, which never passes an `error` parameter to the callback.
// Instead, DirectoryReader emits an "error" event if an error occurs.
});
});
done();
}

View File

@@ -0,0 +1,64 @@
'use strict';
const fs = require('fs');
const call = require('../call');
/**
* A facade around {@link fs.readdirSync} that allows it to be called
* the same way as {@link fs.readdir}.
*
* @param {string} dir
* @param {function} callback
*/
exports.readdir = function (dir, callback) {
// Make sure the callback is only called once
callback = call.once(callback);
try {
let items = fs.readdirSync(dir);
callback(null, items);
}
catch (err) {
callback(err);
}
};
/**
* A facade around {@link fs.statSync} that allows it to be called
* the same way as {@link fs.stat}.
*
* @param {string} path
* @param {function} callback
*/
exports.stat = function (path, callback) {
// Make sure the callback is only called once
callback = call.once(callback);
try {
let stats = fs.statSync(path);
callback(null, stats);
}
catch (err) {
callback(err);
}
};
/**
* A facade around {@link fs.lstatSync} that allows it to be called
* the same way as {@link fs.lstat}.
*
* @param {string} path
* @param {function} callback
*/
exports.lstat = function (path, callback) {
// Make sure the callback is only called once
callback = call.once(callback);
try {
let stats = fs.lstatSync(path);
callback(null, stats);
}
catch (err) {
callback(err);
}
};

View File

@@ -0,0 +1,34 @@
'use strict';
module.exports = readdirSync;
const DirectoryReader = require('../directory-reader');
let syncFacade = {
fs: require('./fs'),
forEach: require('./for-each'),
sync: true
};
/**
* Returns the buffered output from a synchronous {@link DirectoryReader}.
*
* @param {string} dir
* @param {object} [options]
* @param {object} internalOptions
*/
function readdirSync (dir, options, internalOptions) {
internalOptions.facade = syncFacade;
let reader = new DirectoryReader(dir, options, internalOptions);
let stream = reader.stream;
let results = [];
let data = stream.read();
while (data !== null) {
results.push(data);
data = stream.read();
}
return results;
}

View File

@@ -0,0 +1,89 @@
{
"_from": "@mrmlnc/readdir-enhanced@^2.2.1",
"_id": "@mrmlnc/readdir-enhanced@2.2.1",
"_inBundle": false,
"_integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
"_location": "/@mrmlnc/readdir-enhanced",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@mrmlnc/readdir-enhanced@^2.2.1",
"name": "@mrmlnc/readdir-enhanced",
"escapedName": "@mrmlnc%2freaddir-enhanced",
"scope": "@mrmlnc",
"rawSpec": "^2.2.1",
"saveSpec": null,
"fetchSpec": "^2.2.1"
},
"_requiredBy": [
"/fast-glob"
],
"_resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
"_shasum": "524af240d1a360527b730475ecfa1344aa540dde",
"_spec": "@mrmlnc/readdir-enhanced@^2.2.1",
"_where": "/Users/pwittroc/Projects/kpt/site/node_modules/fast-glob",
"author": {
"name": "James Messinger",
"url": "http://bigstickcarpet.com"
},
"bugs": {
"url": "https://github.com/bigstickcarpet/readdir-enhanced/issues"
},
"bundleDependencies": false,
"dependencies": {
"call-me-maybe": "^1.0.1",
"glob-to-regexp": "^0.3.0"
},
"deprecated": false,
"description": "fs.readdir with sync, async, and streaming APIs + filtering, recursion, absolute paths, etc.",
"devDependencies": {
"chai": "^4.1.2",
"codacy-coverage": "^2.0.3",
"coveralls": "^3.0.0",
"del": "^3.0.0",
"eslint": "^4.15.0",
"eslint-config-modular": "^4.1.1",
"istanbul": "^0.4.5",
"mkdirp": "^0.5.1",
"mocha": "^4.1.0",
"npm-check": "^5.5.2",
"through2": "^2.0.3",
"version-bump-prompt": "^4.0.0"
},
"engines": {
"node": ">=4"
},
"files": [
"lib",
"types.d.ts"
],
"homepage": "https://github.com/bigstickcarpet/readdir-enhanced",
"keywords": [
"fs",
"readdir",
"stream",
"event",
"recursive",
"deep",
"filter",
"absolute"
],
"license": "MIT",
"main": "lib/index.js",
"name": "@mrmlnc/readdir-enhanced",
"repository": {
"type": "git",
"url": "git+https://github.com/bigstickcarpet/readdir-enhanced.git"
},
"scripts": {
"bump": "bump --prompt --tag --push --all",
"cover": "istanbul cover _mocha",
"lint": "eslint lib test --fix",
"release": "npm run upgrade && npm test && npm run bump && npm publish",
"test": "mocha && npm run lint",
"upgrade": "npm-check -u"
},
"typings": "types.d.ts",
"version": "2.2.1"
}

67
site/node_modules/@mrmlnc/readdir-enhanced/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,67 @@
/// <reference types="node" />
import fs = require('fs');
declare namespace re {
interface Entry extends fs.Stats {
path: string;
depth: number;
}
type FilterFunction = (stat: Entry) => boolean;
type Callback<T> = (err: NodeJS.ErrnoException, result: T) => void;
type CallbackString = Callback<string[]>;
type CallbackEntry = Callback<Entry[]>;
interface FileSystem {
readdir?: (path: string, callback: Callback<string[]>) => void;
lstat?: (path: string, callback: Callback<fs.Stats>) => void;
stat?: (path: string, callback: Callback<fs.Stats>) => void;
}
interface Options {
filter?: string | RegExp | FilterFunction;
deep?: boolean | number | RegExp | FilterFunction;
sep?: string;
basePath?: string;
fs?: FileSystem;
}
function stat(root: string, options?: Options): Promise<Entry[]>;
function stat(root: string, callback: CallbackEntry): void;
function stat(root: string, options: Options, callback: CallbackEntry): void;
function async(root: string, options?: Options): Promise<string[]>;
function async(root: string, callback: CallbackString): void;
function async(root: string, options: Options, callback: CallbackString): void;
function readdirAsyncStat(root: string, options?: Options): Promise<Entry[]>;
function readdirAsyncStat(root: string, callback: CallbackEntry): void;
function readdirAsyncStat(root: string, options: Options, callback: CallbackEntry): void;
namespace async {
function stat(root: string, options?: Options): Promise<Entry[]>;
function stat(root: string, callback: CallbackEntry): void;
function stat(root: string, options: Options, callback: CallbackEntry): void;
}
function stream(root: string, options?: Options): NodeJS.ReadableStream;
function readdirStreamStat(root: string, options?: Options): NodeJS.ReadableStream;
namespace stream {
function stat(root: string, options?: Options): NodeJS.ReadableStream;
}
function sync(root: string, options?: Options): string[];
function readdirSyncStat(root: string, options?: Options): Entry[];
namespace sync {
function stat(root: string, options?: Options): Entry[];
}
}
declare function re(root: string, options?: re.Options): Promise<string[]>;
declare function re(root: string, callback: re.CallbackString): void;
declare function re(root: string, options: re.Options, callback: re.CallbackString): void;
export = re;

92
site/node_modules/@nodelib/fs.stat/README.md generated vendored Normal file
View File

@@ -0,0 +1,92 @@
# @nodelib/fs.stat
> Get the status of a file with some features.
## :bulb: Highlights
Wrapper over standard methods ([`fs.lstat`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_lstat_path_callback), [`fs.stat`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_stat_path_callback)) with some features.
* :beginner: Normally follows symlinks.
* :gear: Can safely work with broken symlinks (returns information about symlink instead of generating an error).
## Install
```
$ npm install @nodelib/fs.stat
```
## Usage
```js
const fsStat = require('@nodelib/fs.stat');
fsStat.stat('path').then((stat) => {
console.log(stat); // => fs.Stats
});
```
## API
### fsStat.stat(path, [options])
Returns a [`Promise<fs.Stats>`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_class_fs_stats) for provided path.
### fsStat.statSync(path, [options])
Returns a [`fs.Stats`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_class_fs_stats) for provided path.
### fsStat.statCallback(path, [options], callback)
Returns a [`fs.Stats`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_class_fs_stats) for provided path with standard callback-style.
#### path
* Type: `string | Buffer | URL`
The `path` argument for [`fs.lstat`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_lstat_path_callback) or [`fs.stat`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_stat_path_callback) method.
#### options
* Type: `Object`
See [options](#options-1) section for more detailed information.
## Options
### throwErrorOnBrokenSymlinks
* Type: `boolean`
* Default: `true`
Throw an error or return information about symlink, when symlink is broken. When `false`, methods will be return lstat call for broken symlinks.
### followSymlinks
* Type: `boolean`
* Default: `true`
By default, the methods of this package follows symlinks. If you do not want it, set this option to `false` or use the standard method [`fs.lstat`](https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_lstat_path_callback).
### fs
* Type: `FileSystemAdapter`
* Default: `built-in FS methods`
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace each method with your own.
```ts
interface FileSystemAdapter {
lstat?: typeof fs.lstat;
stat?: typeof fs.stat;
lstatSync?: typeof fs.lstatSync;
statSync?: typeof fs.statSync;
}
```
## Changelog
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelogs for each release version.
## License
This software is released under the terms of the MIT license.

View File

@@ -0,0 +1,11 @@
/// <reference types="node" />
import * as fs from 'fs';
export interface FileSystemAdapter {
lstat: typeof fs.lstat;
stat: typeof fs.stat;
lstatSync: typeof fs.lstatSync;
statSync: typeof fs.statSync;
}
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
export declare function getFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;
//# sourceMappingURL=fs.d.ts.map

16
site/node_modules/@nodelib/fs.stat/out/adapters/fs.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
exports.FILE_SYSTEM_ADAPTER = {
lstat: fs.lstat,
stat: fs.stat,
lstatSync: fs.lstatSync,
statSync: fs.statSync
};
function getFileSystemAdapter(fsMethods) {
if (!fsMethods) {
return exports.FILE_SYSTEM_ADAPTER;
}
return Object.assign({}, exports.FILE_SYSTEM_ADAPTER, fsMethods);
}
exports.getFileSystemAdapter = getFileSystemAdapter;

22
site/node_modules/@nodelib/fs.stat/out/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,22 @@
/// <reference types="node" />
import * as fs from 'fs';
import { FileSystemAdapter } from './adapters/fs';
import { Options } from './managers/options';
import { AsyncCallback } from './providers/stat';
/**
* Asynchronous API.
*/
export declare function stat(path: fs.PathLike, opts?: Options): Promise<fs.Stats>;
/**
* Callback API.
*/
export declare function statCallback(path: fs.PathLike, callback: AsyncCallback): void;
export declare function statCallback(path: fs.PathLike, opts: Options, callback: AsyncCallback): void;
/**
* Synchronous API.
*/
export declare function statSync(path: fs.PathLike, opts?: Options): fs.Stats;
export declare type Options = Options;
export declare type StatAsyncCallback = AsyncCallback;
export declare type FileSystemAdapter = FileSystemAdapter;
//# sourceMappingURL=index.d.ts.map

31
site/node_modules/@nodelib/fs.stat/out/index.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const optionsManager = require("./managers/options");
const statProvider = require("./providers/stat");
/**
* Asynchronous API.
*/
function stat(path, opts) {
return new Promise((resolve, reject) => {
statProvider.async(path, optionsManager.prepare(opts), (err, stats) => err ? reject(err) : resolve(stats));
});
}
exports.stat = stat;
function statCallback(path, optsOrCallback, callback) {
if (typeof optsOrCallback === 'function') {
callback = optsOrCallback; /* tslint:disable-line: no-parameter-reassignment */
optsOrCallback = undefined; /* tslint:disable-line: no-parameter-reassignment */
}
if (typeof callback === 'undefined') {
throw new TypeError('The "callback" argument must be of type Function.');
}
statProvider.async(path, optionsManager.prepare(optsOrCallback), callback);
}
exports.statCallback = statCallback;
/**
* Synchronous API.
*/
function statSync(path, opts) {
return statProvider.sync(path, optionsManager.prepare(opts));
}
exports.statSync = statSync;

View File

@@ -0,0 +1,11 @@
import { FileSystemAdapter } from '../adapters/fs';
export interface Options {
fs?: Partial<FileSystemAdapter>;
throwErrorOnBrokenSymlinks?: boolean;
followSymlinks?: boolean;
}
export declare type StrictOptions = {
fs: FileSystemAdapter;
} & Required<Options>;
export declare function prepare(opts?: Options): StrictOptions;
//# sourceMappingURL=options.d.ts.map

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fsAdapter = require("../adapters/fs");
function prepare(opts) {
const options = Object.assign({
fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined),
throwErrorOnBrokenSymlinks: true,
followSymlinks: true
}, opts);
return options;
}
exports.prepare = prepare;

View File

@@ -0,0 +1,11 @@
/// <reference types="node" />
import * as fs from 'fs';
import { StrictOptions } from '../managers/options';
export declare function sync(path: fs.PathLike, options: StrictOptions): fs.Stats;
export declare type AsyncCallback = (err: NodeJS.ErrnoException | null, stats?: fs.Stats) => void;
export declare function async(path: fs.PathLike, options: StrictOptions, callback: AsyncCallback): void;
/**
* Returns `true` for followed symlink.
*/
export declare function isFollowedSymlink(stat: fs.Stats, options: StrictOptions): boolean;
//# sourceMappingURL=stat.d.ts.map

View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function sync(path, options) {
const lstat = options.fs.lstatSync(path);
if (!isFollowedSymlink(lstat, options)) {
return lstat;
}
try {
const stat = options.fs.statSync(path);
stat.isSymbolicLink = () => true;
return stat;
}
catch (err) {
if (!options.throwErrorOnBrokenSymlinks) {
return lstat;
}
throw err;
}
}
exports.sync = sync;
function async(path, options, callback) {
options.fs.lstat(path, (err0, lstat) => {
if (err0) {
return callback(err0, undefined);
}
if (!isFollowedSymlink(lstat, options)) {
return callback(null, lstat);
}
options.fs.stat(path, (err1, stat) => {
if (err1) {
return options.throwErrorOnBrokenSymlinks ? callback(err1) : callback(null, lstat);
}
stat.isSymbolicLink = () => true;
callback(null, stat);
});
});
}
exports.async = async;
/**
* Returns `true` for followed symlink.
*/
function isFollowedSymlink(stat, options) {
return stat.isSymbolicLink() && options.followSymlinks;
}
exports.isFollowedSymlink = isFollowedSymlink;

57
site/node_modules/@nodelib/fs.stat/package.json generated vendored Normal file
View File

@@ -0,0 +1,57 @@
{
"_from": "@nodelib/fs.stat@^1.1.2",
"_id": "@nodelib/fs.stat@1.1.3",
"_inBundle": false,
"_integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
"_location": "/@nodelib/fs.stat",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "@nodelib/fs.stat@^1.1.2",
"name": "@nodelib/fs.stat",
"escapedName": "@nodelib%2ffs.stat",
"scope": "@nodelib",
"rawSpec": "^1.1.2",
"saveSpec": null,
"fetchSpec": "^1.1.2"
},
"_requiredBy": [
"/fast-glob"
],
"_resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
"_shasum": "2b5a3ab3f918cca48a8c754c08168e3f03eba61b",
"_spec": "@nodelib/fs.stat@^1.1.2",
"_where": "/Users/pwittroc/Projects/kpt/site/node_modules/fast-glob",
"bundleDependencies": false,
"deprecated": false,
"description": "Get the status of a file with some features",
"engines": {
"node": ">= 6"
},
"keywords": [
"NodeLib",
"fs",
"FileSystem",
"file system",
"stat"
],
"license": "MIT",
"main": "out/index.js",
"name": "@nodelib/fs.stat",
"repository": {
"type": "git",
"url": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.stat"
},
"scripts": {
"build": "npm run clean && npm run lint && npm run compile && npm test",
"clean": "rimraf out",
"compile": "tsc -b .",
"compile:watch": "tsc -p . --watch --sourceMap",
"lint": "tslint \"src/**/*.ts\" -p . -t stylish",
"test": "mocha \"out/**/*.spec.js\" -s 0",
"watch": "npm run clean && npm run compile:watch"
},
"typings": "out/index.d.ts",
"version": "1.1.3"
}

10
site/node_modules/ansi-regex/index.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
'use strict';
module.exports = () => {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, 'g');
};

9
site/node_modules/ansi-regex/license generated vendored Normal file
View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Some files were not shown because too many files have changed in this diff Show More