Merge pull request #107527 from wojtek-t/remove_selflink_ga

Graduate RemoveSelfLink to Stable
This commit is contained in:
Kubernetes Prow Robot 2022-02-14 19:46:02 -08:00 committed by GitHub
commit e42e2e877f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
188 changed files with 180 additions and 2158 deletions

View File

@ -16657,7 +16657,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -16782,7 +16782,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -7123,7 +7123,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -7254,7 +7254,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -849,7 +849,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -975,7 +975,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1133,7 +1133,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1259,7 +1259,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -4553,7 +4553,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -4679,7 +4679,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -349,7 +349,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -629,7 +629,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -595,7 +595,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -721,7 +721,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1130,7 +1130,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1256,7 +1256,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1044,7 +1044,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1170,7 +1170,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1121,7 +1121,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1247,7 +1247,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -3779,7 +3779,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -3905,7 +3905,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -3581,7 +3581,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -3707,7 +3707,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -634,7 +634,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -760,7 +760,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -526,7 +526,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -657,7 +657,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -682,7 +682,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -808,7 +808,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -672,7 +672,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -798,7 +798,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -628,7 +628,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -759,7 +759,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -628,7 +628,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -759,7 +759,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1019,7 +1019,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1145,7 +1145,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1019,7 +1019,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1145,7 +1145,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -608,7 +608,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -734,7 +734,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1134,7 +1134,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1260,7 +1260,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -587,7 +587,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -713,7 +713,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -601,7 +601,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -727,7 +727,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -587,7 +587,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -713,7 +713,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -681,7 +681,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -807,7 +807,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1132,7 +1132,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1258,7 +1258,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -906,7 +906,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -1032,7 +1032,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -514,7 +514,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -640,7 +640,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -1983,7 +1983,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -2109,7 +2109,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -574,7 +574,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -700,7 +700,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -574,7 +574,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
} }
}, },
@ -700,7 +700,7 @@
"type": "string" "type": "string"
}, },
"selfLink": { "selfLink": {
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "description": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"type": "string" "type": "string"
}, },
"uid": { "uid": {

View File

@ -179,6 +179,7 @@ func fuzzObject(t *testing.T, gvk schema.GroupVersionKind) runtime.Object {
func(s *v1.ObjectMeta, c fuzz.Continue) { func(s *v1.ObjectMeta, c fuzz.Continue) {
c.FuzzNoCustom(s) c.FuzzNoCustom(s)
s.ManagedFields = nil s.ManagedFields = nil
s.SelfLink = ""
}, },
).Fuzz(internalObj) ).Fuzz(internalObj)

View File

@ -46,7 +46,6 @@ var benchmarkPod = api.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "etcd-server-e2e-test-wojtekt-master", Name: "etcd-server-e2e-test-wojtekt-master",
Namespace: "default", Namespace: "default",
SelfLink: "/api/v1/namespaces/default/pods/etcd-server-e2e-test-wojtekt-master",
UID: types.UID("a671734a-e8e5-11e4-8fde-42010af09327"), UID: types.UID("a671734a-e8e5-11e4-8fde-42010af09327"),
ResourceVersion: "22", ResourceVersion: "22",
CreationTimestamp: parseTimeOrDie("2015-04-22T11:49:36Z"), CreationTimestamp: parseTimeOrDie("2015-04-22T11:49:36Z"),

View File

@ -56,11 +56,6 @@ func TestAccessorImplementations(t *testing.T) {
t.Errorf("%v (%v) did not preserve resource version", gv.WithKind(kind), knownType) t.Errorf("%v (%v) did not preserve resource version", gv.WithKind(kind), knownType)
continue continue
} }
m.SetSelfLink("102030")
if m.GetSelfLink() != "102030" {
t.Errorf("%v (%v) did not preserve self link", gv.WithKind(kind), knownType)
continue
}
case isOM: case isOM:
m := om.GetObjectMeta() m := om.GetObjectMeta()
if m == nil { if m == nil {
@ -72,11 +67,6 @@ func TestAccessorImplementations(t *testing.T) {
t.Errorf("%v (%v) did not preserve resource version", gv.WithKind(kind), knownType) t.Errorf("%v (%v) did not preserve resource version", gv.WithKind(kind), knownType)
continue continue
} }
m.SetSelfLink("102030")
if m.GetSelfLink() != "102030" {
t.Errorf("%v (%v) did not preserve self link", gv.WithKind(kind), knownType)
continue
}
labels := map[string]string{"a": "b"} labels := map[string]string{"a": "b"}
m.SetLabels(labels) m.SetLabels(labels)
if !reflect.DeepEqual(m.GetLabels(), labels) { if !reflect.DeepEqual(m.GetLabels(), labels) {

View File

@ -3,7 +3,6 @@
"apiVersion": "v1", "apiVersion": "v1",
"metadata": { "metadata": {
"name": "e2e-test-wojtekt-node-etd6", "name": "e2e-test-wojtekt-node-etd6",
"selfLink": "/api/v1/nodes/e2e-test-wojtekt-node-etd6",
"uid": "a7e89222-e8e5-11e4-8fde-42010af09327", "uid": "a7e89222-e8e5-11e4-8fde-42010af09327",
"resourceVersion": "379", "resourceVersion": "379",
"creationTimestamp": "2015-04-22T11:49:39Z" "creationTimestamp": "2015-04-22T11:49:39Z"

View File

@ -4,7 +4,6 @@
"metadata": { "metadata": {
"name": "elasticsearch-logging-controller", "name": "elasticsearch-logging-controller",
"namespace": "default", "namespace": "default",
"selfLink": "/api/v1/namespaces/default/replicationcontrollers/elasticsearch-logging-controller",
"uid": "aa76f162-e8e5-11e4-8fde-42010af09327", "uid": "aa76f162-e8e5-11e4-8fde-42010af09327",
"resourceVersion": "98", "resourceVersion": "98",
"creationTimestamp": "2015-04-22T11:49:43Z", "creationTimestamp": "2015-04-22T11:49:43Z",

View File

@ -110,13 +110,11 @@ func (h *HumanReadableGenerator) GenerateTable(obj runtime.Object, options Gener
} }
if m, err := meta.ListAccessor(obj); err == nil { if m, err := meta.ListAccessor(obj); err == nil {
table.ResourceVersion = m.GetResourceVersion() table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
table.Continue = m.GetContinue() table.Continue = m.GetContinue()
table.RemainingItemCount = m.GetRemainingItemCount() table.RemainingItemCount = m.GetRemainingItemCount()
} else { } else {
if m, err := meta.CommonAccessor(obj); err == nil { if m, err := meta.CommonAccessor(obj); err == nil {
table.ResourceVersion = m.GetResourceVersion() table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
} }
} }
return table, nil return table, nil

View File

@ -19,7 +19,6 @@ package apiserver
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"path"
"sort" "sort"
"strings" "strings"
"sync" "sync"
@ -814,14 +813,6 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
replicasPathInCustomResource, replicasPathInCustomResource,
) )
selfLinkPrefix := ""
switch crd.Spec.Scope {
case apiextensionsv1.ClusterScoped:
selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, v.Name) + "/" + crd.Status.AcceptedNames.Plural + "/"
case apiextensionsv1.NamespaceScoped:
selfLinkPrefix = "/" + path.Join("apis", crd.Spec.Group, v.Name, "namespaces") + "/"
}
clusterScoped := crd.Spec.Scope == apiextensionsv1.ClusterScoped clusterScoped := crd.Spec.Scope == apiextensionsv1.ClusterScoped
// CRDs explicitly do not support protobuf, but some objects returned by the API server do // CRDs explicitly do not support protobuf, but some objects returned by the API server do
@ -843,9 +834,8 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
requestScopes[v.Name] = &handlers.RequestScope{ requestScopes[v.Name] = &handlers.RequestScope{
Namer: handlers.ContextBasedNaming{ Namer: handlers.ContextBasedNaming{
SelfLinker: meta.NewAccessor(), Namer: meta.NewAccessor(),
ClusterScoped: clusterScoped, ClusterScoped: clusterScoped,
SelfLinkPathPrefix: selfLinkPrefix,
}, },
Serializer: negotiatedSerializer, Serializer: negotiatedSerializer,
ParameterCodec: parameterCodec, ParameterCodec: parameterCodec,
@ -896,10 +886,8 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
scaleScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme()) scaleScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme())
scaleScope.Kind = autoscalingv1.SchemeGroupVersion.WithKind("Scale") scaleScope.Kind = autoscalingv1.SchemeGroupVersion.WithKind("Scale")
scaleScope.Namer = handlers.ContextBasedNaming{ scaleScope.Namer = handlers.ContextBasedNaming{
SelfLinker: meta.NewAccessor(), Namer: meta.NewAccessor(),
ClusterScoped: clusterScoped, ClusterScoped: clusterScoped,
SelfLinkPathPrefix: selfLinkPrefix,
SelfLinkPathSuffix: "/scale",
} }
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Scale != nil { if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Scale != nil {
@ -921,10 +909,8 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
statusScope := *requestScopes[v.Name] statusScope := *requestScopes[v.Name]
statusScope.Subresource = "status" statusScope.Subresource = "status"
statusScope.Namer = handlers.ContextBasedNaming{ statusScope.Namer = handlers.ContextBasedNaming{
SelfLinker: meta.NewAccessor(), Namer: meta.NewAccessor(),
ClusterScoped: clusterScoped, ClusterScoped: clusterScoped,
SelfLinkPathPrefix: selfLinkPrefix,
SelfLinkPathSuffix: "/status",
} }
if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Status != nil { if utilfeature.DefaultFeatureGate.Enabled(features.ServerSideApply) && subresources != nil && subresources.Status != nil {

View File

@ -2051,7 +2051,7 @@ func schema_pkg_apis_meta_v1_ListMeta(ref common.ReferenceCallback) common.OpenA
Properties: map[string]spec.Schema{ Properties: map[string]spec.Schema{
"selfLink": { "selfLink": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", Description: "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
}, },
@ -2277,7 +2277,7 @@ func schema_pkg_apis_meta_v1_ObjectMeta(ref common.ReferenceCallback) common.Ope
}, },
"selfLink": { "selfLink": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", Description: "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
Type: []string{"string"}, Type: []string{"string"},
Format: "", Format: "",
}, },

View File

@ -90,13 +90,11 @@ func (c *convertor) ConvertToTable(ctx context.Context, obj runtime.Object, tabl
if m, err := meta.ListAccessor(obj); err == nil { if m, err := meta.ListAccessor(obj); err == nil {
table.ResourceVersion = m.GetResourceVersion() table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
table.Continue = m.GetContinue() table.Continue = m.GetContinue()
table.RemainingItemCount = m.GetRemainingItemCount() table.RemainingItemCount = m.GetRemainingItemCount()
} else { } else {
if m, err := meta.CommonAccessor(obj); err == nil { if m, err := meta.CommonAccessor(obj); err == nil {
table.ResourceVersion = m.GetResourceVersion() table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
} }
} }

View File

@ -35,10 +35,7 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
featuregatetesting "k8s.io/component-base/featuregate/testing"
) )
func TestServerUp(t *testing.T) { func TestServerUp(t *testing.T) {
@ -626,55 +623,6 @@ func TestSameNameDiffNamespace(t *testing.T) {
} }
func TestSelfLink(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RemoveSelfLink, false)()
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
if err != nil {
t.Fatal(err)
}
defer tearDown()
// namespace scoped
noxuDefinition := fixtures.NewNoxuV1CustomResourceDefinition(apiextensionsv1.NamespaceScoped)
noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
if err != nil {
t.Fatal(err)
}
ns := "not-the-default"
noxuNamespacedResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo")
createdNoxuInstance, err := noxuNamespacedResourceClient.Create(context.TODO(), noxuInstanceToCreate, metav1.CreateOptions{})
if err != nil {
t.Fatal(err)
}
if e, a := "/apis/mygroup.example.com/v1beta1/namespaces/not-the-default/noxus/foo", createdNoxuInstance.GetSelfLink(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
// cluster scoped
curletDefinition := fixtures.NewCurletV1CustomResourceDefinition(apiextensionsv1.ClusterScoped)
curletDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(curletDefinition, apiExtensionClient, dynamicClient)
if err != nil {
t.Fatal(err)
}
curletResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, curletDefinition)
curletInstanceToCreate := fixtures.NewCurletInstance(ns, "foo")
createdCurletInstance, err := curletResourceClient.Create(context.TODO(), curletInstanceToCreate, metav1.CreateOptions{})
if err != nil {
t.Fatal(err)
}
if e, a := "/apis/mygroup.example.com/v1beta1/curlets/foo", createdCurletInstance.GetSelfLink(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
}
func TestPreserveInt(t *testing.T) { func TestPreserveInt(t *testing.T) {
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t) tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
if err != nil { if err != nil {

View File

@ -32,7 +32,6 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/features"
genericfeatures "k8s.io/apiserver/pkg/features" genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
@ -330,14 +329,6 @@ func TestScaleSubresource(t *testing.T) {
t.Fatalf("Scale.Status.Selector: expected: %v, got: %v", "bar", gottenScale.Status.Selector) t.Fatalf("Scale.Status.Selector: expected: %v, got: %v", "bar", gottenScale.Status.Selector)
} }
if !utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) {
// check self link
expectedSelfLink := fmt.Sprintf("/apis/mygroup.example.com/%s/namespaces/not-the-default/noxus/foo/scale", v.Name)
if gottenScale.GetSelfLink() != expectedSelfLink {
t.Fatalf("Scale.Metadata.SelfLink: expected: %v, got: %v", expectedSelfLink, gottenScale.GetSelfLink())
}
}
// update the scale object // update the scale object
// check that spec is updated, but status is not // check that spec is updated, but status is not
gottenScale.Spec.Replicas = 5 gottenScale.Spec.Replicas = 5

View File

@ -457,13 +457,7 @@ message List {
// ListMeta describes metadata that synthetic resources must have, including lists and // ListMeta describes metadata that synthetic resources must have, including lists and
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}. // various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
message ListMeta { message ListMeta {
// selfLink is a URL representing this object. // selfLink is DEPRECATED read-only field that is no longer populated by the system.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional // +optional
optional string selfLink = 1; optional string selfLink = 1;
@ -683,13 +677,7 @@ message ObjectMeta {
// +optional // +optional
optional string namespace = 3; optional string namespace = 3;
// SelfLink is a URL representing this object. // selfLink is DEPRECATED read-only field that is no longer populated by the system.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional // +optional
optional string selfLink = 4; optional string selfLink = 4;

View File

@ -58,13 +58,7 @@ type TypeMeta struct {
// ListMeta describes metadata that synthetic resources must have, including lists and // ListMeta describes metadata that synthetic resources must have, including lists and
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}. // various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
type ListMeta struct { type ListMeta struct {
// selfLink is a URL representing this object. // selfLink is DEPRECATED read-only field that is no longer populated by the system.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional // +optional
SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,1,opt,name=selfLink"` SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,1,opt,name=selfLink"`
@ -152,13 +146,7 @@ type ObjectMeta struct {
// +optional // +optional
Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`
// SelfLink is a URL representing this object. // selfLink is DEPRECATED read-only field that is no longer populated by the system.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional // +optional
SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"` SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"`

View File

@ -195,7 +195,7 @@ func (List) SwaggerDoc() map[string]string {
var map_ListMeta = map[string]string{ var map_ListMeta = map[string]string{
"": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", "": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.",
"selfLink": "selfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "selfLink": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", "resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency",
"continue": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", "continue": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.",
"remainingItemCount": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.", "remainingItemCount": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.",
@ -242,7 +242,7 @@ var map_ObjectMeta = map[string]string{
"name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", "name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
"generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", "generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency",
"namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", "namespace": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces",
"selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", "selfLink": "selfLink is DEPRECATED read-only field that is no longer populated by the system.",
"uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", "uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
"resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", "resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency",
"generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", "generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.",

View File

@ -284,14 +284,11 @@ type ResourceVersioner interface {
ResourceVersion(obj Object) (string, error) ResourceVersion(obj Object) (string, error)
} }
// SelfLinker provides methods for setting and retrieving the SelfLink field of an API object. // Namer provides methods for retrieving name and namespace of an API object.
type SelfLinker interface { type Namer interface {
SetSelfLink(obj Object, selfLink string) error // Name returns the name of a given object.
SelfLink(obj Object) (string, error)
// Knowing Name is sometimes necessary to use a SelfLinker.
Name(obj Object) (string, error) Name(obj Object) (string, error)
// Knowing Namespace is sometimes necessary to use a SelfLinker // Namespace returns the name of a given object.
Namespace(obj Object) (string, error) Namespace(obj Object) (string, error)
} }

View File

@ -298,51 +298,6 @@ func TestResourceVersionerOfAPI(t *testing.T) {
} }
} }
func TestTypeMetaSelfLinker(t *testing.T) {
table := map[string]struct {
obj runtime.Object
expect string
try string
succeed bool
}{
"normal": {
obj: &MyAPIObject{TypeMeta: InternalTypeMeta{SelfLink: "foobar"}},
expect: "foobar",
try: "newbar",
succeed: true,
},
"fail": {
obj: &MyIncorrectlyMarkedAsAPIObject{},
succeed: false,
},
}
linker := runtime.SelfLinker(meta.NewAccessor())
for name, item := range table {
got, err := linker.SelfLink(item.obj)
if e, a := item.succeed, err == nil; e != a {
t.Errorf("%v: expected %v, got %v", name, e, a)
}
if e, a := item.expect, got; item.succeed && e != a {
t.Errorf("%v: expected %v, got %v", name, e, a)
}
err = linker.SetSelfLink(item.obj, item.try)
if e, a := item.succeed, err == nil; e != a {
t.Errorf("%v: expected %v, got %v", name, e, a)
}
if item.succeed {
got, err := linker.SelfLink(item.obj)
if err != nil {
t.Errorf("%v: expected no err, got %v", name, err)
}
if e, a := item.try, got; e != a {
t.Errorf("%v: expected %v, got %v", name, e, a)
}
}
}
}
type MyAPIObject2 struct { type MyAPIObject2 struct {
metav1.TypeMeta metav1.TypeMeta
metav1.ObjectMeta metav1.ObjectMeta

View File

@ -126,7 +126,7 @@ var newCodec = codecs.LegacyCodec(newGroupVersion)
var parameterCodec = runtime.NewParameterCodec(scheme) var parameterCodec = runtime.NewParameterCodec(scheme)
var accessor = meta.NewAccessor() var accessor = meta.NewAccessor()
var selfLinker runtime.SelfLinker = accessor var namer runtime.Namer = accessor
var admissionControl admission.Interface var admissionControl admission.Interface
func init() { func init() {
@ -216,15 +216,10 @@ type defaultAPIServer struct {
// uses the default settings // uses the default settings
func handle(storage map[string]rest.Storage) http.Handler { func handle(storage map[string]rest.Storage) http.Handler {
return handleInternal(storage, admissionControl, selfLinker, nil) return handleInternal(storage, admissionControl, nil)
} }
// tests using a custom self linker func handleInternal(storage map[string]rest.Storage, admissionControl admission.Interface, auditSink audit.Sink) http.Handler {
func handleLinker(storage map[string]rest.Storage, selfLinker runtime.SelfLinker) http.Handler {
return handleInternal(storage, admissionControl, selfLinker, nil)
}
func handleInternal(storage map[string]rest.Storage, admissionControl admission.Interface, selfLinker runtime.SelfLinker, auditSink audit.Sink) http.Handler {
container := restful.NewContainer() container := restful.NewContainer()
container.Router(restful.CurlyRouter{}) container.Router(restful.CurlyRouter{})
mux := container.ServeMux mux := container.ServeMux
@ -237,7 +232,7 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,
Linker: selfLinker, Namer: namer,
RootScopedKinds: sets.NewString("SimpleRoot"), RootScopedKinds: sets.NewString("SimpleRoot"),
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(), EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
@ -376,7 +371,6 @@ func (storage *SimpleRESTStorage) List(ctx context.Context, options *metainterna
result := &genericapitesting.SimpleList{ result := &genericapitesting.SimpleList{
ListMeta: metav1.ListMeta{ ListMeta: metav1.ListMeta{
ResourceVersion: "10", ResourceVersion: "10",
SelfLink: "/test/link",
}, },
Items: storage.list, Items: storage.list,
} }
@ -942,7 +936,6 @@ func TestList(t *testing.T) {
testCases := []struct { testCases := []struct {
url string url string
namespace string namespace string
selfLink string
legacy bool legacy bool
label string label string
field string field string
@ -953,19 +946,16 @@ func TestList(t *testing.T) {
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple?namespace=", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple?namespace=",
namespace: "", namespace: "",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple?namespace=other", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple?namespace=other",
namespace: "", namespace: "",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple?namespace=other&labelSelector=a%3Db&fieldSelector=c%3Dd", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple?namespace=other&labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "", namespace: "",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
legacy: true, legacy: true,
label: "a=b", label: "a=b",
field: "c=d", field: "c=d",
@ -974,19 +964,16 @@ func TestList(t *testing.T) {
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
namespace: "", namespace: "",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple",
namespace: "other", namespace: "other",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "other", namespace: "other",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple",
legacy: true, legacy: true,
label: "a=b", label: "a=b",
field: "c=d", field: "c=d",
@ -995,24 +982,20 @@ func TestList(t *testing.T) {
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
namespace: "", namespace: "",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
// list items in a namespace in the path // list items in a namespace in the path
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple",
namespace: "default", namespace: "default",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple",
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple",
namespace: "other", namespace: "other",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple",
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "other", namespace: "other",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/other/simple",
label: "a=b", label: "a=b",
field: "c=d", field: "c=d",
}, },
@ -1020,7 +1003,6 @@ func TestList(t *testing.T) {
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
namespace: "", namespace: "",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simple",
}, },
// Group API // Group API
@ -1029,19 +1011,16 @@ func TestList(t *testing.T) {
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=",
namespace: "", namespace: "",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other",
namespace: "", namespace: "",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other&labelSelector=a%3Db&fieldSelector=c%3Dd", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other&labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "", namespace: "",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true, legacy: true,
label: "a=b", label: "a=b",
field: "c=d", field: "c=d",
@ -1050,19 +1029,16 @@ func TestList(t *testing.T) {
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
namespace: "", namespace: "",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
namespace: "other", namespace: "other",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
legacy: true, legacy: true,
}, },
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "other", namespace: "other",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
legacy: true, legacy: true,
label: "a=b", label: "a=b",
field: "c=d", field: "c=d",
@ -1071,24 +1047,20 @@ func TestList(t *testing.T) {
{ {
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
namespace: "", namespace: "",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true, legacy: true,
}, },
// list items in a namespace in the path // list items in a namespace in the path
{ {
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple", url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple",
namespace: "default", namespace: "default",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple",
}, },
{ {
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple", url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple",
namespace: "other", namespace: "other",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple",
}, },
{ {
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd", url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "other", namespace: "other",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple",
label: "a=b", label: "a=b",
field: "c=d", field: "c=d",
}, },
@ -1096,19 +1068,13 @@ func TestList(t *testing.T) {
{ {
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple", url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple",
namespace: "", namespace: "",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple",
}, },
} }
for i, testCase := range testCases { for i, testCase := range testCases {
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
simpleStorage := SimpleRESTStorage{expectedResourceNamespace: testCase.namespace} simpleStorage := SimpleRESTStorage{expectedResourceNamespace: testCase.namespace}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{ var handler = handleInternal(storage, admissionControl, nil)
t: t,
namespace: testCase.namespace,
expectedSet: testCase.selfLink,
}
var handler = handleInternal(storage, admissionControl, selfLinker, nil)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1128,9 +1094,6 @@ func TestList(t *testing.T) {
t.Logf("%d: body: %s", i, string(body)) t.Logf("%d: body: %s", i, string(body))
continue continue
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("%d: unexpected selfLinker.called: %v", i, selfLinker.called)
}
if !simpleStorage.namespacePresent { if !simpleStorage.namespacePresent {
t.Errorf("%d: namespace not set", i) t.Errorf("%d: namespace not set", i)
} else if simpleStorage.actualNamespace != testCase.namespace { } else if simpleStorage.actualNamespace != testCase.namespace {
@ -1151,7 +1114,7 @@ func TestRequestsWithInvalidQuery(t *testing.T) {
storage["simple"] = &SimpleRESTStorage{expectedResourceNamespace: "default"} storage["simple"] = &SimpleRESTStorage{expectedResourceNamespace: "default"}
storage["withoptions"] = GetWithOptionsRESTStorage{} storage["withoptions"] = GetWithOptionsRESTStorage{}
var handler = handleInternal(storage, admissionControl, selfLinker, nil) var handler = handleInternal(storage, admissionControl, nil)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1195,7 +1158,6 @@ func TestListCompression(t *testing.T) {
testCases := []struct { testCases := []struct {
url string url string
namespace string namespace string
selfLink string
legacy bool legacy bool
label string label string
field string field string
@ -1205,13 +1167,11 @@ func TestListCompression(t *testing.T) {
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple",
namespace: "default", namespace: "default",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple",
acceptEncoding: "", acceptEncoding: "",
}, },
{ {
url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple", url: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple",
namespace: "default", namespace: "default",
selfLink: "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/simple",
acceptEncoding: "gzip", acceptEncoding: "gzip",
}, },
} }
@ -1224,12 +1184,7 @@ func TestListCompression(t *testing.T) {
}, },
} }
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{ var handler = handleInternal(storage, admissionControl, nil)
t: t,
namespace: testCase.namespace,
expectedSet: testCase.selfLink,
}
var handler = handleInternal(storage, admissionControl, selfLinker, nil)
handler = genericapifilters.WithRequestInfo(handler, newTestRequestInfoResolver()) handler = genericapifilters.WithRequestInfo(handler, newTestRequestInfoResolver())
@ -1262,9 +1217,6 @@ func TestListCompression(t *testing.T) {
t.Logf("%d: body: %s", i, string(body)) t.Logf("%d: body: %s", i, string(body))
continue continue
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("%d: unexpected selfLinker.called: %v", i, selfLinker.called)
}
if !simpleStorage.namespacePresent { if !simpleStorage.namespacePresent {
t.Errorf("%d: namespace not set", i) t.Errorf("%d: namespace not set", i)
} else if simpleStorage.actualNamespace != testCase.namespace { } else if simpleStorage.actualNamespace != testCase.namespace {
@ -1381,126 +1333,6 @@ func TestNonEmptyList(t *testing.T) {
if listOut.Items[0].Other != simpleStorage.list[0].Other { if listOut.Items[0].Other != simpleStorage.list[0].Other {
t.Errorf("Unexpected data: %#v, %s", listOut.Items[0], string(body)) t.Errorf("Unexpected data: %#v, %s", listOut.Items[0], string(body))
} }
if !utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) {
if listOut.SelfLink != "/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/simple" {
t.Errorf("unexpected list self link: %#v", listOut)
}
expectedSelfLink := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple/something"
if listOut.Items[0].ObjectMeta.SelfLink != expectedSelfLink {
t.Errorf("Unexpected data: %#v, %s", listOut.Items[0].ObjectMeta.SelfLink, expectedSelfLink)
}
}
}
func TestSelfLinkSkipsEmptyName(t *testing.T) {
storage := map[string]rest.Storage{}
simpleStorage := SimpleRESTStorage{
list: []genericapitesting.Simple{
{
ObjectMeta: metav1.ObjectMeta{Namespace: "other"},
Other: "foo",
},
},
}
storage["simple"] = &simpleStorage
handler := handle(storage)
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected status: %d, Expected: %d, %#v", resp.StatusCode, http.StatusOK, resp)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
t.Logf("Data: %s", string(body))
}
var listOut genericapitesting.SimpleList
body, err := extractBody(resp, &listOut)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(listOut.Items) != 1 {
t.Errorf("Unexpected response: %#v", listOut)
return
}
if listOut.Items[0].Other != simpleStorage.list[0].Other {
t.Errorf("Unexpected data: %#v, %s", listOut.Items[0], string(body))
}
if !utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) {
if listOut.SelfLink != "/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/simple" {
t.Errorf("unexpected list self link: %#v", listOut)
}
expectedSelfLink := ""
if listOut.Items[0].ObjectMeta.SelfLink != expectedSelfLink {
t.Errorf("Unexpected data: %#v, %s", listOut.Items[0].ObjectMeta.SelfLink, expectedSelfLink)
}
}
}
func TestRootSelfLink(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RemoveSelfLink, false)()
storage := map[string]rest.Storage{}
simpleStorage := GetWithOptionsRootRESTStorage{
SimpleTypedStorage: &SimpleTypedStorage{
baseType: &genericapitesting.SimpleRoot{}, // a root scoped type
item: &genericapitesting.SimpleRoot{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Other: "foo",
},
},
takesPath: "atAPath",
}
storage["simple"] = &simpleStorage
storage["simple/sub"] = &simpleStorage
handler := handle(storage)
server := httptest.NewServer(handler)
defer server.Close()
testCases := []struct {
url string
selfLink string
}{
{
url: server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple/foo",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple/foo",
},
{
url: server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple/foo/sub",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple/foo/sub",
},
}
for _, test := range testCases {
resp, err := http.Get(test.url)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("Unexpected status: %d, Expected: %d, %#v", resp.StatusCode, http.StatusOK, resp)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
t.Logf("Data: %s", string(body))
}
var out genericapitesting.SimpleRoot
if _, err := extractBody(resp, &out); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if out.SelfLink != test.selfLink {
t.Errorf("unexpected self link: %#v", out.SelfLink)
}
}
} }
func TestMetadata(t *testing.T) { func TestMetadata(t *testing.T) {
@ -1547,14 +1379,8 @@ func TestGet(t *testing.T) {
Other: "foo", Other: "foo",
}, },
} }
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
name: "id",
namespace: "default",
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1574,9 +1400,6 @@ func TestGet(t *testing.T) {
if itemOut.Name != simpleStorage.item.Name { if itemOut.Name != simpleStorage.item.Name {
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body)) t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body))
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
func BenchmarkGet(b *testing.B) { func BenchmarkGet(b *testing.B) {
@ -1586,13 +1409,8 @@ func BenchmarkGet(b *testing.B) {
Other: "foo", Other: "foo",
}, },
} }
selfLinker := &setTestSelfLinker{
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
name: "id",
namespace: "default",
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1621,13 +1439,8 @@ func BenchmarkGetNoCompression(b *testing.B) {
Other: "foo", Other: "foo",
}, },
} }
selfLinker := &setTestSelfLinker{
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
name: "id",
namespace: "default",
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1662,15 +1475,9 @@ func TestGetCompression(t *testing.T) {
Other: strings.Repeat("0123456789abcdef", (128*1024/16)+1), Other: strings.Repeat("0123456789abcdef", (128*1024/16)+1),
}, },
} }
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
name: "id",
namespace: "default",
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
handler = genericapifilters.WithRequestInfo(handler, newTestRequestInfoResolver()) handler = genericapifilters.WithRequestInfo(handler, newTestRequestInfoResolver())
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1721,9 +1528,6 @@ func TestGetCompression(t *testing.T) {
if itemOut.Name != simpleStorage.item.Name { if itemOut.Name != simpleStorage.item.Name {
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body)) t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body))
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
} }
@ -1734,14 +1538,8 @@ func TestGetPretty(t *testing.T) {
Other: "foo", Other: "foo",
}, },
} }
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
name: "id",
namespace: "default",
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -1813,7 +1611,7 @@ func TestGetPretty(t *testing.T) {
func TestGetTable(t *testing.T) { func TestGetTable(t *testing.T) {
now := metav1.Now() now := metav1.Now()
obj := genericapitesting.Simple{ obj := genericapitesting.Simple{
ObjectMeta: metav1.ObjectMeta{Name: "foo1", Namespace: "ns1", ResourceVersion: "10", SelfLink: "/blah", CreationTimestamp: now, UID: types.UID("abcdef0123")}, ObjectMeta: metav1.ObjectMeta{Name: "foo1", Namespace: "ns1", ResourceVersion: "10", CreationTimestamp: now, UID: types.UID("abcdef0123")},
Other: "foo", Other: "foo",
} }
@ -1872,7 +1670,7 @@ func TestGetTable(t *testing.T) {
accept: "application/json;as=Table;v=v1;g=meta.k8s.io", accept: "application/json;as=Table;v=v1;g=meta.k8s.io",
expected: &metav1.Table{ expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -1887,7 +1685,7 @@ func TestGetTable(t *testing.T) {
accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io", accept: "application/json;as=Table;v=v1beta1;g=meta.k8s.io",
expected: &metav1.Table{ expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -1905,7 +1703,7 @@ func TestGetTable(t *testing.T) {
}, ","), }, ","),
expected: &metav1.Table{ expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -1921,7 +1719,7 @@ func TestGetTable(t *testing.T) {
params: url.Values{"includeObject": []string{"Metadata"}}, params: url.Values{"includeObject": []string{"Metadata"}},
expected: &metav1.Table{ expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -1936,7 +1734,7 @@ func TestGetTable(t *testing.T) {
params: url.Values{"includeObject": []string{"Metadata"}}, params: url.Values{"includeObject": []string{"Metadata"}},
expected: &metav1.Table{ expected: &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/test/link"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -1954,17 +1752,8 @@ func TestGetTable(t *testing.T) {
item: obj, item: obj,
list: []genericapitesting.Simple{obj}, list: []genericapitesting.Simple{obj},
} }
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple",
namespace: "default",
}
if test.item {
selfLinker.expectedSet += "/id"
selfLinker.name = "id"
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -2016,7 +1805,7 @@ func TestGetTable(t *testing.T) {
func TestWatchTable(t *testing.T) { func TestWatchTable(t *testing.T) {
obj := genericapitesting.Simple{ obj := genericapitesting.Simple{
ObjectMeta: metav1.ObjectMeta{Name: "foo1", Namespace: "ns1", ResourceVersion: "10", SelfLink: "/blah", CreationTimestamp: metav1.NewTime(time.Unix(1, 0)), UID: types.UID("abcdef0123")}, ObjectMeta: metav1.ObjectMeta{Name: "foo1", Namespace: "ns1", ResourceVersion: "10", CreationTimestamp: metav1.NewTime(time.Unix(1, 0)), UID: types.UID("abcdef0123")},
Other: "foo", Other: "foo",
} }
@ -2069,7 +1858,7 @@ func TestWatchTable(t *testing.T) {
Object: runtime.RawExtension{ Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -2094,7 +1883,7 @@ func TestWatchTable(t *testing.T) {
Object: runtime.RawExtension{ Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -2110,7 +1899,7 @@ func TestWatchTable(t *testing.T) {
Object: runtime.RawExtension{ Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1beta1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
Rows: []metav1.TableRow{ Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}}, {Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBody}},
}, },
@ -2131,7 +1920,7 @@ func TestWatchTable(t *testing.T) {
Object: runtime.RawExtension{ Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
ColumnDefinitions: []metav1.TableColumnDefinition{ ColumnDefinitions: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metaDoc["name"]},
{Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]}, {Name: "Created At", Type: "date", Description: metaDoc["creationTimestamp"]},
@ -2147,7 +1936,7 @@ func TestWatchTable(t *testing.T) {
Object: runtime.RawExtension{ Object: runtime.RawExtension{
Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{ Raw: []byte(strings.TrimSpace(runtime.EncodeOrDie(s, &metav1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"}, TypeMeta: metav1.TypeMeta{Kind: "Table", APIVersion: "meta.k8s.io/v1"},
ListMeta: metav1.ListMeta{ResourceVersion: "10", SelfLink: "/blah"}, ListMeta: metav1.ListMeta{ResourceVersion: "10"},
Rows: []metav1.TableRow{ Rows: []metav1.TableRow{
{Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBodyV1}}, {Cells: []interface{}{"foo1", time.Unix(1, 0).UTC().Format(time.RFC3339)}, Object: runtime.RawExtension{Raw: encodedBodyV1}},
}, },
@ -2165,17 +1954,8 @@ func TestWatchTable(t *testing.T) {
list: []genericapitesting.Simple{obj}, list: []genericapitesting.Simple{obj},
} }
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple",
namespace: "default",
}
if test.item {
selfLinker.expectedSet += "/id"
selfLinker.name = "id"
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -2288,15 +2068,8 @@ func TestGetPartialObjectMetadata(t *testing.T) {
}, },
}, },
} }
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
alternativeSet: sets.NewString("/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple"),
name: "id",
namespace: "default",
}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker) handler := handle(storage)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -2379,7 +2152,6 @@ func TestGetPartialObjectMetadata(t *testing.T) {
expected: &metav1beta1.PartialObjectMetadataList{ expected: &metav1beta1.PartialObjectMetadataList{
ListMeta: metav1.ListMeta{ ListMeta: metav1.ListMeta{
ResourceVersion: "10", ResourceVersion: "10",
SelfLink: "/test/link",
}, },
Items: []metav1beta1.PartialObjectMetadata{ Items: []metav1beta1.PartialObjectMetadata{
{ {
@ -2669,82 +2441,6 @@ func TestGetWithOptions(t *testing.T) {
} }
} }
func TestGetAlternateSelfLink(t *testing.T) {
storage := map[string]rest.Storage{}
simpleStorage := SimpleRESTStorage{
item: genericapitesting.Simple{
Other: "foo",
},
}
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/test/simple/id",
name: "id",
namespace: "test",
}
storage["simple"] = &simpleStorage
handler := handleLinker(storage, selfLinker)
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/test/simple/id")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("unexpected response: %#v", resp)
}
var itemOut genericapitesting.Simple
body, err := extractBody(resp, &itemOut)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if itemOut.Name != simpleStorage.item.Name {
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body))
}
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
}
func TestGetNamespaceSelfLink(t *testing.T) {
storage := map[string]rest.Storage{}
simpleStorage := SimpleRESTStorage{
item: genericapitesting.Simple{
Other: "foo",
},
}
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/foo/simple/id",
name: "id",
namespace: "foo",
}
storage["simple"] = &simpleStorage
handler := handleInternal(storage, admissionControl, selfLinker, nil)
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/foo/simple/id")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("unexpected response: %#v", resp)
}
var itemOut genericapitesting.Simple
body, err := extractBody(resp, &itemOut)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if itemOut.Name != simpleStorage.item.Name {
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body))
}
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
}
func TestGetMissing(t *testing.T) { func TestGetMissing(t *testing.T) {
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
simpleStorage := SimpleRESTStorage{ simpleStorage := SimpleRESTStorage{
@ -3194,7 +2890,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) {
simpleStorage := SimpleRESTStorage{} simpleStorage := SimpleRESTStorage{}
ID := "id" ID := "id"
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleInternal(storage, admit, selfLinker, nil) handler := handleInternal(storage, admit, nil)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -3244,13 +2940,7 @@ func TestUpdate(t *testing.T) {
simpleStorage := SimpleRESTStorage{} simpleStorage := SimpleRESTStorage{}
ID := "id" ID := "id"
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{ handler := handle(storage)
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID,
name: ID,
namespace: metav1.NamespaceDefault,
}
handler := handleLinker(storage, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -3282,9 +2972,6 @@ func TestUpdate(t *testing.T) {
if simpleStorage.updated == nil || simpleStorage.updated.Name != item.Name { if simpleStorage.updated == nil || simpleStorage.updated.Name != item.Name {
t.Errorf("Unexpected update value %#v, expected %#v.", simpleStorage.updated, item) t.Errorf("Unexpected update value %#v, expected %#v.", simpleStorage.updated, item)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
func TestUpdateInvokesAdmissionControl(t *testing.T) { func TestUpdateInvokesAdmissionControl(t *testing.T) {
@ -3295,7 +2982,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) {
simpleStorage := SimpleRESTStorage{} simpleStorage := SimpleRESTStorage{}
ID := "id" ID := "id"
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := handleInternal(storage, admit, selfLinker, nil) handler := handleInternal(storage, admit, nil)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -3408,11 +3095,7 @@ func TestUpdateDisallowsMismatchedNamespaceOnError(t *testing.T) {
simpleStorage := SimpleRESTStorage{} simpleStorage := SimpleRESTStorage{}
ID := "id" ID := "id"
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{ handler := handle(storage)
t: t,
err: fmt.Errorf("test error"),
}
handler := handleLinker(storage, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -3444,9 +3127,6 @@ func TestUpdateDisallowsMismatchedNamespaceOnError(t *testing.T) {
if simpleStorage.updated != nil { if simpleStorage.updated != nil {
t.Errorf("Unexpected update value %#v.", simpleStorage.updated) t.Errorf("Unexpected update value %#v.", simpleStorage.updated)
} }
if selfLinker.called {
t.Errorf("self link ignored")
}
} }
func TestUpdatePreventsMismatchedNamespace(t *testing.T) { func TestUpdatePreventsMismatchedNamespace(t *testing.T) {
@ -3599,7 +3279,7 @@ func TestParentResourceIsRequired(t *testing.T) {
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,
Linker: selfLinker, Namer: namer,
RootScopedKinds: sets.NewString("SimpleRoot"), RootScopedKinds: sets.NewString("SimpleRoot"),
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(), EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
@ -3632,7 +3312,7 @@ func TestParentResourceIsRequired(t *testing.T) {
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,
Linker: selfLinker, Namer: namer,
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(), EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
@ -3711,13 +3391,7 @@ func TestNamedCreaterWithoutName(t *testing.T) {
}, },
} }
selfLinker := &setTestSelfLinker{ handler := handle(map[string]rest.Storage{"foo": storage})
t: t,
name: "bar",
namespace: "default",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo",
}
handler := handleLinker(map[string]rest.Storage{"foo": storage}, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
client := http.Client{} client := http.Client{}
@ -3786,18 +3460,12 @@ func TestNamedCreaterWithGenerateName(t *testing.T) {
}, },
} }
selfLinker := &setTestSelfLinker{
t: t,
namespace: "default",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo",
}
ac := &namePopulatorAdmissionControl{ ac := &namePopulatorAdmissionControl{
t: t, t: t,
populateName: populateName, populateName: populateName,
} }
handler := handleInternal(map[string]rest.Storage{"foo": storage}, ac, selfLinker, nil) handler := handleInternal(map[string]rest.Storage{"foo": storage}, ac, nil)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
client := http.Client{} client := http.Client{}
@ -3872,29 +3540,6 @@ func TestUpdateChecksDecode(t *testing.T) {
} }
} }
type setTestSelfLinker struct {
t *testing.T
expectedSet string
alternativeSet sets.String
name string
namespace string
called bool
err error
}
func (s *setTestSelfLinker) Namespace(runtime.Object) (string, error) { return s.namespace, s.err }
func (s *setTestSelfLinker) Name(runtime.Object) (string, error) { return s.name, s.err }
func (s *setTestSelfLinker) SelfLink(runtime.Object) (string, error) { return "", s.err }
func (s *setTestSelfLinker) SetSelfLink(obj runtime.Object, selfLink string) error {
if e, a := s.expectedSet, selfLink; e != a {
if !s.alternativeSet.Has(a) {
s.t.Errorf("expected '%v', got '%v'", e, a)
}
}
s.called = true
return s.err
}
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage := SimpleRESTStorage{ storage := SimpleRESTStorage{
injectedFunction: func(obj runtime.Object) (runtime.Object, error) { injectedFunction: func(obj runtime.Object) (runtime.Object, error) {
@ -3902,13 +3547,7 @@ func TestCreate(t *testing.T) {
return obj, nil return obj, nil
}, },
} }
selfLinker := &setTestSelfLinker{ handler := handle(map[string]rest.Storage{"foo": &storage})
t: t,
name: "bar",
namespace: "default",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar",
}
handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
client := http.Client{} client := http.Client{}
@ -3950,9 +3589,6 @@ func TestCreate(t *testing.T) {
if response.StatusCode != http.StatusCreated { if response.StatusCode != http.StatusCreated {
t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusOK, response) t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusOK, response)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
func TestCreateYAML(t *testing.T) { func TestCreateYAML(t *testing.T) {
@ -3962,13 +3598,7 @@ func TestCreateYAML(t *testing.T) {
return obj, nil return obj, nil
}, },
} }
selfLinker := &setTestSelfLinker{ handler := handle(map[string]rest.Storage{"foo": &storage})
t: t,
name: "bar",
namespace: "default",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar",
}
handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
client := http.Client{} client := http.Client{}
@ -4020,9 +3650,6 @@ func TestCreateYAML(t *testing.T) {
if response.StatusCode != http.StatusCreated { if response.StatusCode != http.StatusCreated {
t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusOK, response) t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusOK, response)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
func TestCreateInNamespace(t *testing.T) { func TestCreateInNamespace(t *testing.T) {
@ -4032,13 +3659,7 @@ func TestCreateInNamespace(t *testing.T) {
return obj, nil return obj, nil
}, },
} }
selfLinker := &setTestSelfLinker{ handler := handle(map[string]rest.Storage{"foo": &storage})
t: t,
name: "bar",
namespace: "other",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/foo/bar",
}
handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
client := http.Client{} client := http.Client{}
@ -4080,9 +3701,6 @@ func TestCreateInNamespace(t *testing.T) {
if response.StatusCode != http.StatusCreated { if response.StatusCode != http.StatusCreated {
t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusOK, response) t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusOK, response)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
func TestCreateInvokeAdmissionControl(t *testing.T) { func TestCreateInvokeAdmissionControl(t *testing.T) {
@ -4095,13 +3713,7 @@ func TestCreateInvokeAdmissionControl(t *testing.T) {
return obj, nil return obj, nil
}, },
} }
selfLinker := &setTestSelfLinker{ handler := handleInternal(map[string]rest.Storage{"foo": &storage}, admit, nil)
t: t,
name: "bar",
namespace: "other",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/foo/bar",
}
handler := handleInternal(map[string]rest.Storage{"foo": &storage}, admit, selfLinker, nil)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
client := http.Client{} client := http.Client{}
@ -4487,7 +4099,7 @@ func TestXGSubresource(t *testing.T) {
UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(scheme),
Defaulter: scheme, Defaulter: scheme,
Typer: scheme, Typer: scheme,
Linker: selfLinker, Namer: namer,
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(), EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),

View File

@ -149,7 +149,6 @@ func TestAudit(t *testing.T) {
for _, test := range []struct { for _, test := range []struct {
desc string desc string
req func(server string) (*http.Request, error) req func(server string) (*http.Request, error)
linker runtime.SelfLinker
code int code int
events int events int
checks []eventCheck checks []eventCheck
@ -159,7 +158,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleFooJSON)) return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleFooJSON))
}, },
selfLinker,
200, 200,
2, 2,
[]eventCheck{ []eventCheck{
@ -173,11 +171,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?labelSelector=a%3Dfoobar", nil) return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?labelSelector=a%3Dfoobar", nil)
}, },
&setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
namespace: "other",
},
200, 200,
2, 2,
[]eventCheck{ []eventCheck{
@ -191,7 +184,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("POST", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(simpleFooJSON)) return http.NewRequest("POST", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(simpleFooJSON))
}, },
selfLinker,
201, 201,
2, 2,
[]eventCheck{ []eventCheck{
@ -205,7 +197,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("POST", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/named", bytes.NewBuffer(simpleFooJSON)) return http.NewRequest("POST", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/named", bytes.NewBuffer(simpleFooJSON))
}, },
selfLinker,
405, 405,
2, 2,
[]eventCheck{ []eventCheck{
@ -219,7 +210,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("DELETE", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", nil) return http.NewRequest("DELETE", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", nil)
}, },
selfLinker,
200, 200,
2, 2,
[]eventCheck{ []eventCheck{
@ -233,7 +223,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("DELETE", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", bytes.NewBuffer([]byte(`{"kind":"DeleteOptions"}`))) return http.NewRequest("DELETE", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", bytes.NewBuffer([]byte(`{"kind":"DeleteOptions"}`)))
}, },
selfLinker,
200, 200,
2, 2,
[]eventCheck{ []eventCheck{
@ -247,7 +236,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("PUT", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleCPrimeJSON)) return http.NewRequest("PUT", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleCPrimeJSON))
}, },
selfLinker,
200, 200,
2, 2,
[]eventCheck{ []eventCheck{
@ -261,7 +249,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("PUT", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/c", bytes.NewBuffer(simpleCPrimeJSON)) return http.NewRequest("PUT", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/c", bytes.NewBuffer(simpleCPrimeJSON))
}, },
selfLinker,
400, 400,
2, 2,
[]eventCheck{ []eventCheck{
@ -277,12 +264,6 @@ func TestAudit(t *testing.T) {
req.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8") req.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
return req, nil return req, nil
}, },
&setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple/c",
name: "c",
namespace: "other",
},
200, 200,
2, 2,
[]eventCheck{ []eventCheck{
@ -296,11 +277,6 @@ func TestAudit(t *testing.T) {
func(server string) (*http.Request, error) { func(server string) (*http.Request, error) {
return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?watch=true", nil) return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?watch=true", nil)
}, },
&setTestSelfLinker{
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
namespace: "other",
},
200, 200,
3, 3,
[]eventCheck{ []eventCheck{
@ -328,7 +304,7 @@ func TestAudit(t *testing.T) {
Other: "foo", Other: "foo",
}, },
}, },
}, admissionControl, selfLinker, sink) }, admissionControl, sink)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()

View File

@ -79,7 +79,7 @@ type APIGroupVersion struct {
Convertor runtime.ObjectConvertor Convertor runtime.ObjectConvertor
ConvertabilityChecker ConvertabilityChecker ConvertabilityChecker ConvertabilityChecker
Defaulter runtime.ObjectDefaulter Defaulter runtime.ObjectDefaulter
Linker runtime.SelfLinker Namer runtime.Namer
UnsafeConvertor runtime.ObjectConvertor UnsafeConvertor runtime.ObjectConvertor
TypeConverter fieldmanager.TypeConverter TypeConverter fieldmanager.TypeConverter

View File

@ -19,8 +19,6 @@ package handlers
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strings"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -38,31 +36,16 @@ type ScopeNamer interface {
// ObjectName returns the namespace and name from an object if they exist, or an error if the object // ObjectName returns the namespace and name from an object if they exist, or an error if the object
// does not support names. // does not support names.
ObjectName(obj runtime.Object) (namespace, name string, err error) ObjectName(obj runtime.Object) (namespace, name string, err error)
// SetSelfLink sets the provided URL onto the object. The method should return nil if the object
// does not support selfLinks.
SetSelfLink(obj runtime.Object, url string) error
// GenerateLink creates an encoded URI for a given runtime object that represents the canonical path
// and query.
GenerateLink(requestInfo *request.RequestInfo, obj runtime.Object) (uri string, err error)
// GenerateListLink creates an encoded URI for a list that represents the canonical path and query.
GenerateListLink(req *http.Request) (uri string, err error)
} }
type ContextBasedNaming struct { type ContextBasedNaming struct {
SelfLinker runtime.SelfLinker Namer runtime.Namer
ClusterScoped bool ClusterScoped bool
SelfLinkPathPrefix string
SelfLinkPathSuffix string
} }
// ContextBasedNaming implements ScopeNamer // ContextBasedNaming implements ScopeNamer
var _ ScopeNamer = ContextBasedNaming{} var _ ScopeNamer = ContextBasedNaming{}
func (n ContextBasedNaming) SetSelfLink(obj runtime.Object, url string) error {
return n.SelfLinker.SetSelfLink(obj, url)
}
func (n ContextBasedNaming) Namespace(req *http.Request) (namespace string, err error) { func (n ContextBasedNaming) Namespace(req *http.Request) (namespace string, err error) {
requestInfo, ok := request.RequestInfoFrom(req.Context()) requestInfo, ok := request.RequestInfoFrom(req.Context())
if !ok { if !ok {
@ -83,64 +66,15 @@ func (n ContextBasedNaming) Name(req *http.Request) (namespace, name string, err
return requestInfo.Namespace, requestInfo.Name, nil return requestInfo.Namespace, requestInfo.Name, nil
} }
// fastURLPathEncode encodes the provided path as a URL path
func fastURLPathEncode(path string) string {
for _, r := range []byte(path) {
switch {
case r >= '-' && r <= '9', r >= 'A' && r <= 'Z', r >= 'a' && r <= 'z':
// characters within this range do not require escaping
default:
var u url.URL
u.Path = path
return u.EscapedPath()
}
}
return path
}
func (n ContextBasedNaming) GenerateLink(requestInfo *request.RequestInfo, obj runtime.Object) (uri string, err error) {
namespace, name, err := n.ObjectName(obj)
if err == errEmptyName && len(requestInfo.Name) > 0 {
name = requestInfo.Name
} else if err != nil {
return "", err
}
if len(namespace) == 0 && len(requestInfo.Namespace) > 0 {
namespace = requestInfo.Namespace
}
if n.ClusterScoped {
return n.SelfLinkPathPrefix + url.QueryEscape(name) + n.SelfLinkPathSuffix, nil
}
builder := strings.Builder{}
builder.Grow(len(n.SelfLinkPathPrefix) + len(namespace) + len(requestInfo.Resource) + len(name) + len(n.SelfLinkPathSuffix) + 8)
builder.WriteString(n.SelfLinkPathPrefix)
builder.WriteString(namespace)
builder.WriteByte('/')
builder.WriteString(requestInfo.Resource)
builder.WriteByte('/')
builder.WriteString(name)
builder.WriteString(n.SelfLinkPathSuffix)
return fastURLPathEncode(builder.String()), nil
}
func (n ContextBasedNaming) GenerateListLink(req *http.Request) (uri string, err error) {
if len(req.URL.RawPath) > 0 {
return req.URL.RawPath, nil
}
return fastURLPathEncode(req.URL.Path), nil
}
func (n ContextBasedNaming) ObjectName(obj runtime.Object) (namespace, name string, err error) { func (n ContextBasedNaming) ObjectName(obj runtime.Object) (namespace, name string, err error) {
name, err = n.SelfLinker.Name(obj) name, err = n.Namer.Name(obj)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
if len(name) == 0 { if len(name) == 0 {
return "", "", errEmptyName return "", "", errEmptyName
} }
namespace, err = n.SelfLinker.Namespace(obj) namespace, err = n.Namer.Namespace(obj)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }

View File

@ -1,179 +0,0 @@
/*
Copyright 2017 The Kubernetes 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 handlers
import (
"math/rand"
"net/url"
"testing"
fuzz "github.com/google/gofuzz"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/endpoints/request"
)
func TestGenerateLink(t *testing.T) {
testCases := []struct {
name string
requestInfo *request.RequestInfo
obj runtime.Object
expect string
expectErr bool
clusterScoped bool
}{
{
name: "obj has more priority than requestInfo",
requestInfo: &request.RequestInfo{
Name: "should-not-use",
Namespace: "should-not-use",
Resource: "pod",
},
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "should-use", Namespace: "should-use"}},
expect: "/api/v1/should-use/pod/should-use",
expectErr: false,
clusterScoped: false,
},
{
name: "hit errEmptyName",
requestInfo: &request.RequestInfo{
Name: "should-use",
Namespace: "should-use",
Resource: "pod",
},
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "should-not-use"}},
expect: "/api/v1/should-use/pod/should-use",
expectErr: false,
clusterScoped: false,
},
{
name: "use namespace of requestInfo if obj namespace is empty",
requestInfo: &request.RequestInfo{
Name: "should-not-use",
Namespace: "should-use",
Resource: "pod",
},
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "should-use"}},
expect: "/api/v1/should-use/pod/should-use",
expectErr: false,
clusterScoped: false,
},
{
name: "hit error",
requestInfo: &request.RequestInfo{
Name: "",
Namespace: "",
Resource: "pod",
},
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{}},
expect: "name must be provided",
expectErr: true,
clusterScoped: false,
},
{
name: "cluster scoped",
requestInfo: &request.RequestInfo{
Name: "only-name",
Namespace: "should-not-use",
Resource: "pod",
},
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{}},
expect: "/api/v1/only-name",
expectErr: false,
clusterScoped: true,
},
}
for _, test := range testCases {
n := ContextBasedNaming{
SelfLinker: meta.NewAccessor(),
SelfLinkPathPrefix: "/api/v1/",
ClusterScoped: test.clusterScoped,
}
uri, err := n.GenerateLink(test.requestInfo, test.obj)
if uri != test.expect && err.Error() != test.expect {
if test.expectErr {
t.Fatalf("%s: unexpected non-error: %v", test.name, err)
} else {
t.Fatalf("%s: expected: %v, but got: %v", test.name, test.expect, uri)
}
}
}
}
func Test_fastURLPathEncode_fuzz(t *testing.T) {
specialCases := []string{"/", "//", ".", "*", "/abc%"}
for _, test := range specialCases {
got := fastURLPathEncode(test)
u := url.URL{Path: test}
expected := u.EscapedPath()
if got != expected {
t.Errorf("%q did not match %q", got, expected)
}
}
f := fuzz.New().Funcs(
func(s *string, c fuzz.Continue) {
*s = randString(c.Rand)
},
)
for i := 0; i < 2000; i++ {
var test string
f.Fuzz(&test)
got := fastURLPathEncode(test)
u := url.URL{Path: test}
expected := u.EscapedPath()
if got != expected {
t.Errorf("%q did not match %q", got, expected)
}
}
}
// Unicode range fuzzer from github.com/google/gofuzz/fuzz.go
type charRange struct {
first, last rune
}
var unicodeRanges = []charRange{
{0x00, 0x255},
{' ', '~'}, // ASCII characters
{'\u00a0', '\u02af'}, // Multi-byte encoded characters
{'\u4e00', '\u9fff'}, // Common CJK (even longer encodings)
}
// randString makes a random string up to 20 characters long. The returned string
// may include a variety of (valid) UTF-8 encodings.
func randString(r *rand.Rand) string {
n := r.Intn(20)
runes := make([]rune, n)
for i := range runes {
runes[i] = unicodeRanges[r.Intn(len(unicodeRanges))].choose(r)
}
return string(runes)
}
// choose returns a random unicode character from the given range, using the
// given randomness source.
func (r *charRange) choose(rand *rand.Rand) rune {
count := int64(r.last - r.first)
return r.first + rune(rand.Int63n(count))
}

View File

@ -236,12 +236,6 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
} }
trace.Step("Object stored in database") trace.Step("Object stored in database")
if err := setObjectSelfLink(ctx, result, req, scope.Namer); err != nil {
scope.err(err, w, req)
return
}
trace.Step("Self-link added")
status := http.StatusOK status := http.StatusOK
if wasCreated { if wasCreated {
status = http.StatusCreated status = http.StatusCreated

View File

@ -59,7 +59,7 @@ func doTransformObject(ctx context.Context, obj runtime.Object, opts interface{}
if _, ok := obj.(*metav1.Status); ok { if _, ok := obj.(*metav1.Status); ok {
return obj, nil return obj, nil
} }
if err := setObjectSelfLink(ctx, obj, req, scope.Namer); err != nil { if err := ensureNonNilItems(obj); err != nil {
return nil, err return nil, err
} }
@ -244,7 +244,6 @@ func asPartialObjectMetadataList(result runtime.Object, groupVersion schema.Grou
if err != nil { if err != nil {
return nil, err return nil, err
} }
list.SelfLink = li.GetSelfLink()
list.ResourceVersion = li.GetResourceVersion() list.ResourceVersion = li.GetResourceVersion()
list.Continue = li.GetContinue() list.Continue = li.GetContinue()
list.RemainingItemCount = li.GetRemainingItemCount() list.RemainingItemCount = li.GetRemainingItemCount()
@ -265,7 +264,6 @@ func asPartialObjectMetadataList(result runtime.Object, groupVersion schema.Grou
if err != nil { if err != nil {
return nil, err return nil, err
} }
list.SelfLink = li.GetSelfLink()
list.ResourceVersion = li.GetResourceVersion() list.ResourceVersion = li.GetResourceVersion()
list.Continue = li.GetContinue() list.Continue = li.GetContinue()
list.RemainingItemCount = li.GetRemainingItemCount() list.RemainingItemCount = li.GetRemainingItemCount()

View File

@ -77,11 +77,6 @@ type mockNamer struct{}
func (*mockNamer) Namespace(_ *http.Request) (string, error) { return "", nil } func (*mockNamer) Namespace(_ *http.Request) (string, error) { return "", nil }
func (*mockNamer) Name(_ *http.Request) (string, string, error) { return "", "", nil } func (*mockNamer) Name(_ *http.Request) (string, string, error) { return "", "", nil }
func (*mockNamer) ObjectName(_ runtime.Object) (string, string, error) { return "", "", nil } func (*mockNamer) ObjectName(_ runtime.Object) (string, string, error) { return "", "", nil }
func (*mockNamer) SetSelfLink(_ runtime.Object, _ string) error { return nil }
func (*mockNamer) GenerateLink(_ *request.RequestInfo, _ runtime.Object) (string, error) {
return "", nil
}
func (*mockNamer) GenerateListLink(_ *http.Request) (string, error) { return "", nil }
func TestCacheableObject(t *testing.T) { func TestCacheableObject(t *testing.T) {
pomGVK := metav1.SchemeGroupVersion.WithKind("PartialObjectMetadata") pomGVK := metav1.SchemeGroupVersion.WithKind("PartialObjectMetadata")
@ -176,7 +171,6 @@ func TestAsPartialObjectMetadataList(t *testing.T) {
var remainingItemCount int64 = 10 var remainingItemCount int64 = 10
pods := &examplev1.PodList{ pods := &examplev1.PodList{
ListMeta: metav1.ListMeta{ ListMeta: metav1.ListMeta{
SelfLink: "/test/link",
ResourceVersion: "10", ResourceVersion: "10",
Continue: "continuetoken", Continue: "continuetoken",
RemainingItemCount: &remainingItemCount, RemainingItemCount: &remainingItemCount,

View File

@ -49,7 +49,6 @@ import (
"k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/registry/rest"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/warning" "k8s.io/apiserver/pkg/warning"
"k8s.io/klog/v2"
) )
const ( const (
@ -260,18 +259,6 @@ func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime
return errors.NewBadRequest(fmt.Sprintf("the object provided is unrecognized (must be of type %s): %v (%s)", objGVK.Kind, baseErr, summary)) return errors.NewBadRequest(fmt.Sprintf("the object provided is unrecognized (must be of type %s): %v (%s)", objGVK.Kind, baseErr, summary))
} }
// setSelfLink sets the self link of an object (or the child items in a list) to the base URL of the request
// plus the path and query generated by the provided linkFunc
func setSelfLink(obj runtime.Object, requestInfo *request.RequestInfo, namer ScopeNamer) error {
// TODO: SelfLink generation should return a full URL?
uri, err := namer.GenerateLink(requestInfo, obj)
if err != nil {
return nil
}
return namer.SetSelfLink(obj, uri)
}
func hasUID(obj runtime.Object) (bool, error) { func hasUID(obj runtime.Object) (bool, error) {
if obj == nil { if obj == nil {
return false, nil return false, nil
@ -369,56 +356,14 @@ func dedupOwnerReferencesAndAddWarning(obj runtime.Object, requestContext contex
} }
} }
// setObjectSelfLink sets the self link of an object as needed. // ensureNonNilItems ensures that for empty lists we don't return <nil> items.
// TODO: remove the need for the namer LinkSetters by requiring objects implement either Object or List func ensureNonNilItems(obj runtime.Object) error {
// interfaces if meta.IsListType(obj) && meta.LenList(obj) == 0 {
func setObjectSelfLink(ctx context.Context, obj runtime.Object, req *http.Request, namer ScopeNamer) error {
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) {
// Ensure that for empty lists we don't return <nil> items.
if meta.IsListType(obj) && meta.LenList(obj) == 0 {
if err := meta.SetList(obj, []runtime.Object{}); err != nil {
return err
}
}
return nil
}
// We only generate list links on objects that implement ListInterface - historically we duck typed this
// check via reflection, but as we move away from reflection we require that you not only carry Items but
// ListMeta into order to be identified as a list.
if !meta.IsListType(obj) {
requestInfo, ok := request.RequestInfoFrom(ctx)
if !ok {
return fmt.Errorf("missing requestInfo")
}
return setSelfLink(obj, requestInfo, namer)
}
uri, err := namer.GenerateListLink(req)
if err != nil {
return err
}
if err := namer.SetSelfLink(obj, uri); err != nil {
klog.V(4).InfoS("Unable to set self link on object", "error", err)
}
requestInfo, ok := request.RequestInfoFrom(ctx)
if !ok {
return fmt.Errorf("missing requestInfo")
}
count := 0
err = meta.EachListItem(obj, func(obj runtime.Object) error {
count++
return setSelfLink(obj, requestInfo, namer)
})
if count == 0 {
if err := meta.SetList(obj, []runtime.Object{}); err != nil { if err := meta.SetList(obj, []runtime.Object{}); err != nil {
return err return err
} }
} }
return nil
return err
} }
func summarizeData(data []byte, maxLength int) string { func summarizeData(data []byte, maxLength int) string {

View File

@ -300,22 +300,6 @@ func (p *testNamer) ObjectName(obj runtime.Object) (namespace, name string, err
return p.namespace, p.name, nil return p.namespace, p.name, nil
} }
// SetSelfLink sets the provided URL onto the object. The method should return nil if the object
// does not support selfLinks.
func (p *testNamer) SetSelfLink(obj runtime.Object, url string) error {
return errors.New("not implemented")
}
// GenerateLink creates a path and query for a given runtime object that represents the canonical path.
func (p *testNamer) GenerateLink(requestInfo *request.RequestInfo, obj runtime.Object) (uri string, err error) {
return "", errors.New("not implemented")
}
// GenerateListLink creates a path and query for a list that represents the canonical path.
func (p *testNamer) GenerateListLink(req *http.Request) (uri string, err error) {
return "", errors.New("not implemented")
}
type patchTestCase struct { type patchTestCase struct {
name string name string

View File

@ -19,7 +19,6 @@ package endpoints
import ( import (
"fmt" "fmt"
"net/http" "net/http"
gpath "path"
"reflect" "reflect"
"sort" "sort"
"strings" "strings"
@ -428,10 +427,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
apiResource.Namespaced = false apiResource.Namespaced = false
apiResource.Kind = resourceKind apiResource.Kind = resourceKind
namer := handlers.ContextBasedNaming{ namer := handlers.ContextBasedNaming{
SelfLinker: a.group.Linker, Namer: a.group.Namer,
ClusterScoped: true, ClusterScoped: true,
SelfLinkPathPrefix: gpath.Join(a.prefix, resource) + "/",
SelfLinkPathSuffix: suffix,
} }
// Handler for standard REST verbs (GET, PUT, POST and DELETE). // Handler for standard REST verbs (GET, PUT, POST and DELETE).
@ -477,10 +474,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
apiResource.Namespaced = true apiResource.Namespaced = true
apiResource.Kind = resourceKind apiResource.Kind = resourceKind
namer := handlers.ContextBasedNaming{ namer := handlers.ContextBasedNaming{
SelfLinker: a.group.Linker, Namer: a.group.Namer,
ClusterScoped: false, ClusterScoped: false,
SelfLinkPathPrefix: gpath.Join(a.prefix, namespaceParamName) + "/",
SelfLinkPathSuffix: itemPathSuffix,
} }
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer, false}, isLister) actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer, false}, isLister)

View File

@ -25,9 +25,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
genericapitesting "k8s.io/apiserver/pkg/endpoints/testing" genericapitesting "k8s.io/apiserver/pkg/endpoints/testing"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/registry/rest"
utilfeature "k8s.io/apiserver/pkg/util/feature"
) )
func TestPatch(t *testing.T) { func TestPatch(t *testing.T) {
@ -43,13 +41,7 @@ func TestPatch(t *testing.T) {
} }
simpleStorage := SimpleRESTStorage{item: *item} simpleStorage := SimpleRESTStorage{item: *item}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{ handler := handle(storage)
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID,
name: ID,
namespace: metav1.NamespaceDefault,
}
handler := handleLinker(storage, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -69,9 +61,6 @@ func TestPatch(t *testing.T) {
if simpleStorage.updated == nil || simpleStorage.updated.Labels["foo"] != "bar" { if simpleStorage.updated == nil || simpleStorage.updated.Labels["foo"] != "bar" {
t.Errorf("Unexpected update value %#v, expected %#v.", simpleStorage.updated, item) t.Errorf("Unexpected update value %#v, expected %#v.", simpleStorage.updated, item)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.RemoveSelfLink) == selfLinker.called {
t.Errorf("unexpected selfLinker.called: %v", selfLinker.called)
}
} }
func TestForbiddenForceOnNonApply(t *testing.T) { func TestForbiddenForceOnNonApply(t *testing.T) {
@ -87,13 +76,7 @@ func TestForbiddenForceOnNonApply(t *testing.T) {
} }
simpleStorage := SimpleRESTStorage{item: *item} simpleStorage := SimpleRESTStorage{item: *item}
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{ handler := handle(storage)
t: t,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID,
name: ID,
namespace: metav1.NamespaceDefault,
}
handler := handleLinker(storage, selfLinker)
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()

View File

@ -135,6 +135,7 @@ const (
// owner: @wojtek-t // owner: @wojtek-t
// alpha: v1.16 // alpha: v1.16
// beta: v1.20 // beta: v1.20
// GA: v1.24
// //
// Deprecates and removes SelfLink from ObjectMeta and ListMeta. // Deprecates and removes SelfLink from ObjectMeta and ListMeta.
RemoveSelfLink featuregate.Feature = "RemoveSelfLink" RemoveSelfLink featuregate.Feature = "RemoveSelfLink"
@ -224,7 +225,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha}, StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha},
WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta}, APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta},
RemoveSelfLink: {Default: true, PreRelease: featuregate.Beta}, RemoveSelfLink: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
SelectorIndex: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, SelectorIndex: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
WarningHeaders: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, WarningHeaders: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, EfficientWatchResumption: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},

View File

@ -1453,13 +1453,12 @@ func (t *Tester) testListTableConversion(obj runtime.Object, assignFn AssignFunc
} }
m.SetContinue("continuetoken") m.SetContinue("continuetoken")
m.SetResourceVersion("11") m.SetResourceVersion("11")
m.SetSelfLink("/list/link")
table, err := t.storage.(rest.TableConvertor).ConvertToTable(ctx, listObj, nil) table, err := t.storage.(rest.TableConvertor).ConvertToTable(ctx, listObj, nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if table.ResourceVersion != "11" || table.SelfLink != "/list/link" || table.Continue != "continuetoken" { if table.ResourceVersion != "11" || table.Continue != "continuetoken" {
t.Errorf("printer lost list meta: %#v", table.ListMeta) t.Errorf("printer lost list meta: %#v", table.ListMeta)
} }
if len(table.Rows) != len(items) { if len(table.Rows) != len(items) {

View File

@ -70,13 +70,11 @@ func (c defaultTableConvertor) ConvertToTable(ctx context.Context, object runtim
} }
if m, err := meta.ListAccessor(object); err == nil { if m, err := meta.ListAccessor(object); err == nil {
table.ResourceVersion = m.GetResourceVersion() table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
table.Continue = m.GetContinue() table.Continue = m.GetContinue()
table.RemainingItemCount = m.GetRemainingItemCount() table.RemainingItemCount = m.GetRemainingItemCount()
} else { } else {
if m, err := meta.CommonAccessor(object); err == nil { if m, err := meta.CommonAccessor(object); err == nil {
table.ResourceVersion = m.GetResourceVersion() table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
} }
} }
if opt, ok := tableOptions.(*metav1.TableOptions); !ok || !opt.NoHeaders { if opt, ok := tableOptions.(*metav1.TableOptions); !ok || !opt.NoHeaders {

View File

@ -676,7 +676,7 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
UnsafeConvertor: runtime.UnsafeObjectConvertor(apiGroupInfo.Scheme), UnsafeConvertor: runtime.UnsafeObjectConvertor(apiGroupInfo.Scheme),
Defaulter: apiGroupInfo.Scheme, Defaulter: apiGroupInfo.Scheme,
Typer: apiGroupInfo.Scheme, Typer: apiGroupInfo.Scheme,
Linker: runtime.SelfLinker(meta.NewAccessor()), Namer: runtime.Namer(meta.NewAccessor()),
EquivalentResourceRegistry: s.EquivalentResourceRegistry, EquivalentResourceRegistry: s.EquivalentResourceRegistry,

View File

@ -60,8 +60,7 @@ type serializationsCache map[runtime.Identifier]*serializationResult
// so that each of those is computed exactly once. // so that each of those is computed exactly once.
// //
// cachingObject implements the metav1.Object interface (accessors for // cachingObject implements the metav1.Object interface (accessors for
// all metadata fields). However, setters for all fields except from // all metadata fields).
// SelfLink (which is set lately in the path) are ignored.
type cachingObject struct { type cachingObject struct {
lock sync.RWMutex lock sync.RWMutex

View File

@ -83,36 +83,39 @@ func TestCachingObject(t *testing.T) {
} }
} }
func TestSelfLink(t *testing.T) { func TestCachingObjectFieldAccessors(t *testing.T) {
object, err := newCachingObject(&v1.Pod{}) object, err := newCachingObject(&v1.Pod{})
if err != nil { if err != nil {
t.Fatalf("couldn't create cachingObject: %v", err) t.Fatalf("couldn't create cachingObject: %v", err)
} }
selfLink := "selfLink"
object.SetSelfLink(selfLink)
encodeSelfLink := func(obj runtime.Object, w io.Writer) error { // Given accessors for all fields implement the same logic,
// we are choosing an arbitrary one to test.
clusterName := "clusterName"
object.SetClusterName(clusterName)
encodeClusterName := func(obj runtime.Object, w io.Writer) error {
accessor, err := meta.Accessor(obj) accessor, err := meta.Accessor(obj)
if err != nil { if err != nil {
t.Fatalf("failed to get accessor for %#v: %v", obj, err) t.Fatalf("failed to get accessor for %#v: %v", obj, err)
} }
_, err = w.Write([]byte(accessor.GetSelfLink())) _, err = w.Write([]byte(accessor.GetClusterName()))
return err return err
} }
buffer := bytes.NewBuffer(nil) buffer := bytes.NewBuffer(nil)
if err := object.CacheEncode("", encodeSelfLink, buffer); err != nil { if err := object.CacheEncode("", encodeClusterName, buffer); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if a, e := buffer.String(), selfLink; a != e { if a, e := buffer.String(), clusterName; a != e {
t.Errorf("unexpected serialization: %s, expected: %s", a, e) t.Errorf("unexpected serialization: %s, expected: %s", a, e)
} }
// GetObject should also set selfLink. // GetObject should also set clusterName.
buffer.Reset() buffer.Reset()
if err := encodeSelfLink(object.GetObject(), buffer); err != nil { if err := encodeClusterName(object.GetObject(), buffer); err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if a, e := buffer.String(), selfLink; a != e { if a, e := buffer.String(), clusterName; a != e {
t.Errorf("unexpected serialization: %s, expected: %s", a, e) t.Errorf("unexpected serialization: %s, expected: %s", a, e)
} }
} }
@ -136,7 +139,7 @@ func TestCachingObjectRaces(t *testing.T) {
for i := 0; i < numWorkers; i++ { for i := 0; i < numWorkers; i++ {
go func() { go func() {
defer wg.Done() defer wg.Done()
object.SetSelfLink("selfLink") object.SetClusterName("clusterName")
buffer := bytes.NewBuffer(nil) buffer := bytes.NewBuffer(nil)
for _, encoder := range encoders { for _, encoder := range encoders {
buffer.Reset() buffer.Reset()
@ -152,8 +155,8 @@ func TestCachingObjectRaces(t *testing.T) {
t.Errorf("failed to get accessor: %v", err) t.Errorf("failed to get accessor: %v", err)
return return
} }
if selfLink := accessor.GetSelfLink(); selfLink != "selfLink" { if clusterName := accessor.GetClusterName(); clusterName != "clusterName" {
t.Errorf("unexpected selfLink: %s", selfLink) t.Errorf("unexpected clusterName: %s", clusterName)
} }
}() }()
} }

View File

@ -60,7 +60,7 @@ func (a APIObjectVersioner) UpdateList(obj runtime.Object, resourceVersion uint6
return nil return nil
} }
// PrepareObjectForStorage clears resource version and self link prior to writing to etcd. // PrepareObjectForStorage clears resourceVersion and selfLink prior to writing to etcd.
func (a APIObjectVersioner) PrepareObjectForStorage(obj runtime.Object) error { func (a APIObjectVersioner) PrepareObjectForStorage(obj runtime.Object) error {
accessor, err := meta.Accessor(obj) accessor, err := meta.Accessor(obj)
if err != nil { if err != nil {

View File

@ -135,7 +135,7 @@ func TestCreate(t *testing.T) {
t.Errorf("output should have non-empty resource version") t.Errorf("output should have non-empty resource version")
} }
if out.SelfLink != "" { if out.SelfLink != "" {
t.Errorf("output should have empty self link") t.Errorf("output should have empty selfLink")
} }
checkStorageInvariants(ctx, t, etcdClient, store, key) checkStorageInvariants(ctx, t, etcdClient, store, key)
@ -158,7 +158,7 @@ func checkStorageInvariants(ctx context.Context, t *testing.T, etcdClient *clien
t.Errorf("stored object should have empty resource version") t.Errorf("stored object should have empty resource version")
} }
if obj.SelfLink != "" { if obj.SelfLink != "" {
t.Errorf("stored output should have empty self link") t.Errorf("stored output should have empty selfLink")
} }
} }
@ -686,7 +686,7 @@ func TestGuaranteedUpdate(t *testing.T) {
expectNotFoundErr: false, expectNotFoundErr: false,
expectInvalidObjErr: false, expectInvalidObjErr: false,
expectNoUpdate: true, expectNoUpdate: true,
}, { // GuaranteedUpdate with same data AND a self link }, { // GuaranteedUpdate with same data AND a selfLink
key: key, key: key,
ignoreNotFound: false, ignoreNotFound: false,
precondition: nil, precondition: nil,
@ -768,7 +768,7 @@ func TestGuaranteedUpdate(t *testing.T) {
t.Errorf("#%d: pod name want=%s, get=%s", i, name, out.ObjectMeta.Name) t.Errorf("#%d: pod name want=%s, get=%s", i, name, out.ObjectMeta.Name)
} }
if out.SelfLink != "" { if out.SelfLink != "" {
t.Errorf("#%d: selflink should not be set", i) t.Errorf("#%d: selfLink should not be set", i)
} }
// verify that kv pair is not empty after set and that the underlying data matches expectations // verify that kv pair is not empty after set and that the underlying data matches expectations
@ -2359,7 +2359,7 @@ func TestLeaseMaxObjectCount(t *testing.T) {
}) })
ctx := context.Background() ctx := context.Background()
obj := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", SelfLink: "testlink"}} obj := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
out := &example.Pod{} out := &example.Pod{}
testCases := []struct { testCases := []struct {

View File

@ -123,15 +123,6 @@ func (b *MutatingWebhookConfigurationApplyConfiguration) WithNamespace(value str
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *MutatingWebhookConfigurationApplyConfiguration) WithSelfLink(value string) *MutatingWebhookConfigurationApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -123,15 +123,6 @@ func (b *ValidatingWebhookConfigurationApplyConfiguration) WithNamespace(value s
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ValidatingWebhookConfigurationApplyConfiguration) WithSelfLink(value string) *ValidatingWebhookConfigurationApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -123,15 +123,6 @@ func (b *MutatingWebhookConfigurationApplyConfiguration) WithNamespace(value str
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *MutatingWebhookConfigurationApplyConfiguration) WithSelfLink(value string) *MutatingWebhookConfigurationApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -123,15 +123,6 @@ func (b *ValidatingWebhookConfigurationApplyConfiguration) WithNamespace(value s
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ValidatingWebhookConfigurationApplyConfiguration) WithSelfLink(value string) *ValidatingWebhookConfigurationApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -124,15 +124,6 @@ func (b *StorageVersionApplyConfiguration) WithNamespace(value string) *StorageV
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *StorageVersionApplyConfiguration) WithSelfLink(value string) *StorageVersionApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -127,15 +127,6 @@ func (b *ControllerRevisionApplyConfiguration) WithNamespace(value string) *Cont
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ControllerRevisionApplyConfiguration) WithSelfLink(value string) *ControllerRevisionApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *DaemonSetApplyConfiguration) WithNamespace(value string) *DaemonSetAppl
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *DaemonSetApplyConfiguration) WithSelfLink(value string) *DaemonSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *DeploymentApplyConfiguration) WithNamespace(value string) *DeploymentAp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *DeploymentApplyConfiguration) WithSelfLink(value string) *DeploymentApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *ReplicaSetApplyConfiguration) WithNamespace(value string) *ReplicaSetAp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ReplicaSetApplyConfiguration) WithSelfLink(value string) *ReplicaSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *StatefulSetApplyConfiguration) WithNamespace(value string) *StatefulSet
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *StatefulSetApplyConfiguration) WithSelfLink(value string) *StatefulSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -127,15 +127,6 @@ func (b *ControllerRevisionApplyConfiguration) WithNamespace(value string) *Cont
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ControllerRevisionApplyConfiguration) WithSelfLink(value string) *ControllerRevisionApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *DeploymentApplyConfiguration) WithNamespace(value string) *DeploymentAp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *DeploymentApplyConfiguration) WithSelfLink(value string) *DeploymentApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *StatefulSetApplyConfiguration) WithNamespace(value string) *StatefulSet
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *StatefulSetApplyConfiguration) WithSelfLink(value string) *StatefulSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -127,15 +127,6 @@ func (b *ControllerRevisionApplyConfiguration) WithNamespace(value string) *Cont
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ControllerRevisionApplyConfiguration) WithSelfLink(value string) *ControllerRevisionApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *DaemonSetApplyConfiguration) WithNamespace(value string) *DaemonSetAppl
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *DaemonSetApplyConfiguration) WithSelfLink(value string) *DaemonSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *DeploymentApplyConfiguration) WithNamespace(value string) *DeploymentAp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *DeploymentApplyConfiguration) WithSelfLink(value string) *DeploymentApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *ReplicaSetApplyConfiguration) WithNamespace(value string) *ReplicaSetAp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ReplicaSetApplyConfiguration) WithSelfLink(value string) *ReplicaSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -86,15 +86,6 @@ func (b *ScaleApplyConfiguration) WithNamespace(value string) *ScaleApplyConfigu
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ScaleApplyConfiguration) WithSelfLink(value string) *ScaleApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *StatefulSetApplyConfiguration) WithNamespace(value string) *StatefulSet
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *StatefulSetApplyConfiguration) WithSelfLink(value string) *StatefulSetApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string)
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *HorizontalPodAutoscalerApplyConfiguration) WithSelfLink(value string) *HorizontalPodAutoscalerApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -85,15 +85,6 @@ func (b *ScaleApplyConfiguration) WithNamespace(value string) *ScaleApplyConfigu
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *ScaleApplyConfiguration) WithSelfLink(value string) *ScaleApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string)
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *HorizontalPodAutoscalerApplyConfiguration) WithSelfLink(value string) *HorizontalPodAutoscalerApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string)
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *HorizontalPodAutoscalerApplyConfiguration) WithSelfLink(value string) *HorizontalPodAutoscalerApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *HorizontalPodAutoscalerApplyConfiguration) WithNamespace(value string)
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *HorizontalPodAutoscalerApplyConfiguration) WithSelfLink(value string) *HorizontalPodAutoscalerApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *CronJobApplyConfiguration) WithNamespace(value string) *CronJobApplyCon
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *CronJobApplyConfiguration) WithSelfLink(value string) *CronJobApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *JobApplyConfiguration) WithNamespace(value string) *JobApplyConfigurati
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *JobApplyConfiguration) WithSelfLink(value string) *JobApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -64,15 +64,6 @@ func (b *JobTemplateSpecApplyConfiguration) WithNamespace(value string) *JobTemp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *JobTemplateSpecApplyConfiguration) WithSelfLink(value string) *JobTemplateSpecApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -126,15 +126,6 @@ func (b *CronJobApplyConfiguration) WithNamespace(value string) *CronJobApplyCon
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *CronJobApplyConfiguration) WithSelfLink(value string) *CronJobApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -65,15 +65,6 @@ func (b *JobTemplateSpecApplyConfiguration) WithNamespace(value string) *JobTemp
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *JobTemplateSpecApplyConfiguration) WithSelfLink(value string) *JobTemplateSpecApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -124,15 +124,6 @@ func (b *CertificateSigningRequestApplyConfiguration) WithNamespace(value string
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *CertificateSigningRequestApplyConfiguration) WithSelfLink(value string) *CertificateSigningRequestApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

View File

@ -124,15 +124,6 @@ func (b *CertificateSigningRequestApplyConfiguration) WithNamespace(value string
return b return b
} }
// WithSelfLink sets the SelfLink field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the SelfLink field is set to the value of the last call.
func (b *CertificateSigningRequestApplyConfiguration) WithSelfLink(value string) *CertificateSigningRequestApplyConfiguration {
b.ensureObjectMetaApplyConfigurationExists()
b.SelfLink = &value
return b
}
// WithUID sets the UID field in the declarative configuration to the given value // WithUID sets the UID field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations. // and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the UID field is set to the value of the last call. // If called multiple times, the UID field is set to the value of the last call.

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