mirror of https://github.com/knative/client.git
Align autoscaling annotations in tests (#1531)
* Align autoscaling annotations in unit tests * Fix code style * Fix e2e tests
This commit is contained in:
parent
0e89cfccbe
commit
2b1e77de20
8
go.mod
8
go.mod
|
|
@ -18,10 +18,10 @@ require (
|
||||||
k8s.io/cli-runtime v0.21.4
|
k8s.io/cli-runtime v0.21.4
|
||||||
k8s.io/client-go v0.21.4
|
k8s.io/client-go v0.21.4
|
||||||
k8s.io/code-generator v0.21.4
|
k8s.io/code-generator v0.21.4
|
||||||
knative.dev/eventing v0.27.1-0.20211123070249-2cda8f40b5d9
|
knative.dev/eventing v0.27.1-0.20211123205351-820db20be4b2
|
||||||
knative.dev/hack v0.0.0-20211122162614-813559cefdda
|
knative.dev/hack v0.0.0-20211122162614-813559cefdda
|
||||||
knative.dev/networking v0.0.0-20211123024050-aa82452902be
|
knative.dev/networking v0.0.0-20211124064027-ea794f17c1bf
|
||||||
knative.dev/pkg v0.0.0-20211123074649-0fae0afc10ad
|
knative.dev/pkg v0.0.0-20211123135150-787aec59e70a
|
||||||
knative.dev/serving v0.27.1-0.20211123120750-26c7dc6ccc53
|
knative.dev/serving v0.27.1-0.20211124064027-e6f8e414ac9e
|
||||||
sigs.k8s.io/yaml v1.3.0
|
sigs.k8s.io/yaml v1.3.0
|
||||||
)
|
)
|
||||||
|
|
|
||||||
19
go.sum
19
go.sum
|
|
@ -1735,25 +1735,24 @@ k8s.io/legacy-cloud-providers v0.21.0/go.mod h1:bNxo7gDg+PGkBmT/MFZswLTWdSWK9kAl
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ=
|
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009 h1:0T5IaWHO3sJTEmCP6mUlBvMukxPKUQWqiI/YuiBNMiQ=
|
||||||
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
knative.dev/caching v0.0.0-20211122134815-4f6b1e562337/go.mod h1:awOzz1AtzphZ5YbuMa3ZfRTN2IqRcLaiknYYuCZPZOA=
|
knative.dev/caching v0.0.0-20211123074749-2c27e22a9971/go.mod h1:/5cq0Jmn8O7zOptuBNUh/iHgy3yS7ZJ1hyEf/8Eof08=
|
||||||
knative.dev/eventing v0.27.1-0.20211123070249-2cda8f40b5d9 h1:8GhioMgKtYTPbcEjzBsMd2g+KfUMiMurqnuD1EU9KNE=
|
knative.dev/eventing v0.27.1-0.20211123205351-820db20be4b2 h1:QwyD6phsrqx5hDplMkFZ6NJPLMSnxN3YjAw+Qnnrbpg=
|
||||||
knative.dev/eventing v0.27.1-0.20211123070249-2cda8f40b5d9/go.mod h1:fnBpTKtPOxC7WOaQY6WUiUAVBXTb44njuhTi7LXHGVc=
|
knative.dev/eventing v0.27.1-0.20211123205351-820db20be4b2/go.mod h1:fnBpTKtPOxC7WOaQY6WUiUAVBXTb44njuhTi7LXHGVc=
|
||||||
knative.dev/hack v0.0.0-20211101195839-11d193bf617b/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
knative.dev/hack v0.0.0-20211101195839-11d193bf617b/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||||
knative.dev/hack v0.0.0-20211112192837-128cf0150a69/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
knative.dev/hack v0.0.0-20211112192837-128cf0150a69/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||||
knative.dev/hack v0.0.0-20211117134436-69a2295d54ce/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
|
||||||
knative.dev/hack v0.0.0-20211122162614-813559cefdda h1:WBfGcmu5pN+RCxDotKVYtWlJVI2V4Hvah+XD9mcSR/o=
|
knative.dev/hack v0.0.0-20211122162614-813559cefdda h1:WBfGcmu5pN+RCxDotKVYtWlJVI2V4Hvah+XD9mcSR/o=
|
||||||
knative.dev/hack v0.0.0-20211122162614-813559cefdda/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
knative.dev/hack v0.0.0-20211122162614-813559cefdda/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||||
knative.dev/hack/schema v0.0.0-20211122162614-813559cefdda/go.mod h1:ffjwmdcrH5vN3mPhO8RrF2KfNnbHeCE2C60A+2cv3U0=
|
knative.dev/hack/schema v0.0.0-20211122162614-813559cefdda/go.mod h1:ffjwmdcrH5vN3mPhO8RrF2KfNnbHeCE2C60A+2cv3U0=
|
||||||
knative.dev/networking v0.0.0-20211122065314-75d86c5d4128/go.mod h1:UCDjE4GxZJat8RJohbAwwxe+U3LjRJOU2Hb2LNiNMY0=
|
|
||||||
knative.dev/networking v0.0.0-20211123024050-aa82452902be h1:E9JdH2VCkl+pfCGExsTtwW158HrSCuCCoOfYHGn+mf0=
|
|
||||||
knative.dev/networking v0.0.0-20211123024050-aa82452902be/go.mod h1:u/Biwu9curBfc1GvZE293SwEfLo84sZ6df7cymgwLvw=
|
knative.dev/networking v0.0.0-20211123024050-aa82452902be/go.mod h1:u/Biwu9curBfc1GvZE293SwEfLo84sZ6df7cymgwLvw=
|
||||||
|
knative.dev/networking v0.0.0-20211124064027-ea794f17c1bf h1:qoRaPCrq3ymaBxK7XV0JOm0Pu+sAgFlTNYQh+pBwS8k=
|
||||||
|
knative.dev/networking v0.0.0-20211124064027-ea794f17c1bf/go.mod h1:ZYtIxKNhCdg8lle16ADEyy/C0ANH9rhJokx5C9dzjDE=
|
||||||
knative.dev/pkg v0.0.0-20211101212339-96c0204a70dc/go.mod h1:SkfDk9bWIiNZD7XtILGkG7AKVyF/M6M0bGxLgl0SYL8=
|
knative.dev/pkg v0.0.0-20211101212339-96c0204a70dc/go.mod h1:SkfDk9bWIiNZD7XtILGkG7AKVyF/M6M0bGxLgl0SYL8=
|
||||||
knative.dev/pkg v0.0.0-20211120133512-d016976f2567/go.mod h1:VqUp1KWJqpTDNoiSI/heaX3uMdubImslJE2tBkP+Bbw=
|
knative.dev/pkg v0.0.0-20211120133512-d016976f2567/go.mod h1:VqUp1KWJqpTDNoiSI/heaX3uMdubImslJE2tBkP+Bbw=
|
||||||
knative.dev/pkg v0.0.0-20211123074649-0fae0afc10ad h1:d5EVnV0T5JX403WUx2scfr1tE/MY9xIY92qJoxCcm1I=
|
knative.dev/pkg v0.0.0-20211123135150-787aec59e70a h1:mgE9GdkjfPJc7KpgBox52dSy1GsQmsFTWXy+1HjEn9I=
|
||||||
knative.dev/pkg v0.0.0-20211123074649-0fae0afc10ad/go.mod h1:fZUlVceKtVNyFU6LokWGk2a9QFQXeSTtnbKOjjkQ690=
|
knative.dev/pkg v0.0.0-20211123135150-787aec59e70a/go.mod h1:fZUlVceKtVNyFU6LokWGk2a9QFQXeSTtnbKOjjkQ690=
|
||||||
knative.dev/reconciler-test v0.0.0-20211112132636-ae9e2e21972f/go.mod h1:gTsbLk496j/M9xqMpx/liyCQ0X3bwDpRtcs2Zzws364=
|
knative.dev/reconciler-test v0.0.0-20211112132636-ae9e2e21972f/go.mod h1:gTsbLk496j/M9xqMpx/liyCQ0X3bwDpRtcs2Zzws364=
|
||||||
knative.dev/serving v0.27.1-0.20211123120750-26c7dc6ccc53 h1:Sw0cdAMaOpGZ9iY2kzmoOBv9oe/mUh1ubdW+U6S7b2M=
|
knative.dev/serving v0.27.1-0.20211124064027-e6f8e414ac9e h1:/Mhn3Z9tM2T+uT/D9sSCtT7QNzwUtofmW24vGUuc9wA=
|
||||||
knative.dev/serving v0.27.1-0.20211123120750-26c7dc6ccc53/go.mod h1:lVEraTokiW04QvfhBaZh4BPn9DAeqL4Gs9yaRbVV4ks=
|
knative.dev/serving v0.27.1-0.20211124064027-e6f8e414ac9e/go.mod h1:VgFSdL4RDG+HAnRod0mtlhwrYJnVAkfuR5m/sH03/c8=
|
||||||
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
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/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
|
|
|
||||||
|
|
@ -507,9 +507,9 @@ func TestServiceCreateWithBothAnnotationAndInitScaleAsOption(t *testing.T) {
|
||||||
|
|
||||||
r := client.Recorder()
|
r := client.Recorder()
|
||||||
|
|
||||||
output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz", "--annotation", "autoscaling.knative.dev/initialScale=0", "--scale-init", "0")
|
output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz", "--annotation", autoscaling.InitialScaleAnnotationKey+"=0", "--scale-init", "0")
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
assert.Assert(t, util.ContainsAll(output, "only one of the", "--scale-init", "--annotation", "autoscaling.knative.dev/initialScale", "can be specified"))
|
assert.Assert(t, util.ContainsAll(output, "only one of the", "--scale-init", "--annotation", autoscaling.InitialScaleAnnotationKey, "can be specified"))
|
||||||
|
|
||||||
r.Validate()
|
r.Validate()
|
||||||
}
|
}
|
||||||
|
|
@ -641,7 +641,7 @@ func TestServiceCreateWithScaleServiceAnnotationsError(t *testing.T) {
|
||||||
"--annotation-service", autoscaling.InitialScaleAnnotationKey+"=1",
|
"--annotation-service", autoscaling.InitialScaleAnnotationKey+"=1",
|
||||||
"--no-wait")
|
"--no-wait")
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
assert.Assert(t, util.ContainsAll(output, "service can not have auto-scaling related annotation", "autoscaling.knative.dev/initialScale"))
|
assert.Assert(t, util.ContainsAll(output, "service can not have auto-scaling related annotation", autoscaling.InitialScaleAnnotationKey))
|
||||||
|
|
||||||
r.Validate()
|
r.Validate()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"knative.dev/serving/pkg/apis/autoscaling"
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
api_errors "k8s.io/apimachinery/pkg/api/errors"
|
api_errors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
@ -406,11 +408,11 @@ func TestServiceCreateMaxMinScale(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "1",
|
autoscaling.MinScaleAnnotationKey, "1",
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
"autoscaling.knative.dev/target", "10",
|
autoscaling.TargetAnnotationKey, "10",
|
||||||
"autoscaling.knative.dev/targetUtilizationPercentage", "50",
|
autoscaling.TargetUtilizationPercentageKey, "50",
|
||||||
"autoscaling.knative.dev/window", "10s",
|
autoscaling.WindowAnnotationKey, "10s",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -441,8 +443,8 @@ func TestServiceCreateScale(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "5",
|
autoscaling.MinScaleAnnotationKey, "5",
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -461,7 +463,7 @@ func TestServiceCreateScaleWithNegativeValue(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
expectedErrMsg := "expected 0 <= -1 <= 2147483647: autoscaling.knative.dev/maxScale"
|
expectedErrMsg := "expected 0 <= -1 <= 2147483647: " + autoscaling.MaxScaleAnnotationKey
|
||||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||||
}
|
}
|
||||||
|
|
@ -522,8 +524,8 @@ func TestServiceCreateScaleRange(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "1",
|
autoscaling.MinScaleAnnotationKey, "1",
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -551,7 +553,7 @@ func TestServiceCreateScaleRangeOnlyMin(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "1",
|
autoscaling.MinScaleAnnotationKey, "1",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -570,7 +572,7 @@ func TestServiceCreateScaleRangeOnlyMinNegative(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
expectedErrMsg := "expected 0 <= -1 <= 2147483647: autoscaling.knative.dev/minScale"
|
expectedErrMsg := "expected 0 <= -1 <= 2147483647: " + autoscaling.MinScaleAnnotationKey
|
||||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||||
}
|
}
|
||||||
|
|
@ -592,7 +594,7 @@ func TestServiceCreateScaleRangeOnlyMax(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -611,7 +613,7 @@ func TestServiceCreateScaleRangeOnlyMaxNegative(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
expectedErrMsg := "expected 0 <= -5 <= 2147483647: autoscaling.knative.dev/maxScale"
|
expectedErrMsg := "expected 0 <= -5 <= 2147483647: " + autoscaling.MaxScaleAnnotationKey
|
||||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||||
}
|
}
|
||||||
|
|
@ -1080,5 +1082,5 @@ func TestServiceCreateFromYAMLWithOverrideError(t *testing.T) {
|
||||||
_, _, _, err = fakeServiceCreate([]string{
|
_, _, _, err = fakeServiceCreate([]string{
|
||||||
"service", "create", "foo", "--filename", tempFile, "--scale", "-1"}, false)
|
"service", "create", "foo", "--filename", tempFile, "--scale", "-1"}, false)
|
||||||
assert.Assert(t, err != nil)
|
assert.Assert(t, err != nil)
|
||||||
assert.Assert(t, util.ContainsAll(err.Error(), "expected", "0", "<=", "2147483647", "autoscaling.knative.dev/maxScale"))
|
assert.Assert(t, util.ContainsAll(err.Error(), "expected", "0", "<=", "2147483647", autoscaling.MaxScaleAnnotationKey))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1500,16 +1500,16 @@ func TestServiceUpdateInitialScaleMock(t *testing.T) {
|
||||||
template := &newService.Spec.Template
|
template := &newService.Spec.Template
|
||||||
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
|
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
|
||||||
template.ObjectMeta.Annotations = map[string]string{
|
template.ObjectMeta.Annotations = map[string]string{
|
||||||
"autoscaling.knative.dev/initialScale": "1",
|
autoscaling.InitialScaleAnnotationKey: "1",
|
||||||
clientserving.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
|
clientserving.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedService := getService(svcName)
|
updatedService := getService(svcName)
|
||||||
template = &updatedService.Spec.Template
|
template = &updatedService.Spec.Template
|
||||||
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
|
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
|
||||||
template.ObjectMeta.Annotations = map[string]string{
|
template.ObjectMeta.Annotations = map[string]string{
|
||||||
"autoscaling.knative.dev/initialScale": "2",
|
autoscaling.InitialScaleAnnotationKey: "2",
|
||||||
clientserving.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
|
clientserving.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
|
||||||
}
|
}
|
||||||
|
|
||||||
r := client.Recorder()
|
r := client.Recorder()
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"knative.dev/serving/pkg/apis/autoscaling"
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/assert/cmp"
|
"gotest.tools/v3/assert/cmp"
|
||||||
|
|
||||||
|
|
@ -387,10 +389,10 @@ func TestServiceUpdateMaxMinScale(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "1",
|
autoscaling.MinScaleAnnotationKey, "1",
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
"autoscaling.knative.dev/target", "10",
|
autoscaling.TargetAnnotationKey, "10",
|
||||||
"autoscaling.knative.dev/targetUtilizationPercentage", "50",
|
autoscaling.TargetUtilizationPercentageKey, "50",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -424,8 +426,8 @@ func TestServiceUpdateScale(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "5",
|
autoscaling.MinScaleAnnotationKey, "5",
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -449,7 +451,7 @@ func TestServiceUpdateScaleWithNegativeValue(t *testing.T) {
|
||||||
t.Fatal("Expected error, got nil")
|
t.Fatal("Expected error, got nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedErrMsg := "expected 0 <= -1 <= 2147483647: autoscaling.knative.dev/maxScale"
|
expectedErrMsg := "expected 0 <= -1 <= 2147483647: " + autoscaling.MaxScaleAnnotationKey
|
||||||
|
|
||||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||||
|
|
@ -512,8 +514,8 @@ func TestServiceUpdateScaleWithRange(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "1",
|
autoscaling.MinScaleAnnotationKey, "1",
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -543,7 +545,7 @@ func TestServiceUpdateScaleMinWithRange(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/minScale", "1",
|
autoscaling.MinScaleAnnotationKey, "1",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -567,7 +569,7 @@ func TestServiceUpdateScaleMinWithRangeNegative(t *testing.T) {
|
||||||
t.Fatal("Expected error, got nil")
|
t.Fatal("Expected error, got nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedErrMsg := "expected 0 <= -1 <= 2147483647: autoscaling.knative.dev/minScale"
|
expectedErrMsg := "expected 0 <= -1 <= 2147483647: " + autoscaling.MinScaleAnnotationKey
|
||||||
|
|
||||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||||
|
|
@ -592,7 +594,7 @@ func TestServiceUpdateScaleMaxWithRange(t *testing.T) {
|
||||||
|
|
||||||
actualAnnos := template.Annotations
|
actualAnnos := template.Annotations
|
||||||
expectedAnnos := []string{
|
expectedAnnos := []string{
|
||||||
"autoscaling.knative.dev/maxScale", "5",
|
autoscaling.MaxScaleAnnotationKey, "5",
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(expectedAnnos); i += 2 {
|
for i := 0; i < len(expectedAnnos); i += 2 {
|
||||||
|
|
@ -616,7 +618,7 @@ func TestServiceUpdateScaleMaxWithRangeNegative(t *testing.T) {
|
||||||
t.Fatal("Expected error, got nil")
|
t.Fatal("Expected error, got nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedErrMsg := "expected 0 <= -5 <= 2147483647: autoscaling.knative.dev/maxScale"
|
expectedErrMsg := "expected 0 <= -5 <= 2147483647: " + autoscaling.MaxScaleAnnotationKey
|
||||||
|
|
||||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||||
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
t.Errorf("Invalid error output, expected: %s, got : '%s'", expectedErrMsg, err)
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ func TestUpdateMinScale(t *testing.T) {
|
||||||
checkAnnotationValueInt(t, template, autoscaling.MinScaleAnnotationKey, 10)
|
checkAnnotationValueInt(t, template, autoscaling.MinScaleAnnotationKey, 10)
|
||||||
// Update with invalid value
|
// Update with invalid value
|
||||||
err = UpdateMinScale(template, -1)
|
err = UpdateMinScale(template, -1)
|
||||||
assert.ErrorContains(t, err, "minScale")
|
assert.ErrorContains(t, err, "min-scale")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateMaxScale(t *testing.T) {
|
func TestUpdateMaxScale(t *testing.T) {
|
||||||
|
|
@ -166,7 +166,7 @@ func TestUpdateMaxScale(t *testing.T) {
|
||||||
checkAnnotationValueInt(t, template, autoscaling.MaxScaleAnnotationKey, 10)
|
checkAnnotationValueInt(t, template, autoscaling.MaxScaleAnnotationKey, 10)
|
||||||
// Update with invalid value
|
// Update with invalid value
|
||||||
err = UpdateMaxScale(template, -1)
|
err = UpdateMaxScale(template, -1)
|
||||||
assert.ErrorContains(t, err, "maxScale")
|
assert.ErrorContains(t, err, "max-scale")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScaleWindow(t *testing.T) {
|
func TestScaleWindow(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ func validateServiceConcurrencyTarget(r *test.KnRunResultCollector, serviceName,
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateServiceConcurrencyUtilization(r *test.KnRunResultCollector, serviceName, concurrencyUtilization string) {
|
func validateServiceConcurrencyUtilization(r *test.KnRunResultCollector, serviceName, concurrencyUtilization string) {
|
||||||
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/targetUtilizationPercentage}"
|
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/target-utilization-percentage}"
|
||||||
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
||||||
assert.Equal(r.T(), out.Stdout, concurrencyUtilization)
|
assert.Equal(r.T(), out.Stdout, concurrencyUtilization)
|
||||||
r.AssertNoError(out)
|
r.AssertNoError(out)
|
||||||
|
|
@ -282,21 +282,21 @@ func validateScaleWindow(r *test.KnRunResultCollector, serviceName, window strin
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateServiceMinScale(r *test.KnRunResultCollector, serviceName, minScale string) {
|
func validateServiceMinScale(r *test.KnRunResultCollector, serviceName, minScale string) {
|
||||||
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/minScale}"
|
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/min-scale}"
|
||||||
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
||||||
assert.Equal(r.T(), out.Stdout, minScale)
|
assert.Equal(r.T(), out.Stdout, minScale)
|
||||||
r.AssertNoError(out)
|
r.AssertNoError(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateServiceMaxScale(r *test.KnRunResultCollector, serviceName, maxScale string) {
|
func validateServiceMaxScale(r *test.KnRunResultCollector, serviceName, maxScale string) {
|
||||||
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/maxScale}"
|
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/max-scale}"
|
||||||
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
||||||
assert.Equal(r.T(), out.Stdout, maxScale)
|
assert.Equal(r.T(), out.Stdout, maxScale)
|
||||||
r.AssertNoError(out)
|
r.AssertNoError(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateServiceInitScale(r *test.KnRunResultCollector, serviceName, initScale string) {
|
func validateServiceInitScale(r *test.KnRunResultCollector, serviceName, initScale string) {
|
||||||
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/initialScale}"
|
jsonpath := "jsonpath={.items[0].spec.template.metadata.annotations.autoscaling\\.knative\\.dev/initial-scale}"
|
||||||
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
out := r.KnTest().Kn().Run("service", "list", serviceName, "-o", jsonpath)
|
||||||
assert.Equal(r.T(), out.Stdout, initScale)
|
assert.Equal(r.T(), out.Stdout, initScale)
|
||||||
r.AssertNoError(out)
|
r.AssertNoError(out)
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/rickb777/date/period"
|
"github.com/rickb777/date/period"
|
||||||
"knative.dev/eventing/pkg/apis/feature"
|
|
||||||
"knative.dev/pkg/apis"
|
"knative.dev/pkg/apis"
|
||||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||||
|
|
||||||
|
"knative.dev/eventing/pkg/apis/feature"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeliverySpec contains the delivery options for event senders,
|
// DeliverySpec contains the delivery options for event senders,
|
||||||
|
|
@ -60,6 +61,26 @@ type DeliverySpec struct {
|
||||||
// For exponential policy, backoff delay is backoffDelay*2^<numberOfRetries>.
|
// For exponential policy, backoff delay is backoffDelay*2^<numberOfRetries>.
|
||||||
// +optional
|
// +optional
|
||||||
BackoffDelay *string `json:"backoffDelay,omitempty"`
|
BackoffDelay *string `json:"backoffDelay,omitempty"`
|
||||||
|
|
||||||
|
// RetryAfterMax provides an optional upper bound on the duration specified in a "Retry-After" header
|
||||||
|
// when calculating backoff times for retrying 429 and 503 response codes. Setting the value to
|
||||||
|
// zero ("PT0S") can be used to opt-out of respecting "Retry-After" header values altogether. This
|
||||||
|
// value only takes effect if "Retry" is configured, and also depends on specific implementations
|
||||||
|
// (Channels, Sources, etc.) choosing to provide this capability.
|
||||||
|
//
|
||||||
|
// Note: This API is EXPERIMENTAL and might be changed at anytime. While this experimental
|
||||||
|
// feature is in the Alpha/Beta stage, you must provide a valid value to opt-in for
|
||||||
|
// supporting "Retry-After" headers. When the feature becomes Stable/GA "Retry-After"
|
||||||
|
// headers will be respected by default, and you can choose to specify "PT0S" to
|
||||||
|
// opt-out of supporting "Retry-After" headers.
|
||||||
|
// For more details: https://github.com/knative/eventing/issues/5811
|
||||||
|
//
|
||||||
|
// More information on Duration format:
|
||||||
|
// - https://www.iso.org/iso-8601-date-and-time-format.html
|
||||||
|
// - https://en.wikipedia.org/wiki/ISO_8601
|
||||||
|
//
|
||||||
|
// +optional
|
||||||
|
RetryAfterMax *string `json:"retryAfterMax,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *DeliverySpec) Validate(ctx context.Context) *apis.FieldError {
|
func (ds *DeliverySpec) Validate(ctx context.Context) *apis.FieldError {
|
||||||
|
|
@ -101,6 +122,18 @@ func (ds *DeliverySpec) Validate(ctx context.Context) *apis.FieldError {
|
||||||
errs = errs.Also(apis.ErrInvalidValue(*ds.BackoffDelay, "backoffDelay"))
|
errs = errs.Also(apis.ErrInvalidValue(*ds.BackoffDelay, "backoffDelay"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ds.RetryAfterMax != nil {
|
||||||
|
if feature.FromContext(ctx).IsEnabled(feature.DeliveryRetryAfter) {
|
||||||
|
p, me := period.Parse(*ds.RetryAfterMax)
|
||||||
|
if me != nil || p.IsNegative() {
|
||||||
|
errs = errs.Also(apis.ErrInvalidValue(*ds.RetryAfterMax, "retryAfterMax"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errs = errs.Also(apis.ErrDisallowedFields("retryAfterMax"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,11 @@ func (in *DeliverySpec) DeepCopyInto(out *DeliverySpec) {
|
||||||
*out = new(string)
|
*out = new(string)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.RetryAfterMax != nil {
|
||||||
|
in, out := &in.RetryAfterMax, &out.RetryAfterMax
|
||||||
|
*out = new(string)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,10 @@ limitations under the License.
|
||||||
package feature
|
package feature
|
||||||
|
|
||||||
const (
|
const (
|
||||||
KReferenceGroup = "kreference-group"
|
KReferenceGroup = "kreference-group"
|
||||||
DeliveryTimeout = "delivery-timeout"
|
DeliveryRetryAfter = "delivery-retryafter"
|
||||||
KReferenceMapping = "kreference-mapping"
|
DeliveryTimeout = "delivery-timeout"
|
||||||
StrictSubscriber = "strict-subscriber"
|
KReferenceMapping = "kreference-mapping"
|
||||||
NewTriggerFilters = "new-trigger-filters"
|
StrictSubscriber = "strict-subscriber"
|
||||||
|
NewTriggerFilters = "new-trigger-filters"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -84,10 +84,6 @@ type metricsConfig struct {
|
||||||
// If duration is less than or equal to zero, it enables the default behavior.
|
// If duration is less than or equal to zero, it enables the default behavior.
|
||||||
reportingPeriod time.Duration
|
reportingPeriod time.Duration
|
||||||
|
|
||||||
// recorder provides a hook for performing custom transformations before
|
|
||||||
// writing the metrics to the stats.RecordWithOptions interface.
|
|
||||||
recorder func(context.Context, []stats.Measurement, ...stats.Options) error
|
|
||||||
|
|
||||||
// secret contains credentials for an exporter to use for authentication.
|
// secret contains credentials for an exporter to use for authentication.
|
||||||
secret *corev1.Secret
|
secret *corev1.Secret
|
||||||
|
|
||||||
|
|
@ -117,16 +113,13 @@ func (mc *metricsConfig) record(ctx context.Context, mss []stats.Measurement, ro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if mc.recorder == nil {
|
opt, err := optionForResource(metricskey.GetResource(ctx))
|
||||||
opt, err := optionForResource(metricskey.GetResource(ctx))
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
ros = append(ros, opt)
|
|
||||||
|
|
||||||
return stats.RecordWithOptions(ctx, append(ros, stats.WithMeasurements(mss...))...)
|
|
||||||
}
|
}
|
||||||
return mc.recorder(ctx, mss, ros...)
|
ros = append(ros, opt)
|
||||||
|
|
||||||
|
return stats.RecordWithOptions(ctx, append(ros, stats.WithMeasurements(mss...))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMetricsConfig(_ context.Context, ops ExporterOptions) (*metricsConfig, error) {
|
func createMetricsConfig(_ context.Context, ops ExporterOptions) (*metricsConfig, error) {
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"knative.dev/pkg/apis"
|
"knative.dev/pkg/apis"
|
||||||
|
"knative.dev/pkg/kmap"
|
||||||
"knative.dev/serving/pkg/autoscaler/config/autoscalerconfig"
|
"knative.dev/serving/pkg/autoscaler/config/autoscalerconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getIntGE0(m map[string]string, k string) (int32, *apis.FieldError) {
|
func getIntGE0(m map[string]string, key kmap.KeyPriority) (int32, *apis.FieldError) {
|
||||||
v, ok := m[k]
|
k, v, ok := key.Get(m)
|
||||||
if !ok {
|
if !ok {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
@ -62,107 +63,109 @@ func ValidateAnnotations(ctx context.Context, config *autoscalerconfig.Config, a
|
||||||
Also(validateInitialScale(config, anns))
|
Also(validateInitialScale(config, anns))
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateClass(annotations map[string]string) *apis.FieldError {
|
func validateClass(m map[string]string) *apis.FieldError {
|
||||||
if c, ok := annotations[ClassAnnotationKey]; ok {
|
if k, v, ok := ClassAnnotation.Get(m); ok {
|
||||||
if strings.HasSuffix(c, domain) && c != KPA && c != HPA {
|
if strings.HasSuffix(v, domain) && v != KPA && v != HPA {
|
||||||
return apis.ErrInvalidValue(c, ClassAnnotationKey)
|
return apis.ErrInvalidValue(v, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateAlgorithm(annotations map[string]string) *apis.FieldError {
|
func validateAlgorithm(m map[string]string) *apis.FieldError {
|
||||||
// Not a KPA? Don't validate, custom autoscalers might have custom values.
|
// Not a KPA? Don't validate, custom autoscalers might have custom values.
|
||||||
if c := annotations[ClassAnnotationKey]; c != KPA {
|
if _, v, _ := ClassAnnotation.Get(m); v != KPA {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if a := annotations[MetricAggregationAlgorithmKey]; a != "" {
|
if k, v, _ := MetricAggregationAlgorithmAnnotation.Get(m); v != "" {
|
||||||
switch a {
|
switch v {
|
||||||
case MetricAggregationAlgorithmLinear, MetricAggregationAlgorithmWeightedExponential:
|
case MetricAggregationAlgorithmLinear,
|
||||||
|
MetricAggregationAlgorithmWeightedExponential,
|
||||||
|
MetricAggregationAlgorithmWeightedExponentialAlt:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return apis.ErrInvalidValue(a, MetricAggregationAlgorithmKey)
|
return apis.ErrInvalidValue(v, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateFloats(annotations map[string]string) (errs *apis.FieldError) {
|
func validateFloats(m map[string]string) (errs *apis.FieldError) {
|
||||||
if v, ok := annotations[PanicWindowPercentageAnnotationKey]; ok {
|
if k, v, ok := PanicWindowPercentageAnnotation.Get(m); ok {
|
||||||
if fv, err := strconv.ParseFloat(v, 64); err != nil {
|
if fv, err := strconv.ParseFloat(v, 64); err != nil {
|
||||||
errs = errs.Also(apis.ErrInvalidValue(v, PanicWindowPercentageAnnotationKey))
|
errs = errs.Also(apis.ErrInvalidValue(v, k))
|
||||||
} else if fv < PanicWindowPercentageMin || fv > PanicWindowPercentageMax {
|
} else if fv < PanicWindowPercentageMin || fv > PanicWindowPercentageMax {
|
||||||
errs = apis.ErrOutOfBoundsValue(v, PanicWindowPercentageMin,
|
errs = apis.ErrOutOfBoundsValue(v, PanicWindowPercentageMin,
|
||||||
PanicWindowPercentageMax, PanicWindowPercentageAnnotationKey)
|
PanicWindowPercentageMax, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v, ok := annotations[PanicThresholdPercentageAnnotationKey]; ok {
|
if k, v, ok := PanicThresholdPercentageAnnotation.Get(m); ok {
|
||||||
if fv, err := strconv.ParseFloat(v, 64); err != nil {
|
if fv, err := strconv.ParseFloat(v, 64); err != nil {
|
||||||
errs = errs.Also(apis.ErrInvalidValue(v, PanicThresholdPercentageAnnotationKey))
|
errs = errs.Also(apis.ErrInvalidValue(v, k))
|
||||||
} else if fv < PanicThresholdPercentageMin || fv > PanicThresholdPercentageMax {
|
} else if fv < PanicThresholdPercentageMin || fv > PanicThresholdPercentageMax {
|
||||||
errs = errs.Also(apis.ErrOutOfBoundsValue(v, PanicThresholdPercentageMin,
|
errs = errs.Also(apis.ErrOutOfBoundsValue(v, PanicThresholdPercentageMin,
|
||||||
PanicThresholdPercentageMax, PanicThresholdPercentageAnnotationKey))
|
PanicThresholdPercentageMax, k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, ok := annotations[TargetAnnotationKey]; ok {
|
if k, v, ok := TargetAnnotation.Get(m); ok {
|
||||||
if fv, err := strconv.ParseFloat(v, 64); err != nil || fv < TargetMin {
|
if fv, err := strconv.ParseFloat(v, 64); err != nil || fv < TargetMin {
|
||||||
errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("target %s should be at least %g", v, TargetMin), TargetAnnotationKey))
|
errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("target %s should be at least %g", v, TargetMin), k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, ok := annotations[TargetUtilizationPercentageKey]; ok {
|
if k, v, ok := TargetUtilizationPercentageAnnotation.Get(m); ok {
|
||||||
if fv, err := strconv.ParseFloat(v, 64); err != nil {
|
if fv, err := strconv.ParseFloat(v, 64); err != nil {
|
||||||
errs = errs.Also(apis.ErrInvalidValue(v, TargetUtilizationPercentageKey))
|
errs = errs.Also(apis.ErrInvalidValue(v, k))
|
||||||
} else if fv < 1 || fv > 100 {
|
} else if fv < 1 || fv > 100 {
|
||||||
errs = errs.Also(apis.ErrOutOfBoundsValue(v, 1, 100, TargetUtilizationPercentageKey))
|
errs = errs.Also(apis.ErrOutOfBoundsValue(v, 1, 100, k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, ok := annotations[TargetBurstCapacityKey]; ok {
|
if k, v, ok := TargetBurstCapacityAnnotation.Get(m); ok {
|
||||||
if fv, err := strconv.ParseFloat(v, 64); err != nil || fv < 0 && fv != -1 {
|
if fv, err := strconv.ParseFloat(v, 64); err != nil || fv < 0 && fv != -1 {
|
||||||
errs = errs.Also(apis.ErrInvalidValue(v, TargetBurstCapacityKey))
|
errs = errs.Also(apis.ErrInvalidValue(v, k))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateScaleDownDelay(annotations map[string]string) *apis.FieldError {
|
func validateScaleDownDelay(m map[string]string) *apis.FieldError {
|
||||||
var errs *apis.FieldError
|
var errs *apis.FieldError
|
||||||
if w, ok := annotations[ScaleDownDelayAnnotationKey]; ok {
|
if k, v, ok := ScaleDownDelayAnnotation.Get(m); ok {
|
||||||
if d, err := time.ParseDuration(w); err != nil {
|
if d, err := time.ParseDuration(v); err != nil {
|
||||||
errs = apis.ErrInvalidValue(w, ScaleDownDelayAnnotationKey)
|
errs = apis.ErrInvalidValue(v, k)
|
||||||
} else if d < 0 || d > WindowMax {
|
} else if d < 0 || d > WindowMax {
|
||||||
// Since we disallow windows longer than WindowMax, so we should limit this
|
// Since we disallow windows longer than WindowMax, so we should limit this
|
||||||
// as well.
|
// as well.
|
||||||
errs = apis.ErrOutOfBoundsValue(w, 0*time.Second, WindowMax, ScaleDownDelayAnnotationKey)
|
errs = apis.ErrOutOfBoundsValue(v, 0*time.Second, WindowMax, k)
|
||||||
} else if d.Round(time.Second) != d {
|
} else if d.Round(time.Second) != d {
|
||||||
errs = apis.ErrGeneric("must be specified with at most second precision", ScaleDownDelayAnnotationKey)
|
errs = apis.ErrGeneric("must be specified with at most second precision", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateLastPodRetention(annotations map[string]string) *apis.FieldError {
|
func validateLastPodRetention(m map[string]string) *apis.FieldError {
|
||||||
if w, ok := annotations[ScaleToZeroPodRetentionPeriodKey]; ok {
|
if k, v, ok := ScaleToZeroPodRetentionPeriodAnnotation.Get(m); ok {
|
||||||
if d, err := time.ParseDuration(w); err != nil {
|
if d, err := time.ParseDuration(v); err != nil {
|
||||||
return apis.ErrInvalidValue(w, ScaleToZeroPodRetentionPeriodKey)
|
return apis.ErrInvalidValue(v, k)
|
||||||
} else if d < 0 || d > WindowMax {
|
} else if d < 0 || d > WindowMax {
|
||||||
// Since we disallow windows longer than WindowMax, so we should limit this
|
// Since we disallow windows longer than WindowMax, so we should limit this
|
||||||
// as well.
|
// as well.
|
||||||
return apis.ErrOutOfBoundsValue(w, time.Duration(0), WindowMax, ScaleToZeroPodRetentionPeriodKey)
|
return apis.ErrOutOfBoundsValue(v, time.Duration(0), WindowMax, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateWindow(annotations map[string]string) *apis.FieldError {
|
func validateWindow(m map[string]string) *apis.FieldError {
|
||||||
if w, ok := annotations[WindowAnnotationKey]; ok {
|
if _, v, ok := WindowAnnotation.Get(m); ok {
|
||||||
switch d, err := time.ParseDuration(w); {
|
switch d, err := time.ParseDuration(v); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return apis.ErrInvalidValue(w, WindowAnnotationKey)
|
return apis.ErrInvalidValue(v, WindowAnnotationKey)
|
||||||
case d < WindowMin || d > WindowMax:
|
case d < WindowMin || d > WindowMax:
|
||||||
return apis.ErrOutOfBoundsValue(w, WindowMin, WindowMax, WindowAnnotationKey)
|
return apis.ErrOutOfBoundsValue(v, WindowMin, WindowMax, WindowAnnotationKey)
|
||||||
case d.Truncate(time.Second) != d:
|
case d.Truncate(time.Second) != d:
|
||||||
return apis.ErrGeneric("must be specified with at most second precision", WindowAnnotationKey)
|
return apis.ErrGeneric("must be specified with at most second precision", WindowAnnotationKey)
|
||||||
}
|
}
|
||||||
|
|
@ -170,48 +173,48 @@ func validateWindow(annotations map[string]string) *apis.FieldError {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateMinMaxScale(config *autoscalerconfig.Config, annotations map[string]string) *apis.FieldError {
|
func validateMinMaxScale(config *autoscalerconfig.Config, m map[string]string) *apis.FieldError {
|
||||||
min, errs := getIntGE0(annotations, MinScaleAnnotationKey)
|
min, errs := getIntGE0(m, MinScaleAnnotation)
|
||||||
max, err := getIntGE0(annotations, MaxScaleAnnotationKey)
|
max, err := getIntGE0(m, MaxScaleAnnotation)
|
||||||
errs = errs.Also(err)
|
errs = errs.Also(err)
|
||||||
|
|
||||||
if max != 0 && max < min {
|
if max != 0 && max < min {
|
||||||
errs = errs.Also(&apis.FieldError{
|
errs = errs.Also(&apis.FieldError{
|
||||||
Message: fmt.Sprintf("maxScale=%d is less than minScale=%d", max, min),
|
Message: fmt.Sprintf("max-scale=%d is less than min-scale=%d", max, min),
|
||||||
Paths: []string{MaxScaleAnnotationKey, MinScaleAnnotationKey},
|
Paths: []string{MaxScaleAnnotationKey, MinScaleAnnotationKey},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, hasMaxScaleAnnotation := annotations[MaxScaleAnnotationKey]; hasMaxScaleAnnotation {
|
if k, _, ok := MaxScaleAnnotation.Get(m); ok {
|
||||||
errs = errs.Also(validateMaxScaleWithinLimit(max, config.MaxScaleLimit))
|
errs = errs.Also(validateMaxScaleWithinLimit(k, max, config.MaxScaleLimit))
|
||||||
}
|
}
|
||||||
|
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateMaxScaleWithinLimit(maxScale, maxScaleLimit int32) (errs *apis.FieldError) {
|
func validateMaxScaleWithinLimit(key string, maxScale, maxScaleLimit int32) (errs *apis.FieldError) {
|
||||||
if maxScaleLimit == 0 {
|
if maxScaleLimit == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if maxScale > maxScaleLimit {
|
if maxScale > maxScaleLimit {
|
||||||
errs = errs.Also(apis.ErrOutOfBoundsValue(maxScale, 1, maxScaleLimit, MaxScaleAnnotationKey))
|
errs = errs.Also(apis.ErrOutOfBoundsValue(maxScale, 1, maxScaleLimit, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
if maxScale == 0 {
|
if maxScale == 0 {
|
||||||
errs = errs.Also(&apis.FieldError{
|
errs = errs.Also(&apis.FieldError{
|
||||||
Message: fmt.Sprint("maxScale=0 (unlimited), must be less than ", maxScaleLimit),
|
Message: fmt.Sprint("max-scale=0 (unlimited), must be less than ", maxScaleLimit),
|
||||||
Paths: []string{MaxScaleAnnotationKey},
|
Paths: []string{key},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateMetric(annotations map[string]string) *apis.FieldError {
|
func validateMetric(m map[string]string) *apis.FieldError {
|
||||||
if metric, ok := annotations[MetricAnnotationKey]; ok {
|
if _, metric, ok := MetricAnnotation.Get(m); ok {
|
||||||
classValue := KPA
|
classValue := KPA
|
||||||
if c, ok := annotations[ClassAnnotationKey]; ok {
|
if _, c, ok := ClassAnnotation.Get(m); ok {
|
||||||
classValue = c
|
classValue = c
|
||||||
}
|
}
|
||||||
switch classValue {
|
switch classValue {
|
||||||
|
|
@ -234,11 +237,11 @@ func validateMetric(annotations map[string]string) *apis.FieldError {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateInitialScale(config *autoscalerconfig.Config, annotations map[string]string) *apis.FieldError {
|
func validateInitialScale(config *autoscalerconfig.Config, m map[string]string) *apis.FieldError {
|
||||||
if initialScale, ok := annotations[InitialScaleAnnotationKey]; ok {
|
if k, v, ok := InitialScaleAnnotation.Get(m); ok {
|
||||||
initScaleInt, err := strconv.Atoi(initialScale)
|
initScaleInt, err := strconv.Atoi(v)
|
||||||
if err != nil || initScaleInt < 0 || (!config.AllowZeroInitialScale && initScaleInt == 0) {
|
if err != nil || initScaleInt < 0 || (!config.AllowZeroInitialScale && initScaleInt == 0) {
|
||||||
return apis.ErrInvalidValue(initialScale, InitialScaleAnnotationKey)
|
return apis.ErrInvalidValue(v, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,11 @@ limitations under the License.
|
||||||
|
|
||||||
package autoscaling
|
package autoscaling
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"knative.dev/pkg/kmap"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
domain = ".knative.dev"
|
domain = ".knative.dev"
|
||||||
|
|
@ -39,20 +43,21 @@ const (
|
||||||
|
|
||||||
// MinScaleAnnotationKey is the annotation to specify the minimum number of Pods
|
// MinScaleAnnotationKey is the annotation to specify the minimum number of Pods
|
||||||
// the PodAutoscaler should provision. For example,
|
// the PodAutoscaler should provision. For example,
|
||||||
// autoscaling.knative.dev/minScale: "1"
|
// autoscaling.knative.dev/min-scale: "1"
|
||||||
MinScaleAnnotationKey = GroupName + "/minScale"
|
MinScaleAnnotationKey = GroupName + "/min-scale"
|
||||||
|
|
||||||
// MaxScaleAnnotationKey is the annotation to specify the maximum number of Pods
|
// MaxScaleAnnotationKey is the annotation to specify the maximum number of Pods
|
||||||
// the PodAutoscaler should provision. For example,
|
// the PodAutoscaler should provision. For example,
|
||||||
// autoscaling.knative.dev/maxScale: "10"
|
// autoscaling.knative.dev/max-scale: "10"
|
||||||
MaxScaleAnnotationKey = GroupName + "/maxScale"
|
MaxScaleAnnotationKey = GroupName + "/max-scale"
|
||||||
|
|
||||||
// InitialScaleAnnotationKey is the annotation to specify the initial scale of
|
// InitialScaleAnnotationKey is the annotation to specify the initial scale of
|
||||||
// a revision when a service is initially deployed. This number can be set to 0 iff
|
// a revision when a service is initially deployed. This number can be set to 0 iff
|
||||||
// allow-zero-initial-scale of config-autoscaler is true.
|
// allow-zero-initial-scale of config-autoscaler is true.
|
||||||
InitialScaleAnnotationKey = GroupName + "/initialScale"
|
InitialScaleAnnotationKey = GroupName + "/initial-scale"
|
||||||
|
|
||||||
// ScaleDownDelayAnnotationKey is the annotation to specify a scale down delay.
|
// ScaleDownDelayAnnotationKey is the annotation to specify a scale down delay.
|
||||||
ScaleDownDelayAnnotationKey = GroupName + "/scaleDownDelay"
|
ScaleDownDelayAnnotationKey = GroupName + "/scale-down-delay"
|
||||||
|
|
||||||
// MetricAnnotationKey is the annotation to specify what metric the PodAutoscaler
|
// MetricAnnotationKey is the annotation to specify what metric the PodAutoscaler
|
||||||
// should be scaled on. For example,
|
// should be scaled on. For example,
|
||||||
|
|
@ -86,7 +91,7 @@ const (
|
||||||
// made the decision to scale to 0.
|
// made the decision to scale to 0.
|
||||||
// This is the per-revision setting compliment to the
|
// This is the per-revision setting compliment to the
|
||||||
// scale-to-zero-pod-retention-period global setting.
|
// scale-to-zero-pod-retention-period global setting.
|
||||||
ScaleToZeroPodRetentionPeriodKey = GroupName + "/scaleToZeroPodRetentionPeriod"
|
ScaleToZeroPodRetentionPeriodKey = GroupName + "/scale-to-zero-pod-retention-period"
|
||||||
|
|
||||||
// MetricAggregationAlgorithmKey is the annotation that can be used for selection
|
// MetricAggregationAlgorithmKey is the annotation that can be used for selection
|
||||||
// of the algorithm to use for averaging metric data in the Autoscaler.
|
// of the algorithm to use for averaging metric data in the Autoscaler.
|
||||||
|
|
@ -102,13 +107,21 @@ const (
|
||||||
// KPA will compute the decay multiplier automatically based on the window size
|
// KPA will compute the decay multiplier automatically based on the window size
|
||||||
// and it is at least 0.2. This algorithm might not utilize all the values
|
// and it is at least 0.2. This algorithm might not utilize all the values
|
||||||
// in the window, due to their coefficients being infinitesimal.
|
// in the window, due to their coefficients being infinitesimal.
|
||||||
MetricAggregationAlgorithmKey = GroupName + "/metricAggregationAlgorithm"
|
MetricAggregationAlgorithmKey = GroupName + "/metric-aggregation-algorithm"
|
||||||
|
|
||||||
// MetricAggregationAlgorithmLinear is the linear aggregation algorithm with all weights
|
// MetricAggregationAlgorithmLinear is the linear aggregation algorithm with all weights
|
||||||
// equal to 1.
|
// equal to 1.
|
||||||
MetricAggregationAlgorithmLinear = "linear"
|
MetricAggregationAlgorithmLinear = "linear"
|
||||||
|
|
||||||
// MetricAggregationAlgorithmWeightedExponential is the weighted aggregation algorithm
|
// MetricAggregationAlgorithmWeightedExponential is the weighted aggregation algorithm
|
||||||
// with exponentially decaying weights.
|
// with exponentially decaying weights.
|
||||||
MetricAggregationAlgorithmWeightedExponential = "weightedExponential"
|
MetricAggregationAlgorithmWeightedExponential = "weighted-exponential"
|
||||||
|
|
||||||
|
// MetricAggregationAlgorithmWeightedExponentialAlt is the alternate casing for MetricAggregationAlgorithmWeightedExponential
|
||||||
|
|
||||||
|
// Note: use the Metric.AggregationAlgorithm() method as it will normalize the casing
|
||||||
|
// and return MetricAggregationAlgorithmWeightedExponential
|
||||||
|
MetricAggregationAlgorithmWeightedExponentialAlt = "weightedExponential"
|
||||||
|
|
||||||
// WindowAnnotationKey is the annotation to specify the time
|
// WindowAnnotationKey is the annotation to specify the time
|
||||||
// interval over which to calculate the average metric. Larger
|
// interval over which to calculate the average metric. Larger
|
||||||
|
|
@ -136,7 +149,7 @@ const (
|
||||||
// desired target resource utilization for the revision.
|
// desired target resource utilization for the revision.
|
||||||
// TargetUtilization is a percentage in the 1 <= TU <= 100 range.
|
// TargetUtilization is a percentage in the 1 <= TU <= 100 range.
|
||||||
// This annotation takes precedence over the config map value.
|
// This annotation takes precedence over the config map value.
|
||||||
TargetUtilizationPercentageKey = GroupName + "/targetUtilizationPercentage"
|
TargetUtilizationPercentageKey = GroupName + "/target-utilization-percentage"
|
||||||
|
|
||||||
// TargetBurstCapacityKey specifies the desired burst capacity for the
|
// TargetBurstCapacityKey specifies the desired burst capacity for the
|
||||||
// revision. Possible values are:
|
// revision. Possible values are:
|
||||||
|
|
@ -144,7 +157,7 @@ const (
|
||||||
// 0 -- no TBC;
|
// 0 -- no TBC;
|
||||||
// >0 -- actual TBC.
|
// >0 -- actual TBC.
|
||||||
// <0 && != -1 -- an error.
|
// <0 && != -1 -- an error.
|
||||||
TargetBurstCapacityKey = GroupName + "/targetBurstCapacity"
|
TargetBurstCapacityKey = GroupName + "/target-burst-capacity"
|
||||||
|
|
||||||
// PanicWindowPercentageAnnotationKey is the annotation to
|
// PanicWindowPercentageAnnotationKey is the annotation to
|
||||||
// specify the time interval over which to calculate the average
|
// specify the time interval over which to calculate the average
|
||||||
|
|
@ -153,15 +166,16 @@ const (
|
||||||
// mode). Lower values make panic mode more sensitive. Note:
|
// mode). Lower values make panic mode more sensitive. Note:
|
||||||
// Panic threshold can be overridden with the
|
// Panic threshold can be overridden with the
|
||||||
// PanicThresholdPercentageAnnotationKey. For example,
|
// PanicThresholdPercentageAnnotationKey. For example,
|
||||||
// autoscaling.knative.dev/panicWindowPercentage: "5.0"
|
// autoscaling.knative.dev/panic-window-percentage: "5.0"
|
||||||
// autoscaling.knative.dev/panicThresholdPercentage: "150.0"
|
// autoscaling.knative.dev/panic-threshold-percentage: "150.0"
|
||||||
// Only the kpa.autoscaling.knative.dev class autoscaler supports
|
// Only the kpa.autoscaling.knative.dev class autoscaler supports
|
||||||
// the panicWindowPercentage annotation.
|
// the panic-window-percentage annotation.
|
||||||
// Panic window is specified as a percentage to maintain the
|
// Panic window is specified as a percentage to maintain the
|
||||||
// autoscaler's algorithm behavior when only the stable window is
|
// autoscaler's algorithm behavior when only the stable window is
|
||||||
// specified. The panic window will change along with the stable
|
// specified. The panic window will change along with the stable
|
||||||
// window at the default percentage.
|
// window at the default percentage.
|
||||||
PanicWindowPercentageAnnotationKey = GroupName + "/panicWindowPercentage"
|
PanicWindowPercentageAnnotationKey = GroupName + "/panic-window-percentage"
|
||||||
|
|
||||||
// PanicWindowPercentageMin is the minimum allowable panic window
|
// PanicWindowPercentageMin is the minimum allowable panic window
|
||||||
// percentage. The autoscaler calculates desired replicas every 2
|
// percentage. The autoscaler calculates desired replicas every 2
|
||||||
// seconds (tick-interval in config-autoscaler), so a panic
|
// seconds (tick-interval in config-autoscaler), so a panic
|
||||||
|
|
@ -182,11 +196,12 @@ const (
|
||||||
// in the panic window. The level is defined as a percentage of
|
// in the panic window. The level is defined as a percentage of
|
||||||
// the metric target. Lower values make panic mode more
|
// the metric target. Lower values make panic mode more
|
||||||
// sensitive. For example,
|
// sensitive. For example,
|
||||||
// autoscaling.knative.dev/panicWindowPercentage: "5.0"
|
// autoscaling.knative.dev/panic-window-percentage: "5.0"
|
||||||
// autoscaling.knative.dev/panicThresholdPercentage: "150.0"
|
// autoscaling.knative.dev/panic-threshold-percentage: "150.0"
|
||||||
// Only the kpa.autoscaling.knative.dev class autoscaler supports
|
// Only the kpa.autoscaling.knative.dev class autoscaler supports
|
||||||
// the panicThresholdPercentage annotation
|
// the panicThresholdPercentage annotation
|
||||||
PanicThresholdPercentageAnnotationKey = GroupName + "/panicThresholdPercentage"
|
PanicThresholdPercentageAnnotationKey = GroupName + "/panic-threshold-percentage"
|
||||||
|
|
||||||
// PanicThresholdPercentageMin is the minimum allowable panic
|
// PanicThresholdPercentageMin is the minimum allowable panic
|
||||||
// threshold percentage. The KPA autoscaler's panic feature
|
// threshold percentage. The KPA autoscaler's panic feature
|
||||||
// allows the autoscaler to be more responsive over a smaller
|
// allows the autoscaler to be more responsive over a smaller
|
||||||
|
|
@ -202,3 +217,58 @@ const (
|
||||||
// but bounding from above.
|
// but bounding from above.
|
||||||
PanicThresholdPercentageMax = 1000.0
|
PanicThresholdPercentageMax = 1000.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ClassAnnotation = kmap.KeyPriority{
|
||||||
|
ClassAnnotationKey,
|
||||||
|
}
|
||||||
|
InitialScaleAnnotation = kmap.KeyPriority{
|
||||||
|
InitialScaleAnnotationKey,
|
||||||
|
GroupName + "/initialScale",
|
||||||
|
}
|
||||||
|
MaxScaleAnnotation = kmap.KeyPriority{
|
||||||
|
MaxScaleAnnotationKey,
|
||||||
|
GroupName + "/maxScale",
|
||||||
|
}
|
||||||
|
MetricAnnotation = kmap.KeyPriority{
|
||||||
|
MetricAnnotationKey,
|
||||||
|
}
|
||||||
|
MetricAggregationAlgorithmAnnotation = kmap.KeyPriority{
|
||||||
|
MetricAggregationAlgorithmKey,
|
||||||
|
GroupName + "/metricAggregationAlgorithm",
|
||||||
|
}
|
||||||
|
MinScaleAnnotation = kmap.KeyPriority{
|
||||||
|
MinScaleAnnotationKey,
|
||||||
|
GroupName + "/minScale",
|
||||||
|
}
|
||||||
|
PanicThresholdPercentageAnnotation = kmap.KeyPriority{
|
||||||
|
PanicThresholdPercentageAnnotationKey,
|
||||||
|
GroupName + "/panicThresholdPercentage",
|
||||||
|
}
|
||||||
|
PanicWindowPercentageAnnotation = kmap.KeyPriority{
|
||||||
|
PanicWindowPercentageAnnotationKey,
|
||||||
|
GroupName + "/panicWindowPercentage",
|
||||||
|
}
|
||||||
|
ScaleDownDelayAnnotation = kmap.KeyPriority{
|
||||||
|
ScaleDownDelayAnnotationKey,
|
||||||
|
GroupName + "/scaleDownDelay",
|
||||||
|
}
|
||||||
|
ScaleToZeroPodRetentionPeriodAnnotation = kmap.KeyPriority{
|
||||||
|
ScaleToZeroPodRetentionPeriodKey,
|
||||||
|
GroupName + "/scaleToZeroPodRetentionPeriod",
|
||||||
|
}
|
||||||
|
TargetAnnotation = kmap.KeyPriority{
|
||||||
|
TargetAnnotationKey,
|
||||||
|
}
|
||||||
|
TargetBurstCapacityAnnotation = kmap.KeyPriority{
|
||||||
|
TargetBurstCapacityKey,
|
||||||
|
GroupName + "/targetBurstCapacity",
|
||||||
|
}
|
||||||
|
TargetUtilizationPercentageAnnotation = kmap.KeyPriority{
|
||||||
|
TargetUtilizationPercentageKey,
|
||||||
|
GroupName + "/targetUtilizationPercentage",
|
||||||
|
}
|
||||||
|
WindowAnnotation = kmap.KeyPriority{
|
||||||
|
WindowAnnotationKey,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package v1alpha1
|
||||||
import (
|
import (
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"knative.dev/pkg/apis"
|
"knative.dev/pkg/apis"
|
||||||
|
"knative.dev/serving/pkg/apis/autoscaling"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -74,3 +75,14 @@ func (m *Metric) IsReady() bool {
|
||||||
return ms.ObservedGeneration == m.Generation &&
|
return ms.ObservedGeneration == m.Generation &&
|
||||||
ms.GetCondition(MetricConditionReady).IsTrue()
|
ms.GetCondition(MetricConditionReady).IsTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Metric) AggregationAlgorithm() string {
|
||||||
|
if _, s, ok := autoscaling.MetricAggregationAlgorithmAnnotation.Get(m.Annotations); ok {
|
||||||
|
// Normalize and use the regular casing
|
||||||
|
if s == autoscaling.MetricAggregationAlgorithmWeightedExponentialAlt {
|
||||||
|
return autoscaling.MetricAggregationAlgorithmWeightedExponential
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
|
||||||
"knative.dev/pkg/apis"
|
"knative.dev/pkg/apis"
|
||||||
|
"knative.dev/pkg/kmap"
|
||||||
"knative.dev/serving/pkg/apis/autoscaling"
|
"knative.dev/serving/pkg/apis/autoscaling"
|
||||||
"knative.dev/serving/pkg/autoscaler/config/autoscalerconfig"
|
"knative.dev/serving/pkg/autoscaler/config/autoscalerconfig"
|
||||||
)
|
)
|
||||||
|
|
@ -63,16 +64,16 @@ func (pa *PodAutoscaler) Metric() string {
|
||||||
return defaultMetric(pa.Class())
|
return defaultMetric(pa.Class())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pa *PodAutoscaler) annotationInt32(key string) (int32, bool) {
|
func (pa *PodAutoscaler) annotationInt32(k kmap.KeyPriority) (int32, bool) {
|
||||||
if s, ok := pa.Annotations[key]; ok {
|
if _, s, ok := k.Get(pa.Annotations); ok {
|
||||||
i, err := strconv.ParseInt(s, 10, 32)
|
i, err := strconv.ParseInt(s, 10, 32)
|
||||||
return int32(i), err == nil
|
return int32(i), err == nil
|
||||||
}
|
}
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pa *PodAutoscaler) annotationFloat64(key string) (float64, bool) {
|
func (pa *PodAutoscaler) annotationFloat64(k kmap.KeyPriority) (float64, bool) {
|
||||||
if s, ok := pa.Annotations[key]; ok {
|
if _, s, ok := k.Get(pa.Annotations); ok {
|
||||||
f, err := strconv.ParseFloat(s, 64)
|
f, err := strconv.ParseFloat(s, 64)
|
||||||
return f, err == nil
|
return f, err == nil
|
||||||
}
|
}
|
||||||
|
|
@ -87,13 +88,13 @@ func (pa *PodAutoscaler) ScaleBounds(asConfig *autoscalerconfig.Config) (int32,
|
||||||
var min int32
|
var min int32
|
||||||
if pa.Spec.Reachability != ReachabilityUnreachable {
|
if pa.Spec.Reachability != ReachabilityUnreachable {
|
||||||
min = asConfig.MinScale
|
min = asConfig.MinScale
|
||||||
if paMin, ok := pa.annotationInt32(autoscaling.MinScaleAnnotationKey); ok {
|
if paMin, ok := pa.annotationInt32(autoscaling.MinScaleAnnotation); ok {
|
||||||
min = paMin
|
min = paMin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
max := asConfig.MaxScale
|
max := asConfig.MaxScale
|
||||||
if paMax, ok := pa.annotationInt32(autoscaling.MaxScaleAnnotationKey); ok {
|
if paMax, ok := pa.annotationInt32(autoscaling.MaxScaleAnnotation); ok {
|
||||||
max = paMax
|
max = paMax
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,13 +103,13 @@ func (pa *PodAutoscaler) ScaleBounds(asConfig *autoscalerconfig.Config) (int32,
|
||||||
|
|
||||||
// Target returns the target annotation value or false if not present, or invalid.
|
// Target returns the target annotation value or false if not present, or invalid.
|
||||||
func (pa *PodAutoscaler) Target() (float64, bool) {
|
func (pa *PodAutoscaler) Target() (float64, bool) {
|
||||||
return pa.annotationFloat64(autoscaling.TargetAnnotationKey)
|
return pa.annotationFloat64(autoscaling.TargetAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TargetUtilization returns the target utilization percentage as a fraction, if
|
// TargetUtilization returns the target utilization percentage as a fraction, if
|
||||||
// the corresponding annotation is set.
|
// the corresponding annotation is set.
|
||||||
func (pa *PodAutoscaler) TargetUtilization() (float64, bool) {
|
func (pa *PodAutoscaler) TargetUtilization() (float64, bool) {
|
||||||
if tu, ok := pa.annotationFloat64(autoscaling.TargetUtilizationPercentageKey); ok {
|
if tu, ok := pa.annotationFloat64(autoscaling.TargetUtilizationPercentageAnnotation); ok {
|
||||||
return tu / 100, true
|
return tu / 100, true
|
||||||
}
|
}
|
||||||
return 0, false
|
return 0, false
|
||||||
|
|
@ -117,11 +118,11 @@ func (pa *PodAutoscaler) TargetUtilization() (float64, bool) {
|
||||||
// TargetBC returns the target burst capacity, if the corresponding annotation is set.
|
// TargetBC returns the target burst capacity, if the corresponding annotation is set.
|
||||||
func (pa *PodAutoscaler) TargetBC() (float64, bool) {
|
func (pa *PodAutoscaler) TargetBC() (float64, bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationFloat64(autoscaling.TargetBurstCapacityKey)
|
return pa.annotationFloat64(autoscaling.TargetBurstCapacityAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pa *PodAutoscaler) annotationDuration(key string) (time.Duration, bool) {
|
func (pa *PodAutoscaler) annotationDuration(k kmap.KeyPriority) (time.Duration, bool) {
|
||||||
if s, ok := pa.Annotations[key]; ok {
|
if _, s, ok := k.Get(pa.Annotations); ok {
|
||||||
d, err := time.ParseDuration(s)
|
d, err := time.ParseDuration(s)
|
||||||
return d, err == nil
|
return d, err == nil
|
||||||
}
|
}
|
||||||
|
|
@ -132,37 +133,37 @@ func (pa *PodAutoscaler) annotationDuration(key string) (time.Duration, bool) {
|
||||||
// or false if not present.
|
// or false if not present.
|
||||||
func (pa *PodAutoscaler) ScaleToZeroPodRetention() (time.Duration, bool) {
|
func (pa *PodAutoscaler) ScaleToZeroPodRetention() (time.Duration, bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationDuration(autoscaling.ScaleToZeroPodRetentionPeriodKey)
|
return pa.annotationDuration(autoscaling.ScaleToZeroPodRetentionPeriodAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window returns the window annotation value, or false if not present.
|
// Window returns the window annotation value, or false if not present.
|
||||||
func (pa *PodAutoscaler) Window() (time.Duration, bool) {
|
func (pa *PodAutoscaler) Window() (time.Duration, bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationDuration(autoscaling.WindowAnnotationKey)
|
return pa.annotationDuration(autoscaling.WindowAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScaleDownDelay returns the scale down delay annotation, or false if not present.
|
// ScaleDownDelay returns the scale down delay annotation, or false if not present.
|
||||||
func (pa *PodAutoscaler) ScaleDownDelay() (time.Duration, bool) {
|
func (pa *PodAutoscaler) ScaleDownDelay() (time.Duration, bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationDuration(autoscaling.ScaleDownDelayAnnotationKey)
|
return pa.annotationDuration(autoscaling.ScaleDownDelayAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PanicWindowPercentage returns the panic window annotation value, or false if not present.
|
// PanicWindowPercentage returns the panic window annotation value, or false if not present.
|
||||||
func (pa *PodAutoscaler) PanicWindowPercentage() (percentage float64, ok bool) {
|
func (pa *PodAutoscaler) PanicWindowPercentage() (percentage float64, ok bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationFloat64(autoscaling.PanicWindowPercentageAnnotationKey)
|
return pa.annotationFloat64(autoscaling.PanicWindowPercentageAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PanicThresholdPercentage returns the panic threshold annotation value, or false if not present.
|
// PanicThresholdPercentage returns the panic threshold annotation value, or false if not present.
|
||||||
func (pa *PodAutoscaler) PanicThresholdPercentage() (percentage float64, ok bool) {
|
func (pa *PodAutoscaler) PanicThresholdPercentage() (percentage float64, ok bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationFloat64(autoscaling.PanicThresholdPercentageAnnotationKey)
|
return pa.annotationFloat64(autoscaling.PanicThresholdPercentageAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitialScale returns the initial scale on the revision if present, or false if not present.
|
// InitialScale returns the initial scale on the revision if present, or false if not present.
|
||||||
func (pa *PodAutoscaler) InitialScale() (int32, bool) {
|
func (pa *PodAutoscaler) InitialScale() (int32, bool) {
|
||||||
// The value is validated in the webhook.
|
// The value is validated in the webhook.
|
||||||
return pa.annotationInt32(autoscaling.InitialScaleAnnotationKey)
|
return pa.annotationInt32(autoscaling.InitialScaleAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsReady returns true if the Status condition PodAutoscalerConditionReady
|
// IsReady returns true if the Status condition PodAutoscalerConditionReady
|
||||||
|
|
|
||||||
|
|
@ -50,25 +50,25 @@ func ValidateObjectMetadata(ctx context.Context, meta metav1.Object, allowAutosc
|
||||||
// ValidateRolloutDurationAnnotation validates the rollout duration annotation.
|
// ValidateRolloutDurationAnnotation validates the rollout duration annotation.
|
||||||
// This annotation can be set on either service or route objects.
|
// This annotation can be set on either service or route objects.
|
||||||
func ValidateRolloutDurationAnnotation(annos map[string]string) (errs *apis.FieldError) {
|
func ValidateRolloutDurationAnnotation(annos map[string]string) (errs *apis.FieldError) {
|
||||||
if v := annos[RolloutDurationKey]; v != "" {
|
if k, v, _ := RolloutDurationAnnotation.Get(annos); v != "" {
|
||||||
// Parse as duration.
|
// Parse as duration.
|
||||||
d, err := time.ParseDuration(v)
|
d, err := time.ParseDuration(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Also(apis.ErrInvalidValue(v, RolloutDurationKey))
|
return errs.Also(apis.ErrInvalidValue(v, k))
|
||||||
}
|
}
|
||||||
// Validate that it has second precision.
|
// Validate that it has second precision.
|
||||||
if d.Round(time.Second) != d {
|
if d.Round(time.Second) != d {
|
||||||
return errs.Also(&apis.FieldError{
|
return errs.Also(&apis.FieldError{
|
||||||
// Even if tempting %v won't work here, since it might output the value spelled differently.
|
// Even if tempting %v won't work here, since it might output the value spelled differently.
|
||||||
Message: fmt.Sprintf("rolloutDuration=%s is not at second precision", v),
|
Message: fmt.Sprintf("rollout-duration=%s is not at second precision", v),
|
||||||
Paths: []string{RolloutDurationKey},
|
Paths: []string{k},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// And positive.
|
// And positive.
|
||||||
if d < 0 {
|
if d < 0 {
|
||||||
return errs.Also(&apis.FieldError{
|
return errs.Also(&apis.FieldError{
|
||||||
Message: fmt.Sprintf("rolloutDuration=%s must be positive", v),
|
Message: fmt.Sprintf("rollout-duration=%s must be positive", v),
|
||||||
Paths: []string{RolloutDurationKey},
|
Paths: []string{k},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,10 @@ limitations under the License.
|
||||||
|
|
||||||
package serving
|
package serving
|
||||||
|
|
||||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"knative.dev/pkg/kmap"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// GroupName is the group name for knative labels and annotations
|
// GroupName is the group name for knative labels and annotations
|
||||||
|
|
@ -55,7 +58,7 @@ const (
|
||||||
// of the rollout of the latest revision. The value must be a valid positive
|
// of the rollout of the latest revision. The value must be a valid positive
|
||||||
// Golang time.Duration value serialized to string.
|
// Golang time.Duration value serialized to string.
|
||||||
// The value can be specified with at most with a second precision.
|
// The value can be specified with at most with a second precision.
|
||||||
RolloutDurationKey = GroupName + "/rolloutDuration"
|
RolloutDurationKey = GroupName + "/rollout-duration"
|
||||||
|
|
||||||
// RoutingStateLabelKey is the label attached to a Revision indicating
|
// RoutingStateLabelKey is the label attached to a Revision indicating
|
||||||
// its state in relation to serving a Route.
|
// its state in relation to serving a Route.
|
||||||
|
|
@ -111,9 +114,9 @@ const (
|
||||||
// last updated the resource.
|
// last updated the resource.
|
||||||
UpdaterAnnotation = GroupName + "/lastModifier"
|
UpdaterAnnotation = GroupName + "/lastModifier"
|
||||||
|
|
||||||
// QueueSideCarResourcePercentageAnnotation is the percentage of user container resources to be used for queue-proxy
|
// QueueSidecarResourcePercentageAnnotationKey is the percentage of user container resources to be used for queue-proxy
|
||||||
// It has to be in [0.1,100]
|
// It has to be in [0.1,100]
|
||||||
QueueSideCarResourcePercentageAnnotation = "queue.sidecar." + GroupName + "/resourcePercentage"
|
QueueSidecarResourcePercentageAnnotationKey = "queue.sidecar." + GroupName + "/resource-percentage"
|
||||||
|
|
||||||
// VisibilityClusterLocal is the label value for VisibilityLabelKey
|
// VisibilityClusterLocal is the label value for VisibilityLabelKey
|
||||||
// that will result to the Route/KService getting a cluster local
|
// that will result to the Route/KService getting a cluster local
|
||||||
|
|
@ -146,3 +149,14 @@ var (
|
||||||
Resource: "routes",
|
Resource: "routes",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
RolloutDurationAnnotation = kmap.KeyPriority{
|
||||||
|
RolloutDurationKey,
|
||||||
|
GroupName + "/rolloutDuration",
|
||||||
|
}
|
||||||
|
QueueSidecarResourcePercentageAnnotation = kmap.KeyPriority{
|
||||||
|
QueueSidecarResourcePercentageAnnotationKey,
|
||||||
|
"queue.sidecar." + GroupName + "/resourcePercentage",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -178,22 +178,20 @@ func validateTimeoutSeconds(ctx context.Context, timeoutSeconds int64) *apis.Fie
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateQueueSidecarAnnotation validates QueueSideCarResourcePercentageAnnotation
|
// validateQueueSidecarAnnotation validates QueueSideCarResourcePercentageAnnotation
|
||||||
func validateQueueSidecarAnnotation(annotations map[string]string) *apis.FieldError {
|
func validateQueueSidecarAnnotation(m map[string]string) *apis.FieldError {
|
||||||
if len(annotations) == 0 {
|
if len(m) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
v, ok := annotations[serving.QueueSideCarResourcePercentageAnnotation]
|
k, v, ok := serving.QueueSidecarResourcePercentageAnnotation.Get(m)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
value, err := strconv.ParseFloat(v, 64)
|
value, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return apis.ErrInvalidValue(v, apis.CurrentField).
|
return apis.ErrInvalidValue(v, apis.CurrentField).ViaKey(k)
|
||||||
ViaKey(serving.QueueSideCarResourcePercentageAnnotation)
|
|
||||||
}
|
}
|
||||||
if value < 0.1 || value > 100 {
|
if value < 0.1 || value > 100 {
|
||||||
return apis.ErrOutOfBoundsValue(value, 0.1, 100.0, apis.CurrentField).
|
return apis.ErrOutOfBoundsValue(value, 0.1, 100.0, apis.CurrentField).ViaKey(k)
|
||||||
ViaKey(serving.QueueSideCarResourcePercentageAnnotation)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func (r *Route) IsFailed() bool {
|
||||||
// annotation.
|
// annotation.
|
||||||
// 0 is returned if missing or cannot be parsed.
|
// 0 is returned if missing or cannot be parsed.
|
||||||
func (r *Route) RolloutDuration() time.Duration {
|
func (r *Route) RolloutDuration() time.Duration {
|
||||||
if v, ok := r.Annotations[serving.RolloutDurationKey]; ok && v != "" {
|
if _, v, ok := serving.RolloutDurationAnnotation.Get(r.Annotations); ok && v != "" {
|
||||||
// WH should've declined all the invalid values for this annotation.
|
// WH should've declined all the invalid values for this annotation.
|
||||||
if d, err := time.ParseDuration(v); err == nil {
|
if d, err := time.ParseDuration(v); err == nil {
|
||||||
return d
|
return d
|
||||||
|
|
|
||||||
|
|
@ -731,7 +731,7 @@ k8s.io/utils/buffer
|
||||||
k8s.io/utils/integer
|
k8s.io/utils/integer
|
||||||
k8s.io/utils/pointer
|
k8s.io/utils/pointer
|
||||||
k8s.io/utils/trace
|
k8s.io/utils/trace
|
||||||
# knative.dev/eventing v0.27.1-0.20211123070249-2cda8f40b5d9
|
# knative.dev/eventing v0.27.1-0.20211123205351-820db20be4b2
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/eventing/pkg/apis/config
|
knative.dev/eventing/pkg/apis/config
|
||||||
knative.dev/eventing/pkg/apis/duck
|
knative.dev/eventing/pkg/apis/duck
|
||||||
|
|
@ -760,7 +760,7 @@ knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1beta2/fake
|
||||||
# knative.dev/hack v0.0.0-20211122162614-813559cefdda
|
# knative.dev/hack v0.0.0-20211122162614-813559cefdda
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/hack
|
knative.dev/hack
|
||||||
# knative.dev/networking v0.0.0-20211123024050-aa82452902be
|
# knative.dev/networking v0.0.0-20211124064027-ea794f17c1bf
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/networking/pkg
|
knative.dev/networking/pkg
|
||||||
knative.dev/networking/pkg/apis/networking
|
knative.dev/networking/pkg/apis/networking
|
||||||
|
|
@ -768,7 +768,7 @@ knative.dev/networking/pkg/apis/networking/v1alpha1
|
||||||
knative.dev/networking/pkg/client/clientset/versioned
|
knative.dev/networking/pkg/client/clientset/versioned
|
||||||
knative.dev/networking/pkg/client/clientset/versioned/scheme
|
knative.dev/networking/pkg/client/clientset/versioned/scheme
|
||||||
knative.dev/networking/pkg/client/clientset/versioned/typed/networking/v1alpha1
|
knative.dev/networking/pkg/client/clientset/versioned/typed/networking/v1alpha1
|
||||||
# knative.dev/pkg v0.0.0-20211123074649-0fae0afc10ad
|
# knative.dev/pkg v0.0.0-20211123135150-787aec59e70a
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/pkg/apis
|
knative.dev/pkg/apis
|
||||||
knative.dev/pkg/apis/duck
|
knative.dev/pkg/apis/duck
|
||||||
|
|
@ -818,7 +818,7 @@ knative.dev/pkg/tracing/config
|
||||||
knative.dev/pkg/tracing/propagation
|
knative.dev/pkg/tracing/propagation
|
||||||
knative.dev/pkg/tracing/propagation/tracecontextb3
|
knative.dev/pkg/tracing/propagation/tracecontextb3
|
||||||
knative.dev/pkg/tracker
|
knative.dev/pkg/tracker
|
||||||
# knative.dev/serving v0.27.1-0.20211123120750-26c7dc6ccc53
|
# knative.dev/serving v0.27.1-0.20211124064027-e6f8e414ac9e
|
||||||
## explicit
|
## explicit
|
||||||
knative.dev/serving/pkg/apis/autoscaling
|
knative.dev/serving/pkg/apis/autoscaling
|
||||||
knative.dev/serving/pkg/apis/autoscaling/v1alpha1
|
knative.dev/serving/pkg/apis/autoscaling/v1alpha1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue