mirror of
https://github.com/ko-build/ko.git
synced 2025-02-07 19:30:23 +02:00
Bump sigs.k8s.io/kind from 0.16.0 to 0.17.0 (#875)
Bumps [sigs.k8s.io/kind](https://github.com/kubernetes-sigs/kind) from 0.16.0 to 0.17.0. - [Release notes](https://github.com/kubernetes-sigs/kind/releases) - [Commits](https://github.com/kubernetes-sigs/kind/compare/v0.16.0...v0.17.0) --- updated-dependencies: - dependency-name: sigs.k8s.io/kind dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
df7549241d
commit
8fd18099d6
3
go.mod
3
go.mod
@ -20,7 +20,7 @@ require (
|
||||
golang.org/x/tools v0.2.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.25.3
|
||||
sigs.k8s.io/kind v0.16.0
|
||||
sigs.k8s.io/kind v0.17.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -75,6 +75,7 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
|
7
go.sum
7
go.sum
@ -490,6 +490,8 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI=
|
||||
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg=
|
||||
github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
|
||||
github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -1600,6 +1602,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
@ -1657,8 +1660,8 @@ mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/kind v0.16.0 h1:GFXyyxtPnHFKqXr3ZG8/X0+0K9sl69lejStlPn2WQyM=
|
||||
sigs.k8s.io/kind v0.16.0/go.mod h1:cKTqagdRyUQmihhBOd+7p43DpOPRn9rHsUC08K1Jbsk=
|
||||
sigs.k8s.io/kind v0.17.0 h1:CScmGz/wX66puA06Gj8OZb76Wmk7JIjgWf5JDvY7msM=
|
||||
sigs.k8s.io/kind v0.17.0/go.mod h1:Qqp8AiwOlMZmJWs37Hgs31xcbiYXjtXlRBSftcnZXQk=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
202
vendor/github.com/google/safetext/LICENSE
generated
vendored
Normal file
202
vendor/github.com/google/safetext/LICENSE
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
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.
|
260
vendor/github.com/google/safetext/common/common.go
generated
vendored
Normal file
260
vendor/github.com/google/safetext/common/common.go
generated
vendored
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package common implements common functionality for dealing with text/template.
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"text/template/parse"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// ContainsStringsWithSpecialCharacters determines whether an object contains interface{} strings that contain special characters.
|
||||
func ContainsStringsWithSpecialCharacters(data interface{}, special string) bool {
|
||||
if data == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
switch reflect.TypeOf(data).Kind() {
|
||||
case reflect.Ptr:
|
||||
p := reflect.ValueOf(data)
|
||||
return !p.IsNil() && ContainsStringsWithSpecialCharacters(p.Elem().Interface(), special)
|
||||
case reflect.String:
|
||||
return strings.ContainsAny(reflect.ValueOf(data).String(), special)
|
||||
case reflect.Slice, reflect.Array:
|
||||
for i := 0; i < reflect.ValueOf(data).Len(); i++ {
|
||||
if ContainsStringsWithSpecialCharacters(reflect.ValueOf(data).Index(i).Interface(), special) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
dataIter := reflect.ValueOf(data).MapRange()
|
||||
for dataIter.Next() {
|
||||
if ContainsStringsWithSpecialCharacters(dataIter.Value().Interface(), special) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
t := reflect.TypeOf(data)
|
||||
v := reflect.ValueOf(data)
|
||||
n := v.NumField()
|
||||
for i := 0; i < n; i++ {
|
||||
r, _ := utf8.DecodeRuneInString(t.Field(i).Name)
|
||||
if unicode.IsUpper(r) && ContainsStringsWithSpecialCharacters(v.Field(i).Interface(), special) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// FuncMap to register new template objects with.
|
||||
var FuncMap = map[string]interface{}{
|
||||
"textTemplateRemediationFunc": textTemplateRemediationFunc,
|
||||
"StructuralData": echo,
|
||||
}
|
||||
|
||||
func echo(in interface{}) interface{} {
|
||||
return in
|
||||
}
|
||||
|
||||
// BaselineString is a string callback function that just returns a constant string,
|
||||
// used to get a baseline of how the resultant YAML is structured.
|
||||
func BaselineString(string) string {
|
||||
return "baseline"
|
||||
}
|
||||
|
||||
// stringCallback provides the callback for how strings should be manipulated before
|
||||
// being pasted into the template execution result.
|
||||
var stringCallback func(string) string
|
||||
var stringCallbackLock sync.Mutex
|
||||
|
||||
func textTemplateRemediationFunc(data interface{}) interface{} {
|
||||
return deepCopyMutateStrings(data, stringCallback)
|
||||
}
|
||||
|
||||
// ExecuteWithCallback performs an execution on a callback-applied template
|
||||
// (WalkApplyFuncToNonDeclaractiveActions) with a specified callback.
|
||||
func ExecuteWithCallback(tmpl *template.Template, cb func(string) string, result *bytes.Buffer, data interface{}) error {
|
||||
stringCallbackLock.Lock()
|
||||
defer stringCallbackLock.Unlock()
|
||||
stringCallback = cb
|
||||
|
||||
return tmpl.Execute(result, data)
|
||||
}
|
||||
|
||||
func makePointer(data interface{}) interface{} {
|
||||
rtype := reflect.New(reflect.TypeOf(data))
|
||||
rtype.Elem().Set(reflect.ValueOf(data))
|
||||
return rtype.Interface()
|
||||
}
|
||||
|
||||
func dereference(data interface{}) interface{} {
|
||||
return reflect.ValueOf(data).Elem().Interface()
|
||||
}
|
||||
|
||||
func deepCopyMutateStrings(data interface{}, mutateF func(string) string) interface{} {
|
||||
var r interface{}
|
||||
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch reflect.TypeOf(data).Kind() {
|
||||
case reflect.Ptr:
|
||||
p := reflect.ValueOf(data)
|
||||
if p.IsNil() {
|
||||
r = data
|
||||
} else {
|
||||
c := deepCopyMutateStrings(dereference(data), mutateF)
|
||||
r = makePointer(c)
|
||||
|
||||
// Sometimes we accidentally introduce one too minterface{} layers of indirection (seems related to protobuf generated fields like ReleaseNamespace *ReleaseNamespace `... reflect:"unexport"`)
|
||||
if reflect.TypeOf(r) != reflect.TypeOf(data) {
|
||||
r = c
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
return mutateF(reflect.ValueOf(data).String())
|
||||
case reflect.Slice, reflect.Array:
|
||||
rc := reflect.MakeSlice(reflect.TypeOf(data), reflect.ValueOf(data).Len(), reflect.ValueOf(data).Len())
|
||||
for i := 0; i < reflect.ValueOf(data).Len(); i++ {
|
||||
rc.Index(i).Set(reflect.ValueOf(deepCopyMutateStrings(reflect.ValueOf(data).Index(i).Interface(), mutateF)))
|
||||
}
|
||||
r = rc.Interface()
|
||||
case reflect.Map:
|
||||
rc := reflect.MakeMap(reflect.TypeOf(data))
|
||||
dataIter := reflect.ValueOf(data).MapRange()
|
||||
for dataIter.Next() {
|
||||
rc.SetMapIndex(dataIter.Key(), reflect.ValueOf(deepCopyMutateStrings(dataIter.Value().Interface(), mutateF)))
|
||||
}
|
||||
r = rc.Interface()
|
||||
case reflect.Struct:
|
||||
s := reflect.New(reflect.TypeOf(data))
|
||||
|
||||
t := reflect.TypeOf(data)
|
||||
v := reflect.ValueOf(data)
|
||||
n := v.NumField()
|
||||
for i := 0; i < n; i++ {
|
||||
r, _ := utf8.DecodeRuneInString(t.Field(i).Name)
|
||||
|
||||
// Don't copy unexported fields
|
||||
if unicode.IsUpper(r) {
|
||||
reflect.Indirect(s).Field(i).Set(
|
||||
reflect.ValueOf(deepCopyMutateStrings(v.Field(i).Interface(), mutateF)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
r = s.Interface()
|
||||
default:
|
||||
// No other types need special handling (int, bool, etc)
|
||||
r = data
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func applyPipeCmds(cmds []*parse.CommandNode) {
|
||||
applyFunc := "textTemplateRemediationFunc"
|
||||
|
||||
for _, c := range cmds {
|
||||
newArgs := make([]parse.Node, 0)
|
||||
for i, a := range c.Args {
|
||||
switch a := a.(type) {
|
||||
case *parse.DotNode, *parse.FieldNode, *parse.VariableNode:
|
||||
if i == 0 && len(c.Args) > 1 {
|
||||
// If this is the first "argument" of multiple, then it is really a function
|
||||
newArgs = append(newArgs, a)
|
||||
} else {
|
||||
// If this node is an argument to a call to "StructuralData", then pass it through as-is
|
||||
switch identifier := c.Args[0].(type) {
|
||||
case *parse.IdentifierNode:
|
||||
if identifier.Ident == "StructuralData" {
|
||||
newArgs = append(newArgs, a)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
newPipe := &parse.PipeNode{NodeType: parse.NodePipe, Decl: nil}
|
||||
newPipe.Cmds = []*parse.CommandNode{
|
||||
&parse.CommandNode{NodeType: parse.NodeCommand, Args: []parse.Node{a}},
|
||||
&parse.CommandNode{NodeType: parse.NodeCommand, Args: []parse.Node{&parse.IdentifierNode{NodeType: parse.NodeIdentifier, Ident: applyFunc}}},
|
||||
}
|
||||
newArgs = append(newArgs, newPipe)
|
||||
}
|
||||
case *parse.PipeNode:
|
||||
applyPipeCmds(a.Cmds)
|
||||
newArgs = append(newArgs, a)
|
||||
default:
|
||||
newArgs = append(newArgs, a)
|
||||
}
|
||||
}
|
||||
|
||||
c.Args = newArgs
|
||||
}
|
||||
}
|
||||
|
||||
func branchNode(node parse.Node) *parse.BranchNode {
|
||||
switch node := node.(type) {
|
||||
case *parse.IfNode:
|
||||
return &node.BranchNode
|
||||
case *parse.RangeNode:
|
||||
return &node.BranchNode
|
||||
case *parse.WithNode:
|
||||
return &node.BranchNode
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WalkApplyFuncToNonDeclaractiveActions walks the AST, applying a pipeline function to interface{} "paste" nodes (non-declarative action nodes)
|
||||
func WalkApplyFuncToNonDeclaractiveActions(template *template.Template, node parse.Node) {
|
||||
switch node := node.(type) {
|
||||
case *parse.ActionNode:
|
||||
// Non-declarative actions are paste actions
|
||||
if len(node.Pipe.Decl) == 0 {
|
||||
applyPipeCmds(node.Pipe.Cmds)
|
||||
}
|
||||
|
||||
case *parse.IfNode, *parse.RangeNode, *parse.WithNode:
|
||||
nodeBranch := branchNode(node)
|
||||
WalkApplyFuncToNonDeclaractiveActions(template, nodeBranch.List)
|
||||
if nodeBranch.ElseList != nil {
|
||||
WalkApplyFuncToNonDeclaractiveActions(template, nodeBranch.ElseList)
|
||||
}
|
||||
case *parse.ListNode:
|
||||
for _, node := range node.Nodes {
|
||||
WalkApplyFuncToNonDeclaractiveActions(template, node)
|
||||
}
|
||||
case *parse.TemplateNode:
|
||||
tmpl := template.Lookup(node.Name)
|
||||
if tmpl != nil {
|
||||
treeCopy := tmpl.Tree.Copy()
|
||||
WalkApplyFuncToNonDeclaractiveActions(tmpl, treeCopy.Root)
|
||||
template.AddParseTree(node.Name, treeCopy)
|
||||
}
|
||||
}
|
||||
}
|
657
vendor/github.com/google/safetext/yamltemplate/yamltemplate.go
generated
vendored
Normal file
657
vendor/github.com/google/safetext/yamltemplate/yamltemplate.go
generated
vendored
Normal file
@ -0,0 +1,657 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2022 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package yamltemplate is a drop-in-replacement for using text/template to produce YAML, that adds automatic detection for YAML injection
|
||||
package yamltemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"text/template"
|
||||
"text/template/parse"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/google/safetext/common"
|
||||
)
|
||||
|
||||
// ErrInvalidYAMLTemplate indicates the requested template is not valid YAML.
|
||||
var ErrInvalidYAMLTemplate error = errors.New("Invalid YAML Template")
|
||||
|
||||
// ErrYAMLInjection indicates the inputs resulted in YAML injection.
|
||||
var ErrYAMLInjection error = errors.New("YAML Injection Detected")
|
||||
|
||||
// ExecError is the custom error type returned when Execute has an
|
||||
// error evaluating its template. (If a write error occurs, the actual
|
||||
// error is returned; it will not be of type ExecError.)
|
||||
type ExecError = template.ExecError
|
||||
|
||||
// FuncMap is the type of the map defining the mapping from names to functions.
|
||||
// Each function must have either a single return value, or two return values of
|
||||
// which the second has type error. In that case, if the second (error)
|
||||
// return value evaluates to non-nil during execution, execution terminates and
|
||||
// Execute returns that error.
|
||||
//
|
||||
// Errors returned by Execute wrap the underlying error; call errors.As to
|
||||
// uncover them.
|
||||
//
|
||||
// When template execution invokes a function with an argument list, that list
|
||||
// must be assignable to the function's parameter types. Functions meant to
|
||||
// apply to arguments of arbitrary type can use parameters of type interface{} or
|
||||
// of type reflect.Value. Similarly, functions meant to return a result of arbitrary
|
||||
// type can return interface{} or reflect.Value.
|
||||
type FuncMap = template.FuncMap
|
||||
|
||||
// Template is the representation of a parsed template. The *parse.Tree
|
||||
// field is exported only for use by html/template and should be treated
|
||||
// as unexported by all other clients.
|
||||
type Template struct {
|
||||
unsafeTemplate *template.Template
|
||||
}
|
||||
|
||||
// New allocates a new, undefined template with the given name.
|
||||
func New(name string) *Template {
|
||||
return &Template{unsafeTemplate: template.New(name).Funcs(common.FuncMap)}
|
||||
}
|
||||
|
||||
const yamlSpecialCharacters = "{}[]&*#?|-.<>=!%@:\"'`,\r\n"
|
||||
|
||||
func mapOrArray(in interface{}) bool {
|
||||
return in != nil && (reflect.TypeOf(in).Kind() == reflect.Map || reflect.TypeOf(in).Kind() == reflect.Slice || reflect.TypeOf(in).Kind() == reflect.Array)
|
||||
}
|
||||
|
||||
func allKeysMatch(base interface{}, a interface{}, b interface{}) bool {
|
||||
if base == nil {
|
||||
return a == nil && b == nil
|
||||
}
|
||||
|
||||
switch reflect.TypeOf(base).Kind() {
|
||||
case reflect.Ptr:
|
||||
if reflect.TypeOf(a).Kind() != reflect.Ptr || reflect.TypeOf(b).Kind() != reflect.Ptr {
|
||||
return false
|
||||
}
|
||||
|
||||
if !allKeysMatch(reflect.ValueOf(base).Elem().Interface(), reflect.ValueOf(a).Elem().Interface(), reflect.ValueOf(b).Elem().Interface()) {
|
||||
return true
|
||||
}
|
||||
case reflect.Map:
|
||||
if reflect.TypeOf(a).Kind() != reflect.Map || reflect.TypeOf(b).Kind() != reflect.Map {
|
||||
return false
|
||||
}
|
||||
|
||||
if reflect.ValueOf(a).Len() != reflect.ValueOf(base).Len() || reflect.ValueOf(b).Len() != reflect.ValueOf(base).Len() {
|
||||
return false
|
||||
}
|
||||
|
||||
basei := reflect.ValueOf(base).MapRange()
|
||||
for basei.Next() {
|
||||
av := reflect.ValueOf(a).MapIndex(basei.Key())
|
||||
bv := reflect.ValueOf(b).MapIndex(basei.Key())
|
||||
if !av.IsValid() || !bv.IsValid() ||
|
||||
!allKeysMatch(basei.Value().Interface(), av.Interface(), bv.Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case reflect.Slice, reflect.Array:
|
||||
if reflect.TypeOf(a).Kind() != reflect.Slice && reflect.TypeOf(a).Kind() != reflect.Array &&
|
||||
reflect.TypeOf(b).Kind() != reflect.Slice && reflect.TypeOf(b).Kind() != reflect.Array {
|
||||
return false
|
||||
}
|
||||
|
||||
if reflect.ValueOf(a).Len() != reflect.ValueOf(base).Len() || reflect.ValueOf(b).Len() != reflect.ValueOf(base).Len() {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < reflect.ValueOf(base).Len(); i++ {
|
||||
if !allKeysMatch(reflect.ValueOf(base).Index(i).Interface(), reflect.ValueOf(a).Index(i).Interface(), reflect.ValueOf(b).Index(i).Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
n := reflect.ValueOf(base).NumField()
|
||||
for i := 0; i < n; i++ {
|
||||
baseit := reflect.TypeOf(base).Field(i)
|
||||
ait := reflect.TypeOf(a).Field(i)
|
||||
bit := reflect.TypeOf(b).Field(i)
|
||||
|
||||
if baseit.Name != ait.Name || baseit.Name != bit.Name {
|
||||
return false
|
||||
}
|
||||
|
||||
// Only compare public members (private members cannot be overwritten by text/template)
|
||||
decodedName, _ := utf8.DecodeRuneInString(baseit.Name)
|
||||
if unicode.IsUpper(decodedName) {
|
||||
basei := reflect.ValueOf(base).Field(i)
|
||||
ai := reflect.ValueOf(a).Field(i)
|
||||
bi := reflect.ValueOf(b).Field(i)
|
||||
|
||||
if !allKeysMatch(basei.Interface(), ai.Interface(), bi.Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.String:
|
||||
// Baseline type of string was chosen arbitrarily, so just check that there isn't a new a map or slice/array injected, which would change the structure of the YAML
|
||||
if mapOrArray(a) || mapOrArray(b) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if reflect.TypeOf(a) != reflect.TypeOf(base) || reflect.TypeOf(b) != reflect.TypeOf(base) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func unmarshalYaml(data []byte) ([]interface{}, error) {
|
||||
r := make([]interface{}, 0)
|
||||
|
||||
decoder := yaml.NewDecoder(bytes.NewReader(data))
|
||||
for {
|
||||
var t interface{}
|
||||
err := decoder.Decode(&t)
|
||||
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err == nil {
|
||||
r = append(r, t)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Mutation algorithm
|
||||
func mutateString(s string) string {
|
||||
// Longest possible output string is 2x the original
|
||||
out := make([]rune, len(s)*2)
|
||||
|
||||
i := 0
|
||||
for _, r := range s {
|
||||
out[i] = r
|
||||
i++
|
||||
|
||||
// Don't repeat quoting-related characters so as to not allow YAML context change in the mutation result
|
||||
if r != '\\' && r != '\'' && r != '"' {
|
||||
out[i] = r
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
return string(out[:i])
|
||||
}
|
||||
|
||||
// Execute applies a parsed template to the specified data object,
|
||||
// and writes the output to wr.
|
||||
// If an error occurs executing the template or writing its output,
|
||||
// execution stops, but partial results may already have been written to
|
||||
// the output writer.
|
||||
// A template may be executed safely in parallel, although if parallel
|
||||
// executions share a Writer the output may be interleaved.
|
||||
//
|
||||
// If data is a reflect.Value, the template applies to the concrete
|
||||
// value that the reflect.Value holds, as in fmt.Print.
|
||||
func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
|
||||
if data == nil {
|
||||
return t.unsafeTemplate.Execute(wr, data)
|
||||
}
|
||||
|
||||
// An attacker may be able to cause type confusion or nil dereference panic during allKeysMatch
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = ErrYAMLInjection
|
||||
}
|
||||
}()
|
||||
|
||||
// Calculate requested result first
|
||||
var requestedResult bytes.Buffer
|
||||
|
||||
if err := t.unsafeTemplate.Execute(&requestedResult, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Fast path for if there are no YAML special characters in the input strings
|
||||
if !common.ContainsStringsWithSpecialCharacters(data, yamlSpecialCharacters) {
|
||||
// Note: We assume the result was valid YAML, and don't check for ErrInvalidYAMLTemplate
|
||||
requestedResult.WriteTo(wr)
|
||||
return nil
|
||||
}
|
||||
|
||||
walked, err := t.unsafeTemplate.Clone()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
walked.Tree = walked.Tree.Copy()
|
||||
|
||||
common.WalkApplyFuncToNonDeclaractiveActions(walked, walked.Tree.Root)
|
||||
|
||||
// Get baseline
|
||||
var baselineResult bytes.Buffer
|
||||
if err = common.ExecuteWithCallback(walked, common.BaselineString, &baselineResult, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parsedBaselineResult, err := unmarshalYaml(baselineResult.Bytes())
|
||||
if err != nil {
|
||||
return ErrInvalidYAMLTemplate
|
||||
}
|
||||
|
||||
// If baseline was valid, request must also be valid YAML for no injection to have occurred
|
||||
parsedRequestedResult, err := unmarshalYaml(requestedResult.Bytes())
|
||||
if err != nil {
|
||||
return ErrYAMLInjection
|
||||
}
|
||||
|
||||
// Mutate the input
|
||||
var mutatedResult bytes.Buffer
|
||||
if err = common.ExecuteWithCallback(walked, mutateString, &mutatedResult, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parsedMutatedResult, err := unmarshalYaml(mutatedResult.Bytes())
|
||||
if err != nil {
|
||||
return ErrYAMLInjection
|
||||
}
|
||||
|
||||
// Compare results
|
||||
if !allKeysMatch(parsedBaselineResult, parsedRequestedResult, parsedMutatedResult) {
|
||||
return ErrYAMLInjection
|
||||
}
|
||||
|
||||
requestedResult.WriteTo(wr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns the name of the template.
|
||||
func (t *Template) Name() string {
|
||||
return t.unsafeTemplate.Name()
|
||||
}
|
||||
|
||||
// New allocates a new, undefined template associated with the given one and with the same
|
||||
// delimiters. The association, which is transitive, allows one template to
|
||||
// invoke another with a {{template}} action.
|
||||
//
|
||||
// Because associated templates share underlying data, template construction
|
||||
// cannot be done safely in parallel. Once the templates are constructed, they
|
||||
// can be executed in parallel.
|
||||
func (t *Template) New(name string) *Template {
|
||||
return &Template{unsafeTemplate: t.unsafeTemplate.New(name).Funcs(common.FuncMap)}
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the template, including all associated
|
||||
// templates. The actual representation is not copied, but the name space of
|
||||
// associated templates is, so further calls to Parse in the copy will add
|
||||
// templates to the copy but not to the original. Clone can be used to prepare
|
||||
// common templates and use them with variant definitions for other templates
|
||||
// by adding the variants after the clone is made.
|
||||
func (t *Template) Clone() (*Template, error) {
|
||||
nt, err := t.unsafeTemplate.Clone()
|
||||
return &Template{unsafeTemplate: nt}, err
|
||||
}
|
||||
|
||||
// AddParseTree associates the argument parse tree with the template t, giving
|
||||
// it the specified name. If the template has not been defined, this tree becomes
|
||||
// its definition. If it has been defined and already has that name, the existing
|
||||
// definition is replaced; otherwise a new template is created, defined, and returned.
|
||||
func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) {
|
||||
nt, err := t.unsafeTemplate.AddParseTree(name, tree)
|
||||
|
||||
if nt != t.unsafeTemplate {
|
||||
return &Template{unsafeTemplate: nt}, err
|
||||
}
|
||||
return t, err
|
||||
}
|
||||
|
||||
// Option sets options for the template. Options are described by
|
||||
// strings, either a simple string or "key=value". There can be at
|
||||
// most one equals sign in an option string. If the option string
|
||||
// is unrecognized or otherwise invalid, Option panics.
|
||||
//
|
||||
// Known options:
|
||||
//
|
||||
// missingkey: Control the behavior during execution if a map is
|
||||
// indexed with a key that is not present in the map.
|
||||
//
|
||||
// "missingkey=default" or "missingkey=invalid"
|
||||
// The default behavior: Do nothing and continue execution.
|
||||
// If printed, the result of the index operation is the string
|
||||
// "<no value>".
|
||||
// "missingkey=zero"
|
||||
// The operation returns the zero value for the map type's element.
|
||||
// "missingkey=error"
|
||||
// Execution stops immediately with an error.
|
||||
func (t *Template) Option(opt ...string) *Template {
|
||||
for _, s := range opt {
|
||||
t.unsafeTemplate.Option(s)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Templates returns a slice of defined templates associated with t.
|
||||
func (t *Template) Templates() []*Template {
|
||||
s := t.unsafeTemplate.Templates()
|
||||
|
||||
var ns []*Template
|
||||
for _, nt := range s {
|
||||
ns = append(ns, &Template{unsafeTemplate: nt})
|
||||
}
|
||||
|
||||
return ns
|
||||
}
|
||||
|
||||
// ExecuteTemplate applies the template associated with t that has the given name
|
||||
// to the specified data object and writes the output to wr.
|
||||
// If an error occurs executing the template or writing its output,
|
||||
// execution stops, but partial results may already have been written to
|
||||
// the output writer.
|
||||
// A template may be executed safely in parallel, although if parallel
|
||||
// executions share a Writer the output may be interleaved.
|
||||
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
|
||||
tmpl := t.Lookup(name)
|
||||
if tmpl == nil {
|
||||
return fmt.Errorf("template: no template %q associated with template %q", name, t.Name())
|
||||
}
|
||||
return tmpl.Execute(wr, data)
|
||||
}
|
||||
|
||||
// Delims sets the action delimiters to the specified strings, to be used in
|
||||
// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template
|
||||
// definitions will inherit the settings. An empty delimiter stands for the
|
||||
// corresponding default: {{ or }}.
|
||||
// The return value is the template, so calls can be chained.
|
||||
func (t *Template) Delims(left, right string) *Template {
|
||||
t.unsafeTemplate.Delims(left, right)
|
||||
return t
|
||||
}
|
||||
|
||||
// DefinedTemplates returns a string listing the defined templates,
|
||||
// prefixed by the string "; defined templates are: ". If there are none,
|
||||
// it returns the empty string. For generating an error message here
|
||||
// and in html/template.
|
||||
func (t *Template) DefinedTemplates() string {
|
||||
return t.unsafeTemplate.DefinedTemplates()
|
||||
}
|
||||
|
||||
// Funcs adds the elements of the argument map to the template's function map.
|
||||
// It must be called before the template is parsed.
|
||||
// It panics if a value in the map is not a function with appropriate return
|
||||
// type or if the name cannot be used syntactically as a function in a template.
|
||||
// It is legal to overwrite elements of the map. The return value is the template,
|
||||
// so calls can be chained.
|
||||
func (t *Template) Funcs(funcMap FuncMap) *Template {
|
||||
t.unsafeTemplate.Funcs(funcMap)
|
||||
return t
|
||||
}
|
||||
|
||||
// Lookup returns the template with the given name that is associated with t.
|
||||
// It returns nil if there is no such template or the template has no definition.
|
||||
func (t *Template) Lookup(name string) *Template {
|
||||
nt := t.unsafeTemplate.Lookup(name)
|
||||
|
||||
if nt == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if nt != t.unsafeTemplate {
|
||||
return &Template{unsafeTemplate: nt}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// Parse parses text as a template body for t.
|
||||
// Named template definitions ({{define ...}} or {{block ...}} statements) in text
|
||||
// define additional templates associated with t and are removed from the
|
||||
// definition of t itself.
|
||||
//
|
||||
// Templates can be redefined in successive calls to Parse.
|
||||
// A template definition with a body containing only white space and comments
|
||||
// is considered empty and will not replace an existing template's body.
|
||||
// This allows using Parse to add new named template definitions without
|
||||
// overwriting the main template body.
|
||||
func (t *Template) Parse(text string) (*Template, error) {
|
||||
nt, err := t.unsafeTemplate.Parse(text)
|
||||
|
||||
if nt != t.unsafeTemplate {
|
||||
return &Template{unsafeTemplate: nt}, err
|
||||
}
|
||||
|
||||
return t, err
|
||||
}
|
||||
|
||||
// Must is a helper that wraps a call to a function returning (*Template, error)
|
||||
// and panics if the error is non-nil. It is intended for use in variable
|
||||
// initializations such as
|
||||
//
|
||||
// var t = template.Must(template.New("name").Parse("text"))
|
||||
func Must(t *Template, err error) *Template {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func readFileOS(file string) (name string, b []byte, err error) {
|
||||
name = filepath.Base(file)
|
||||
b, err = os.ReadFile(file)
|
||||
return
|
||||
}
|
||||
|
||||
func readFileFS(fsys fs.FS) func(string) (string, []byte, error) {
|
||||
return func(file string) (name string, b []byte, err error) {
|
||||
name = path.Base(file)
|
||||
b, err = fs.ReadFile(fsys, file)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func parseFiles(t *Template, readFile func(string) (string, []byte, error), filenames ...string) (*Template, error) {
|
||||
if len(filenames) == 0 {
|
||||
// Not really a problem, but be consistent.
|
||||
return nil, fmt.Errorf("template: no files named in call to ParseFiles")
|
||||
}
|
||||
for _, filename := range filenames {
|
||||
name, b, err := readFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := string(b)
|
||||
// First template becomes return value if not already defined,
|
||||
// and we use that one for subsequent New calls to associate
|
||||
// all the templates together. Also, if this file has the same name
|
||||
// as t, this file becomes the contents of t, so
|
||||
// t, err := New(name).Funcs(xxx).ParseFiles(name)
|
||||
// works. Otherwise we create a new template associated with t.
|
||||
var tmpl *Template
|
||||
if t == nil {
|
||||
t = New(name)
|
||||
}
|
||||
if name == t.Name() {
|
||||
tmpl = t
|
||||
} else {
|
||||
tmpl = t.New(name)
|
||||
}
|
||||
_, err = tmpl.Parse(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// parseGlob is the implementation of the function and method ParseGlob.
|
||||
func parseGlob(t *Template, pattern string) (*Template, error) {
|
||||
filenames, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(filenames) == 0 {
|
||||
return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
|
||||
}
|
||||
return parseFiles(t, readFileOS, filenames...)
|
||||
}
|
||||
|
||||
func parseFS(t *Template, fsys fs.FS, patterns []string) (*Template, error) {
|
||||
var filenames []string
|
||||
for _, pattern := range patterns {
|
||||
list, err := fs.Glob(fsys, pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern)
|
||||
}
|
||||
filenames = append(filenames, list...)
|
||||
}
|
||||
return parseFiles(t, readFileFS(fsys), filenames...)
|
||||
}
|
||||
|
||||
// ParseFiles creates a new Template and parses the template definitions from
|
||||
// the named files. The returned template's name will have the base name and
|
||||
// parsed contents of the first file. There must be at least one file.
|
||||
// If an error occurs, parsing stops and the returned *Template is nil.
|
||||
//
|
||||
// When parsing multiple files with the same name in different directories,
|
||||
// the last one mentioned will be the one that results.
|
||||
// For instance, ParseFiles("a/foo", "b/foo") stores "b/foo" as the template
|
||||
// named "foo", while "a/foo" is unavailable.
|
||||
func ParseFiles(filenames ...string) (*Template, error) {
|
||||
return parseFiles(nil, readFileOS, filenames...)
|
||||
}
|
||||
|
||||
// ParseFiles parses the named files and associates the resulting templates with
|
||||
// t. If an error occurs, parsing stops and the returned template is nil;
|
||||
// otherwise it is t. There must be at least one file.
|
||||
// Since the templates created by ParseFiles are named by the base
|
||||
// names of the argument files, t should usually have the name of one
|
||||
// of the (base) names of the files. If it does not, depending on t's
|
||||
// contents before calling ParseFiles, t.Execute may fail. In that
|
||||
// case use t.ExecuteTemplate to execute a valid template.
|
||||
//
|
||||
// When parsing multiple files with the same name in different directories,
|
||||
// the last one mentioned will be the one that results.
|
||||
func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
|
||||
// Ensure template is inited
|
||||
t.Option()
|
||||
|
||||
return parseFiles(t, readFileOS, filenames...)
|
||||
}
|
||||
|
||||
// ParseGlob creates a new Template and parses the template definitions from
|
||||
// the files identified by the pattern. The files are matched according to the
|
||||
// semantics of filepath.Match, and the pattern must match at least one file.
|
||||
// The returned template will have the (base) name and (parsed) contents of the
|
||||
// first file matched by the pattern. ParseGlob is equivalent to calling
|
||||
// ParseFiles with the list of files matched by the pattern.
|
||||
//
|
||||
// When parsing multiple files with the same name in different directories,
|
||||
// the last one mentioned will be the one that results.
|
||||
func ParseGlob(pattern string) (*Template, error) {
|
||||
return parseGlob(nil, pattern)
|
||||
}
|
||||
|
||||
// ParseGlob parses the template definitions in the files identified by the
|
||||
// pattern and associates the resulting templates with t. The files are matched
|
||||
// according to the semantics of filepath.Match, and the pattern must match at
|
||||
// least one file. ParseGlob is equivalent to calling t.ParseFiles with the
|
||||
// list of files matched by the pattern.
|
||||
//
|
||||
// When parsing multiple files with the same name in different directories,
|
||||
// the last one mentioned will be the one that results.
|
||||
func (t *Template) ParseGlob(pattern string) (*Template, error) {
|
||||
// Ensure template is inited
|
||||
t.Option()
|
||||
|
||||
return parseGlob(t, pattern)
|
||||
}
|
||||
|
||||
// ParseFS is like ParseFiles or ParseGlob but reads from the file system fsys
|
||||
// instead of the host operating system's file system.
|
||||
// It accepts a list of glob patterns.
|
||||
// (Note that most file names serve as glob patterns matching only themselves.)
|
||||
func ParseFS(fsys fs.FS, patterns ...string) (*Template, error) {
|
||||
return parseFS(nil, fsys, patterns)
|
||||
}
|
||||
|
||||
// ParseFS is like ParseFiles or ParseGlob but reads from the file system fsys
|
||||
// instead of the host operating system's file system.
|
||||
// It accepts a list of glob patterns.
|
||||
// (Note that most file names serve as glob patterns matching only themselves.)
|
||||
func (t *Template) ParseFS(fsys fs.FS, patterns ...string) (*Template, error) {
|
||||
// Ensure template is inited
|
||||
t.Option()
|
||||
|
||||
return parseFS(t, fsys, patterns)
|
||||
}
|
||||
|
||||
// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
|
||||
func HTMLEscape(w io.Writer, b []byte) {
|
||||
template.HTMLEscape(w, b)
|
||||
}
|
||||
|
||||
// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
|
||||
func HTMLEscapeString(s string) string {
|
||||
return template.HTMLEscapeString(s)
|
||||
}
|
||||
|
||||
// HTMLEscaper returns the escaped HTML equivalent of the textual
|
||||
// representation of its arguments.
|
||||
func HTMLEscaper(args ...interface{}) string {
|
||||
return template.HTMLEscaper(args)
|
||||
}
|
||||
|
||||
// IsTrue reports whether the value is 'true', in the sense of not the zero of its type,
|
||||
// and whether the value has a meaningful truth value. This is the definition of
|
||||
// truth used by if and other such actions.
|
||||
func IsTrue(val interface{}) (truth, ok bool) {
|
||||
return template.IsTrue(val)
|
||||
}
|
||||
|
||||
// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
|
||||
func JSEscape(w io.Writer, b []byte) {
|
||||
template.JSEscape(w, b)
|
||||
}
|
||||
|
||||
// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
|
||||
func JSEscapeString(s string) string {
|
||||
return template.JSEscapeString(s)
|
||||
}
|
||||
|
||||
// JSEscaper returns the escaped JavaScript equivalent of the textual
|
||||
// representation of its arguments.
|
||||
func JSEscaper(args ...interface{}) string {
|
||||
return template.JSEscaper(args)
|
||||
}
|
||||
|
||||
// URLQueryEscaper returns the escaped value of the textual representation of
|
||||
// its arguments in a form suitable for embedding in a URL query.
|
||||
func URLQueryEscaper(args ...interface{}) string {
|
||||
return template.URLQueryEscaper(args)
|
||||
}
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -316,6 +316,10 @@ github.com/google/go-containerregistry/pkg/v1/stream
|
||||
github.com/google/go-containerregistry/pkg/v1/tarball
|
||||
github.com/google/go-containerregistry/pkg/v1/types
|
||||
github.com/google/go-containerregistry/pkg/v1/validate
|
||||
# github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2
|
||||
## explicit; go 1.19
|
||||
github.com/google/safetext/common
|
||||
github.com/google/safetext/yamltemplate
|
||||
# github.com/hashicorp/hcl v1.0.0
|
||||
## explicit
|
||||
github.com/hashicorp/hcl
|
||||
@ -681,7 +685,7 @@ k8s.io/klog/v2/internal/severity
|
||||
k8s.io/utils/internal/third_party/forked/golang/net
|
||||
k8s.io/utils/net
|
||||
k8s.io/utils/strings/slices
|
||||
# sigs.k8s.io/kind v0.16.0
|
||||
# sigs.k8s.io/kind v0.17.0
|
||||
## explicit; go 1.14
|
||||
sigs.k8s.io/kind/pkg/apis/config/defaults
|
||||
sigs.k8s.io/kind/pkg/apis/config/v1alpha4
|
||||
|
2
vendor/sigs.k8s.io/kind/pkg/apis/config/defaults/image.go
generated
vendored
2
vendor/sigs.k8s.io/kind/pkg/apis/config/defaults/image.go
generated
vendored
@ -18,4 +18,4 @@ limitations under the License.
|
||||
package defaults
|
||||
|
||||
// Image is the default for the Config.Image field, aka the default node image.
|
||||
const Image = "kindest/node:v1.25.2@sha256:9be91e9e9cdf116809841fc77ebdb8845443c4c72fe5218f3ae9eb57fdb4bace"
|
||||
const Image = "kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1"
|
||||
|
5
vendor/sigs.k8s.io/kind/pkg/cluster/internal/create/actions/installcni/cni.go
generated
vendored
5
vendor/sigs.k8s.io/kind/pkg/cluster/internal/create/actions/installcni/cni.go
generated
vendored
@ -20,7 +20,8 @@ package installcni
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/google/safetext/yamltemplate"
|
||||
|
||||
"sigs.k8s.io/kind/pkg/errors"
|
||||
"sigs.k8s.io/kind/pkg/internal/apis/config"
|
||||
@ -69,7 +70,7 @@ func (a *action) Execute(ctx *actions.ActionContext) error {
|
||||
// their own, or use the default. The internal templating mechanism is
|
||||
// not intended for external usage and is unstable.
|
||||
if strings.Contains(manifest, "would you kindly template this file") {
|
||||
t, err := template.New("cni-manifest").Parse(manifest)
|
||||
t, err := yamltemplate.New("cni-manifest").Parse(manifest)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse CNI manifest template")
|
||||
}
|
||||
|
42
vendor/sigs.k8s.io/kind/pkg/cluster/internal/kubeadm/config.go
generated
vendored
42
vendor/sigs.k8s.io/kind/pkg/cluster/internal/kubeadm/config.go
generated
vendored
@ -21,7 +21,8 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/google/safetext/yamltemplate"
|
||||
|
||||
"sigs.k8s.io/kind/pkg/errors"
|
||||
|
||||
@ -94,8 +95,8 @@ type DerivedConfigData struct {
|
||||
AdvertiseAddress string
|
||||
// DockerStableTag is automatically derived from KubernetesVersion
|
||||
DockerStableTag string
|
||||
// SortedFeatureGateKeys allows us to iterate FeatureGates deterministically
|
||||
SortedFeatureGateKeys []string
|
||||
// SortedFeatureGates allows us to iterate FeatureGates deterministically
|
||||
SortedFeatureGates []FeatureGate
|
||||
// FeatureGatesString is of the form `Foo=true,Baz=false`
|
||||
FeatureGatesString string
|
||||
// RuntimeConfigString is of the form `Foo=true,Baz=false`
|
||||
@ -108,6 +109,11 @@ type DerivedConfigData struct {
|
||||
CgroupDriver string
|
||||
}
|
||||
|
||||
type FeatureGate struct {
|
||||
Name string
|
||||
Value bool
|
||||
}
|
||||
|
||||
// Derive automatically derives DockerStableTag if not specified
|
||||
func (c *ConfigData) Derive() {
|
||||
// default cgroup driver
|
||||
@ -130,13 +136,17 @@ func (c *ConfigData) Derive() {
|
||||
featureGateKeys = append(featureGateKeys, k)
|
||||
}
|
||||
sort.Strings(featureGateKeys)
|
||||
c.SortedFeatureGateKeys = featureGateKeys
|
||||
|
||||
// create a sorted key=value,... string of FeatureGates
|
||||
var featureGates []string
|
||||
c.SortedFeatureGates = make([]FeatureGate, 0, len(c.FeatureGates))
|
||||
featureGates := make([]string, 0, len(c.FeatureGates))
|
||||
for _, k := range featureGateKeys {
|
||||
v := c.FeatureGates[k]
|
||||
featureGates = append(featureGates, fmt.Sprintf("%s=%t", k, v))
|
||||
c.SortedFeatureGates = append(c.SortedFeatureGates, FeatureGate{
|
||||
Name: k,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
c.FeatureGatesString = strings.Join(featureGates, ",")
|
||||
|
||||
@ -173,7 +183,7 @@ kubernetesVersion: {{.KubernetesVersion}}
|
||||
clusterName: "{{.ClusterName}}"
|
||||
{{ if .KubeadmFeatureGates}}featureGates:
|
||||
{{ range $key, $value := .KubeadmFeatureGates }}
|
||||
"{{ $key }}": {{ $value }}
|
||||
"{{ (StructuralData $key) }}": {{ $value }}
|
||||
{{end}}{{end}}
|
||||
controlPlaneEndpoint: "{{ .ControlPlaneEndpoint }}"
|
||||
# on docker for mac we have to expose the api server via port forward,
|
||||
@ -272,8 +282,8 @@ evictionHard:
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
{{if .FeatureGates}}featureGates:
|
||||
{{ range $key := .SortedFeatureGateKeys }}
|
||||
"{{ $key }}": {{ index $.FeatureGates $key }}
|
||||
{{ range $index, $gate := .SortedFeatureGates }}
|
||||
"{{ (StructuralData $gate.Name) }}": {{ $gate.Value }}
|
||||
{{end}}{{end}}
|
||||
{{if ne .KubeProxyMode "None"}}
|
||||
---
|
||||
@ -283,8 +293,8 @@ metadata:
|
||||
name: config
|
||||
mode: "{{ .KubeProxyMode }}"
|
||||
{{if .FeatureGates}}featureGates:
|
||||
{{ range $key := .SortedFeatureGateKeys }}
|
||||
"{{ $key }}": {{ index $.FeatureGates $key }}
|
||||
{{ range $index, $gate := .SortedFeatureGates }}
|
||||
"{{ (StructuralData $gate.Name) }}": {{ $gate.Value }}
|
||||
{{end}}{{end}}
|
||||
iptables:
|
||||
minSyncPeriod: 1s
|
||||
@ -310,7 +320,7 @@ kubernetesVersion: {{.KubernetesVersion}}
|
||||
clusterName: "{{.ClusterName}}"
|
||||
{{ if .KubeadmFeatureGates}}featureGates:
|
||||
{{ range $key, $value := .KubeadmFeatureGates }}
|
||||
"{{ $key }}": {{ $value }}
|
||||
"{{ (StructuralData $key) }}": {{ $value }}
|
||||
{{end}}{{end}}
|
||||
controlPlaneEndpoint: "{{ .ControlPlaneEndpoint }}"
|
||||
# on docker for mac we have to expose the api server via port forward,
|
||||
@ -409,8 +419,8 @@ evictionHard:
|
||||
nodefs.inodesFree: "0%"
|
||||
imagefs.available: "0%"
|
||||
{{if .FeatureGates}}featureGates:
|
||||
{{ range $key := .SortedFeatureGateKeys }}
|
||||
"{{ $key }}": {{ index $.FeatureGates $key }}
|
||||
{{ range $index, $gate := .SortedFeatureGates }}
|
||||
"{{ (StructuralData $gate.Name) }}": {{ $gate.Value }}
|
||||
{{end}}{{end}}
|
||||
{{if .DisableLocalStorageCapacityIsolation}}localStorageCapacityIsolation: false{{end}}
|
||||
{{if ne .KubeProxyMode "None"}}
|
||||
@ -421,8 +431,8 @@ metadata:
|
||||
name: config
|
||||
mode: "{{ .KubeProxyMode }}"
|
||||
{{if .FeatureGates}}featureGates:
|
||||
{{ range $key := .SortedFeatureGateKeys }}
|
||||
"{{ $key }}": {{ index $.FeatureGates $key }}
|
||||
{{ range $index, $gate := .SortedFeatureGates }}
|
||||
"{{ (StructuralData $gate.Name) }}": {{ $gate.Value }}
|
||||
{{end}}{{end}}
|
||||
iptables:
|
||||
minSyncPeriod: 1s
|
||||
@ -476,7 +486,7 @@ func Config(data ConfigData) (config string, err error) {
|
||||
templateSource = ConfigTemplateBetaV2
|
||||
}
|
||||
|
||||
t, err := template.New("kubeadm-config").Parse(templateSource)
|
||||
t, err := yamltemplate.New("kubeadm-config").Parse(templateSource)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "failed to parse config template")
|
||||
}
|
||||
|
2
vendor/sigs.k8s.io/kind/pkg/cluster/nodeutils/util.go
generated
vendored
2
vendor/sigs.k8s.io/kind/pkg/cluster/nodeutils/util.go
generated
vendored
@ -82,7 +82,7 @@ func LoadImageArchive(n nodes.Node, image io.Reader) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := n.Command("ctr", "--namespace=k8s.io", "images", "import", "--digests", "--snapshotter="+snapshotter, "-").SetStdin(image)
|
||||
cmd := n.Command("ctr", "--namespace=k8s.io", "images", "import", "--all-platforms", "--digests", "--snapshotter="+snapshotter, "-").SetStdin(image)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return errors.Wrap(err, "failed to load image")
|
||||
}
|
||||
|
2
vendor/sigs.k8s.io/kind/pkg/cmd/kind/version/version.go
generated
vendored
2
vendor/sigs.k8s.io/kind/pkg/cmd/kind/version/version.go
generated
vendored
@ -54,7 +54,7 @@ func DisplayVersion() string {
|
||||
}
|
||||
|
||||
// versionCore is the core portion of the kind CLI version per Semantic Versioning 2.0.0
|
||||
const versionCore = "0.16.0"
|
||||
const versionCore = "0.17.0"
|
||||
|
||||
// versionPreRelease is the base pre-release portion of the kind CLI version per
|
||||
// Semantic Versioning 2.0.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user