mirror of https://github.com/helm/helm
commit
dd17d125b0
@ -1,3 +1,3 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
entries: {}
|
entries: {}
|
||||||
generated: "2020-06-23T10:01:59.2530763-07:00"
|
generated: "2020-09-09T19:50:50.198347916-04:00"
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
NAME: apollo
|
||||||
|
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
|
||||||
|
NAMESPACE: default
|
||||||
|
STATUS: deployed
|
||||||
|
REVISION: 1
|
||||||
|
TEST SUITE: None
|
@ -0,0 +1 @@
|
|||||||
|
Rollback was a success! Happy Helming!
|
@ -0,0 +1,86 @@
|
|||||||
|
---
|
||||||
|
# Source: subchart/templates/subdir/serviceaccount.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: subchart-sa
|
||||||
|
---
|
||||||
|
# Source: subchart/templates/subdir/role.yaml
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: subchart-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods"]
|
||||||
|
verbs: ["get","list","watch"]
|
||||||
|
---
|
||||||
|
# Source: subchart/templates/subdir/rolebinding.yaml
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: subchart-binding
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: subchart-role
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: subchart-sa
|
||||||
|
namespace: default
|
||||||
|
---
|
||||||
|
# Source: subchart/charts/subcharta/templates/service.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: subcharta
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: "subcharta-0.1.0"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
name: apache
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: subcharta
|
||||||
|
---
|
||||||
|
# Source: subchart/charts/subchartb/templates/service.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: subchartb
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: "subchartb-0.1.0"
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
name: nginx
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: subchartb
|
||||||
|
---
|
||||||
|
# Source: subchart/templates/service.yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: subchart
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: "subchart-0.1.0"
|
||||||
|
app.kubernetes.io/instance: "RELEASE-NAME"
|
||||||
|
kube-version/major: "1"
|
||||||
|
kube-version/minor: "20"
|
||||||
|
kube-version/version: "v1.20.0"
|
||||||
|
kube-api-version/test: v1
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
name: nginx
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: subchart
|
@ -0,0 +1,7 @@
|
|||||||
|
Release "crazy-bunny" has been upgraded. Happy Helming!
|
||||||
|
NAME: crazy-bunny
|
||||||
|
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
|
||||||
|
NAMESPACE: default
|
||||||
|
STATUS: deployed
|
||||||
|
REVISION: 3
|
||||||
|
TEST SUITE: None
|
@ -1 +1 @@
|
|||||||
version.BuildInfo{Version:"v3.4", GitCommit:"", GitTreeState:"", GoVersion:""}
|
version.BuildInfo{Version:"v3.5", GitCommit:"", GitTreeState:"", GoVersion:""}
|
||||||
|
@ -1 +1 @@
|
|||||||
version.BuildInfo{Version:"v3.4", GitCommit:"", GitTreeState:"", GoVersion:""}
|
version.BuildInfo{Version:"v3.5", GitCommit:"", GitTreeState:"", GoVersion:""}
|
||||||
|
@ -1 +1 @@
|
|||||||
v3.4
|
v3.5
|
||||||
|
@ -1 +1 @@
|
|||||||
Version: v3.4
|
Version: v3.5
|
@ -1 +1 @@
|
|||||||
version.BuildInfo{Version:"v3.4", GitCommit:"", GitTreeState:"", GoVersion:""}
|
version.BuildInfo{Version:"v3.5", GitCommit:"", GitTreeState:"", GoVersion:""}
|
||||||
|
Binary file not shown.
@ -1,13 +1,14 @@
|
|||||||
apiVersion: apiextensions.k8s.io/v1beta1
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
name: testCRDs
|
name: testcrds.testcrdgroups.example.com
|
||||||
spec:
|
spec:
|
||||||
group: testCRDGroups
|
group: testcrdgroups.example.com
|
||||||
|
version: v1alpha1
|
||||||
names:
|
names:
|
||||||
kind: TestCRD
|
kind: TestCRD
|
||||||
listKind: TestCRDList
|
listKind: TestCRDList
|
||||||
plural: TestCRDs
|
plural: testcrds
|
||||||
shortNames:
|
shortNames:
|
||||||
- tc
|
- tc
|
||||||
singular: authconfig
|
singular: authconfig
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: "{{ .Release.Name }}-testconfig"
|
||||||
|
annotations:
|
||||||
|
"helm.sh/hook": test
|
||||||
|
data:
|
||||||
|
message: Hello World
|
@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: "{{ .Release.Name }}-test"
|
||||||
|
annotations:
|
||||||
|
"helm.sh/hook": test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: test
|
||||||
|
image: "alpine:latest"
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: "{{ .Release.Name }}-testconfig"
|
||||||
|
command:
|
||||||
|
- echo
|
||||||
|
- "$message"
|
||||||
|
restartPolicy: Never
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package getter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"helm.sh/helm/v3/internal/experimental/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OCIGetter is the default HTTP(/S) backend handler
|
||||||
|
type OCIGetter struct {
|
||||||
|
opts options
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get performs a Get from repo.Getter and returns the body.
|
||||||
|
func (g *OCIGetter) Get(href string, options ...Option) (*bytes.Buffer, error) {
|
||||||
|
for _, opt := range options {
|
||||||
|
opt(&g.opts)
|
||||||
|
}
|
||||||
|
return g.get(href)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *OCIGetter) get(href string) (*bytes.Buffer, error) {
|
||||||
|
client := g.opts.registryClient
|
||||||
|
|
||||||
|
ref := strings.TrimPrefix(href, "oci://")
|
||||||
|
if version := g.opts.version; version != "" {
|
||||||
|
ref = fmt.Sprintf("%s:%s", ref, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := registry.ParseReference(ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := client.PullChart(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOCIGetter constructs a valid http/https client as a Getter
|
||||||
|
func NewOCIGetter(options ...Option) (Getter, error) {
|
||||||
|
var client OCIGetter
|
||||||
|
|
||||||
|
for _, opt := range options {
|
||||||
|
opt(&client.opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &client, nil
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEJDCCAwygAwIBAgIUcGE5xyj7IH7sZLntsHKxZHCd3awwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwYTELMAkGA1UEBhMCSU4xDzANBgNVBAgMBktlcmFsYTEOMAwGA1UEBwwFS29j
|
||||||
|
aGkxGDAWBgNVBAoMD2NoYXJ0bXVzZXVtLmNvbTEXMBUGA1UEAwwOY2hhcnRtdXNl
|
||||||
|
dW1fY2EwIBcNMjAxMjA0MDkxMjU4WhgPMjI5NDA5MTkwOTEyNThaMGExCzAJBgNV
|
||||||
|
BAYTAklOMQ8wDQYDVQQIDAZLZXJhbGExDjAMBgNVBAcMBUtvY2hpMRgwFgYDVQQK
|
||||||
|
DA9jaGFydG11c2V1bS5jb20xFzAVBgNVBAMMDmNoYXJ0bXVzZXVtX2NhMIIBIjAN
|
||||||
|
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQJi/BRWzaXlkDP48kUAWgaLtD0Y
|
||||||
|
72E30WBZDAw3S+BaYulRk1LWK1QM+ALiZQb1a6YgNvuERyywOv45pZaC2xtP6Bju
|
||||||
|
+59kwBrEtNCTNa2cSqs0hSw6NCDe+K8lpFKlTdh4c5sAkiDkMBr1R6uu7o4HvfO0
|
||||||
|
iGMZ9VUdrbf4psZIyPVRdt/sAkAKqbjQfxr6VUmMktrZNND+mwPgrhS2kPL4P+JS
|
||||||
|
zpxgpkuSUvg5DvJuypmCI0fDr6GwshqXM1ONHE0HT8MEVy1xZj9rVHt7sgQhjBX1
|
||||||
|
PsFySZrq1lSz8R864c1l+tCGlk9+1ldQjc9tBzdvCjJB+nYfTTpBUk/VKwIDAQAB
|
||||||
|
o4HRMIHOMB0GA1UdDgQWBBSv1IMZGHWsZVqJkJoPDzVLMcUivjCBngYDVR0jBIGW
|
||||||
|
MIGTgBSv1IMZGHWsZVqJkJoPDzVLMcUivqFlpGMwYTELMAkGA1UEBhMCSU4xDzAN
|
||||||
|
BgNVBAgMBktlcmFsYTEOMAwGA1UEBwwFS29jaGkxGDAWBgNVBAoMD2NoYXJ0bXVz
|
||||||
|
ZXVtLmNvbTEXMBUGA1UEAwwOY2hhcnRtdXNldW1fY2GCFHBhOcco+yB+7GS57bBy
|
||||||
|
sWRwnd2sMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAI6Fg9F8cjB9
|
||||||
|
2jJn1vZPpynSFs7XPlUBVh0YXBt+o6g7+nKInwFBPzPEQ7ZZotz3GIe4I7wYiQAn
|
||||||
|
c6TU2nnqK+9TLbJIyv6NOfikLgwrTy+dAW8wrOiu+IIzA8Gdy8z8m3B7v9RUYVhx
|
||||||
|
zoNoqCEvOIzCZKDH68PZDJrDVSuvPPK33Ywj3zxYeDNXU87BKGER0vjeVG4oTAcQ
|
||||||
|
hKJURh4IRy/eW9NWiFqvNgst7k5MldOgLIOUBh1faaxlWkjuGpfdr/EBAAr491S5
|
||||||
|
IPFU7TopsrgANnxldSzVbcgfo2nt0A976T3xZQHy3xpk1rIt55xVzT0W55NRAc7v
|
||||||
|
+9NTUOB10so=
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,21 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDejCCAmKgAwIBAgIUfSn63/ldeo1prOaxXV8I0Id6HTEwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwYTELMAkGA1UEBhMCSU4xDzANBgNVBAgMBktlcmFsYTEOMAwGA1UEBwwFS29j
|
||||||
|
aGkxGDAWBgNVBAoMD2NoYXJ0bXVzZXVtLmNvbTEXMBUGA1UEAwwOY2hhcnRtdXNl
|
||||||
|
dW1fY2EwIBcNMjAxMjA0MDkxMzIwWhgPMjI5NDA5MTkwOTEzMjBaMFwxCzAJBgNV
|
||||||
|
BAYTAklOMQ8wDQYDVQQIDAZLZXJhbGExDjAMBgNVBAcMBUtvY2hpMRgwFgYDVQQK
|
||||||
|
DA9jaGFydG11c2V1bS5jb20xEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZI
|
||||||
|
hvcNAQEBBQADggEPADCCAQoCggEBAKeCbADaK+7yrM9rQszF54334mGoSXbXY6Ca
|
||||||
|
7FKdkgmKCjeeqZ+lr+i+6WQ+O+Tn0dhlyHier42IqUw5Rzzegvl7QrhiChd8C6sW
|
||||||
|
pEqDK7Z1U+cv9gIabYd+qWDwFw67xiMNQfdZxwI/AgPzixlfsMw3ZNKM3Q0Vxtdz
|
||||||
|
EEYdEDDNgZ34Cj+KXCPpYDi2i5hZnha4wzIfbL3+z2o7sPBBLBrrsOtPdVVkxysN
|
||||||
|
HM4h7wp7w7QyOosndFvcTaX7yRA1ka0BoulCt2wdVc2ZBRPiPMySi893VCQ8zeHP
|
||||||
|
QMFDL3rGmKVLbP1to2dgf9ZgckMEwE8chm2D8Ls87F9tsK9fVlUCAwEAAaMtMCsw
|
||||||
|
EwYDVR0lBAwwCgYIKwYBBQUHAwIwFAYDVR0RBA0wC4IJMTI3LjAuMC4xMA0GCSqG
|
||||||
|
SIb3DQEBCwUAA4IBAQCi7z5U9J5DkM6eYzyyH/8p32Azrunw+ZpwtxbKq3xEkpcX
|
||||||
|
0XtbyTG2szegKF0eLr9NizgEN8M1nvaMO1zuxFMB6tCWO/MyNWH/0T4xvFnnVzJ4
|
||||||
|
OKlGSvyIuMW3wofxCLRG4Cpw750iWpJ0GwjTOu2ep5tbnEMC5Ueg55WqCAE/yDrd
|
||||||
|
nL1wZSGXy1bj5H6q8EM/4/yrzK80QkfdpbDR0NGkDO2mmAKL8d57NuASWljieyV3
|
||||||
|
Ty5C8xXw5jF2JIESvT74by8ufozUOPKmgRqySgEPgAkNm0s5a05KAi5Cpyxgdylm
|
||||||
|
CEvjni1LYGhJp9wXucF9ehKSdsw4qn9T5ire8YfI
|
||||||
|
-----END CERTIFICATE-----
|
@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEAp4JsANor7vKsz2tCzMXnjffiYahJdtdjoJrsUp2SCYoKN56p
|
||||||
|
n6Wv6L7pZD475OfR2GXIeJ6vjYipTDlHPN6C+XtCuGIKF3wLqxakSoMrtnVT5y/2
|
||||||
|
Ahpth36pYPAXDrvGIw1B91nHAj8CA/OLGV+wzDdk0ozdDRXG13MQRh0QMM2BnfgK
|
||||||
|
P4pcI+lgOLaLmFmeFrjDMh9svf7Pajuw8EEsGuuw6091VWTHKw0cziHvCnvDtDI6
|
||||||
|
iyd0W9xNpfvJEDWRrQGi6UK3bB1VzZkFE+I8zJKLz3dUJDzN4c9AwUMvesaYpUts
|
||||||
|
/W2jZ2B/1mByQwTATxyGbYPwuzzsX22wr19WVQIDAQABAoIBABw7qUSDgUAm+uWC
|
||||||
|
6KFnAd4115wqJye2qf4Z3pcWI9UjxREW1vQnkvyhoOjabHHqeL4GecGKzYAHdrF4
|
||||||
|
Pf+OaXjvQ5GcRKMsrzLJACvm6+k24UtoFAjKt4dM2/OQw/IhyAWEaIfuQ9KnGAne
|
||||||
|
dKV0MXJaK84pG+DmuLr7k9SddWskElEyxK2j0tvdyI5byRfjf5schac9M4i5ZAYV
|
||||||
|
pT+PuXZQh8L8GEY2koE+uEMpXGOstD7yUxyV8zHFyBC7FVDkqF4S8IWY+RXQtVd6
|
||||||
|
l8B8dRLjKSLBKDB+neStepcwNUyCDYiqyqsKfN7eVHDd0arPm6LeTuAsHKBw2OoN
|
||||||
|
YdAmUUkCgYEA0vb9mxsMgr0ORTZ14vWghz9K12oKPk9ajYuLTQVn8GQazp0XTIi5
|
||||||
|
Mil2I78Qj87ApzGqOyHbkEgpg0C9/mheYLOYNHC4of83kNF+pHbDi1TckwxIaIK0
|
||||||
|
rZLb3Az3zZQ2rAWZ2IgSyoeVO9RxYK/RuvPFp+UBeucuXiYoI0YlEXcCgYEAy0Sk
|
||||||
|
LTiYuLsnk21RIFK01iq4Y+4112K1NGTKu8Wm6wPaPsnLznP6339cEkbiSgbRgERE
|
||||||
|
jgOfa/CiSw5CVT9dWZuQ3OoQ83pMRb7IB0TobPmhBS/HQZ8Ocbfb6PnxQ3o1Bx7I
|
||||||
|
QuIpZFxzuTP80p1p2DMDxEl+r/DCvT/wgBKX6ZMCgYAdw1bYMSK8tytyPFK5aGnz
|
||||||
|
asyGQ6GaVNuzqIJIpYCae6UEjUkiNQ/bsdnHBUey4jpv3CPmH8q4OlYQ/GtRnyvh
|
||||||
|
fLT2gQirYjRWrBev4EmKOLi9zjfQ9s/CxTtbekDjsgtcjZW85MWx6Rr2y+wK9gMi
|
||||||
|
2w2BuF9TFZaHFd8Hyvej1QKBgAoFbU6pbqYU3AOhrRE54p54ZrTOhqsCu8pEedY+
|
||||||
|
DVeizfyweDLKdwDTx5dDFV7u7R80vmh99zscFvQ6VLzdLd4AFGk/xOwsCFyb5kKt
|
||||||
|
fAP7Xpvh2iH7FHw4w0e+Is3f1YNvWhIqEj5XbIEh9gHwLsqw4SupL+y+ousvnszB
|
||||||
|
nemvAoGBAJa7bYG8MMCFJ4OFAmkpgQzHSzq7dzOR6O4GKsQQhiZ/0nRK5l3sLcDO
|
||||||
|
9viuRfhRepJGbcQ/Hw0AVIRWU01y4mejbuxfUE/FgWBoBBvpbot2zfuJgeFAIvkY
|
||||||
|
iFsZwuxPQUFobTu2hj6gh0gOKj/LpNXHkZGbZ2zTXmK3GDYlf6bR
|
||||||
|
-----END RSA PRIVATE KEY-----
|
@ -0,0 +1,515 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kube // import "helm.sh/helm/v3/pkg/kube"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultNamespace = metav1.NamespaceDefault
|
||||||
|
|
||||||
|
func Test_waiter_deploymentReady(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
rs *appsv1.ReplicaSet
|
||||||
|
dep *appsv1.Deployment
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "deployment is ready",
|
||||||
|
args: args{
|
||||||
|
rs: newReplicaSet("foo", 1, 1),
|
||||||
|
dep: newDeployment("foo", 1, 1, 0),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deployment is not ready",
|
||||||
|
args: args{
|
||||||
|
rs: newReplicaSet("foo", 0, 0),
|
||||||
|
dep: newDeployment("foo", 1, 1, 0),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deployment is ready when maxUnavailable is set",
|
||||||
|
args: args{
|
||||||
|
rs: newReplicaSet("foo", 2, 1),
|
||||||
|
dep: newDeployment("foo", 2, 1, 1),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &waiter{
|
||||||
|
c: fake.NewSimpleClientset(),
|
||||||
|
log: nopLogger,
|
||||||
|
}
|
||||||
|
if got := w.deploymentReady(tt.args.rs, tt.args.dep); got != tt.want {
|
||||||
|
t.Errorf("deploymentReady() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_waiter_daemonSetReady(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ds *appsv1.DaemonSet
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "daemonset is ready",
|
||||||
|
args: args{
|
||||||
|
ds: newDaemonSet("foo", 0, 1, 1, 1),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "daemonset is not ready",
|
||||||
|
args: args{
|
||||||
|
ds: newDaemonSet("foo", 0, 0, 1, 1),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "daemonset pods have not been scheduled successfully",
|
||||||
|
args: args{
|
||||||
|
ds: newDaemonSet("foo", 0, 0, 1, 0),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "daemonset is ready when maxUnavailable is set",
|
||||||
|
args: args{
|
||||||
|
ds: newDaemonSet("foo", 1, 1, 2, 2),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &waiter{
|
||||||
|
c: fake.NewSimpleClientset(),
|
||||||
|
log: nopLogger,
|
||||||
|
}
|
||||||
|
if got := w.daemonSetReady(tt.args.ds); got != tt.want {
|
||||||
|
t.Errorf("daemonSetReady() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_waiter_statefulSetReady(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
sts *appsv1.StatefulSet
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "statefulset is ready",
|
||||||
|
args: args{
|
||||||
|
sts: newStatefulSet("foo", 1, 0, 1, 1),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "statefulset is not ready",
|
||||||
|
args: args{
|
||||||
|
sts: newStatefulSet("foo", 1, 0, 0, 1),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "statefulset is ready when partition is specified",
|
||||||
|
args: args{
|
||||||
|
sts: newStatefulSet("foo", 2, 1, 2, 1),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "statefulset is not ready when partition is set",
|
||||||
|
args: args{
|
||||||
|
sts: newStatefulSet("foo", 1, 1, 1, 1),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &waiter{
|
||||||
|
c: fake.NewSimpleClientset(),
|
||||||
|
log: nopLogger,
|
||||||
|
}
|
||||||
|
if got := w.statefulSetReady(tt.args.sts); got != tt.want {
|
||||||
|
t.Errorf("statefulSetReady() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_waiter_podsReadyForObject(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
namespace string
|
||||||
|
obj runtime.Object
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
existPods []corev1.Pod
|
||||||
|
want bool
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "pods ready for a replicaset",
|
||||||
|
args: args{
|
||||||
|
namespace: defaultNamespace,
|
||||||
|
obj: newReplicaSet("foo", 1, 1),
|
||||||
|
},
|
||||||
|
existPods: []corev1.Pod{
|
||||||
|
*newPodWithCondition("foo", corev1.ConditionTrue),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pods not ready for a replicaset",
|
||||||
|
args: args{
|
||||||
|
namespace: defaultNamespace,
|
||||||
|
obj: newReplicaSet("foo", 1, 1),
|
||||||
|
},
|
||||||
|
existPods: []corev1.Pod{
|
||||||
|
*newPodWithCondition("foo", corev1.ConditionFalse),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &waiter{
|
||||||
|
c: fake.NewSimpleClientset(),
|
||||||
|
log: nopLogger,
|
||||||
|
}
|
||||||
|
for _, pod := range tt.existPods {
|
||||||
|
if _, err := w.c.CoreV1().Pods(defaultNamespace).Create(context.TODO(), &pod, metav1.CreateOptions{}); err != nil {
|
||||||
|
t.Errorf("Failed to create Pod error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
got, err := w.podsReadyForObject(tt.args.namespace, tt.args.obj)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("podsReadyForObject() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("podsReadyForObject() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_waiter_jobReady(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
job *batchv1.Job
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "job is completed",
|
||||||
|
args: args{job: newJob("foo", 1, 1, 1, 0)},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job is incomplete",
|
||||||
|
args: args{job: newJob("foo", 1, 1, 0, 0)},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job is failed",
|
||||||
|
args: args{job: newJob("foo", 1, 1, 0, 1)},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &waiter{
|
||||||
|
c: fake.NewSimpleClientset(),
|
||||||
|
log: nopLogger,
|
||||||
|
}
|
||||||
|
if got := w.jobReady(tt.args.job); got != tt.want {
|
||||||
|
t.Errorf("jobReady() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_waiter_volumeReady(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
v *corev1.PersistentVolumeClaim
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "pvc is bound",
|
||||||
|
args: args{
|
||||||
|
v: newPersistentVolumeClaim("foo", corev1.ClaimBound),
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "pvc is not ready",
|
||||||
|
args: args{
|
||||||
|
v: newPersistentVolumeClaim("foo", corev1.ClaimPending),
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
w := &waiter{
|
||||||
|
c: fake.NewSimpleClientset(),
|
||||||
|
log: nopLogger,
|
||||||
|
}
|
||||||
|
if got := w.volumeReady(tt.args.v); got != tt.want {
|
||||||
|
t.Errorf("volumeReady() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDaemonSet(name string, maxUnavailable, numberReady, desiredNumberScheduled, updatedNumberScheduled int) *appsv1.DaemonSet {
|
||||||
|
return &appsv1.DaemonSet{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
},
|
||||||
|
Spec: appsv1.DaemonSetSpec{
|
||||||
|
UpdateStrategy: appsv1.DaemonSetUpdateStrategy{
|
||||||
|
Type: appsv1.RollingUpdateDaemonSetStrategyType,
|
||||||
|
RollingUpdate: &appsv1.RollingUpdateDaemonSet{
|
||||||
|
MaxUnavailable: func() *intstr.IntOrString { i := intstr.FromInt(maxUnavailable); return &i }(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": name}},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Labels: map[string]string{"name": name},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Image: "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: appsv1.DaemonSetStatus{
|
||||||
|
DesiredNumberScheduled: int32(desiredNumberScheduled),
|
||||||
|
NumberReady: int32(numberReady),
|
||||||
|
UpdatedNumberScheduled: int32(updatedNumberScheduled),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStatefulSet(name string, replicas, partition, readyReplicas, updatedReplicas int) *appsv1.StatefulSet {
|
||||||
|
return &appsv1.StatefulSet{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
},
|
||||||
|
Spec: appsv1.StatefulSetSpec{
|
||||||
|
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
|
||||||
|
Type: appsv1.RollingUpdateStatefulSetStrategyType,
|
||||||
|
RollingUpdate: &appsv1.RollingUpdateStatefulSetStrategy{
|
||||||
|
Partition: intToInt32(partition),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Replicas: intToInt32(replicas),
|
||||||
|
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": name}},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Labels: map[string]string{"name": name},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Image: "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: appsv1.StatefulSetStatus{
|
||||||
|
UpdatedReplicas: int32(updatedReplicas),
|
||||||
|
ReadyReplicas: int32(readyReplicas),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDeployment(name string, replicas, maxSurge, maxUnavailable int) *appsv1.Deployment {
|
||||||
|
return &appsv1.Deployment{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
},
|
||||||
|
Spec: appsv1.DeploymentSpec{
|
||||||
|
Strategy: appsv1.DeploymentStrategy{
|
||||||
|
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||||
|
RollingUpdate: &appsv1.RollingUpdateDeployment{
|
||||||
|
MaxUnavailable: func() *intstr.IntOrString { i := intstr.FromInt(maxUnavailable); return &i }(),
|
||||||
|
MaxSurge: func() *intstr.IntOrString { i := intstr.FromInt(maxSurge); return &i }(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Replicas: intToInt32(replicas),
|
||||||
|
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": name}},
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Labels: map[string]string{"name": name},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Image: "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newReplicaSet(name string, replicas int, readyReplicas int) *appsv1.ReplicaSet {
|
||||||
|
d := newDeployment(name, replicas, 0, 0)
|
||||||
|
return &appsv1.ReplicaSet{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
Labels: d.Spec.Selector.MatchLabels,
|
||||||
|
OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(d, d.GroupVersionKind())},
|
||||||
|
},
|
||||||
|
Spec: appsv1.ReplicaSetSpec{
|
||||||
|
Selector: d.Spec.Selector,
|
||||||
|
Replicas: intToInt32(replicas),
|
||||||
|
Template: d.Spec.Template,
|
||||||
|
},
|
||||||
|
Status: appsv1.ReplicaSetStatus{
|
||||||
|
ReadyReplicas: int32(readyReplicas),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPodWithCondition(name string, podReadyCondition corev1.ConditionStatus) *corev1.Pod {
|
||||||
|
return &corev1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
Labels: map[string]string{"name": name},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Image: "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
Conditions: []corev1.PodCondition{
|
||||||
|
{
|
||||||
|
Type: corev1.PodReady,
|
||||||
|
Status: podReadyCondition,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPersistentVolumeClaim(name string, phase corev1.PersistentVolumeClaimPhase) *corev1.PersistentVolumeClaim {
|
||||||
|
return &corev1.PersistentVolumeClaim{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
},
|
||||||
|
Status: corev1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: phase,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newJob(name string, backoffLimit, completions, succeeded, failed int) *batchv1.Job {
|
||||||
|
return &batchv1.Job{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Namespace: defaultNamespace,
|
||||||
|
},
|
||||||
|
Spec: batchv1.JobSpec{
|
||||||
|
BackoffLimit: intToInt32(backoffLimit),
|
||||||
|
Completions: intToInt32(completions),
|
||||||
|
Template: corev1.PodTemplateSpec{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: name,
|
||||||
|
Labels: map[string]string{"name": name},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
Containers: []corev1.Container{
|
||||||
|
{
|
||||||
|
Image: "nginx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: batchv1.JobStatus{
|
||||||
|
Succeeded: int32(succeeded),
|
||||||
|
Failed: int32(failed),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func intToInt32(i int) *int32 {
|
||||||
|
i32 := int32(i)
|
||||||
|
return &i32
|
||||||
|
}
|
Loading…
Reference in new issue