Skip to content

Commit 16d221e

Browse files
committed
Promote GMSA to GA
Signed-off-by: Deep Debroy <[email protected]>
1 parent c73532c commit 16d221e

File tree

10 files changed

+7
-288
lines changed

10 files changed

+7
-288
lines changed

api/openapi-spec/swagger.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/pod/util.go

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,6 @@ func dropDisabledFields(
389389

390390
dropDisabledRunAsGroupField(podSpec, oldPodSpec)
391391

392-
dropDisabledGMSAFields(podSpec, oldPodSpec)
393-
394392
if !utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) && !runtimeClassInUse(oldPodSpec) {
395393
// Set RuntimeClassName to nil only if feature is disabled and it is not used
396394
podSpec.RuntimeClassName = nil
@@ -434,39 +432,6 @@ func dropDisabledRunAsGroupField(podSpec, oldPodSpec *api.PodSpec) {
434432
}
435433
}
436434

437-
// dropDisabledGMSAFields removes disabled fields related to Windows GMSA
438-
// from the given PodSpec.
439-
func dropDisabledGMSAFields(podSpec, oldPodSpec *api.PodSpec) {
440-
if utilfeature.DefaultFeatureGate.Enabled(features.WindowsGMSA) ||
441-
gMSAFieldsInUse(oldPodSpec) {
442-
return
443-
}
444-
445-
if podSpec.SecurityContext != nil {
446-
dropDisabledGMSAFieldsFromWindowsSecurityOptions(podSpec.SecurityContext.WindowsOptions)
447-
}
448-
dropDisabledGMSAFieldsFromContainers(podSpec.Containers)
449-
dropDisabledGMSAFieldsFromContainers(podSpec.InitContainers)
450-
}
451-
452-
// dropDisabledGMSAFieldsFromWindowsSecurityOptions removes disabled fields
453-
// related to Windows GMSA from the given WindowsSecurityContextOptions.
454-
func dropDisabledGMSAFieldsFromWindowsSecurityOptions(windowsOptions *api.WindowsSecurityContextOptions) {
455-
if windowsOptions != nil {
456-
windowsOptions.GMSACredentialSpecName = nil
457-
windowsOptions.GMSACredentialSpec = nil
458-
}
459-
}
460-
461-
// dropDisabledGMSAFieldsFromContainers removes disabled fields
462-
func dropDisabledGMSAFieldsFromContainers(containers []api.Container) {
463-
for i := range containers {
464-
if containers[i].SecurityContext != nil {
465-
dropDisabledGMSAFieldsFromWindowsSecurityOptions(containers[i].SecurityContext.WindowsOptions)
466-
}
467-
}
468-
}
469-
470435
// dropDisabledProcMountField removes disabled fields from PodSpec related
471436
// to ProcMount only if it is not already used by the old spec
472437
func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) {
@@ -686,44 +651,6 @@ func runAsGroupInUse(podSpec *api.PodSpec) bool {
686651
return inUse
687652
}
688653

689-
// gMSAFieldsInUse returns true if the pod spec is non-nil and has one of any
690-
// SecurityContext's GMSACredentialSpecName or GMSACredentialSpec fields set.
691-
func gMSAFieldsInUse(podSpec *api.PodSpec) bool {
692-
if podSpec == nil {
693-
return false
694-
}
695-
696-
if podSpec.SecurityContext != nil && gMSAFieldsInUseInWindowsSecurityOptions(podSpec.SecurityContext.WindowsOptions) {
697-
return true
698-
}
699-
700-
return gMSAFieldsInUseInAnyContainer(podSpec.Containers) ||
701-
gMSAFieldsInUseInAnyContainer(podSpec.InitContainers)
702-
}
703-
704-
// gMSAFieldsInUseInWindowsSecurityOptions returns true if the given WindowsSecurityContextOptions is
705-
// non-nil and one of its GMSACredentialSpecName or GMSACredentialSpec fields is set.
706-
func gMSAFieldsInUseInWindowsSecurityOptions(windowsOptions *api.WindowsSecurityContextOptions) bool {
707-
if windowsOptions == nil {
708-
return false
709-
}
710-
711-
return windowsOptions.GMSACredentialSpecName != nil ||
712-
windowsOptions.GMSACredentialSpec != nil
713-
}
714-
715-
// gMSAFieldsInUseInAnyContainer returns true if any of the given Containers has its
716-
// SecurityContext's GMSACredentialSpecName or GMSACredentialSpec fields set.
717-
func gMSAFieldsInUseInAnyContainer(containers []api.Container) bool {
718-
for _, container := range containers {
719-
if container.SecurityContext != nil && gMSAFieldsInUseInWindowsSecurityOptions(container.SecurityContext.WindowsOptions) {
720-
return true
721-
}
722-
}
723-
724-
return false
725-
}
726-
727654
// subpathExprInUse returns true if the pod spec is non-nil and has a volume mount that makes use of the subPathExpr feature
728655
func subpathExprInUse(podSpec *api.PodSpec) bool {
729656
if podSpec == nil {

pkg/api/pod/util_test.go

Lines changed: 0 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,208 +1315,6 @@ func TestDropRunAsGroup(t *testing.T) {
13151315
}
13161316
}
13171317

1318-
func TestDropGMSAFields(t *testing.T) {
1319-
defaultContainerSecurityContextFactory := func() *api.SecurityContext {
1320-
defaultProcMount := api.DefaultProcMount
1321-
return &api.SecurityContext{ProcMount: &defaultProcMount}
1322-
}
1323-
podWithoutWindowsOptionsFactory := func() *api.Pod {
1324-
return &api.Pod{
1325-
Spec: api.PodSpec{
1326-
RestartPolicy: api.RestartPolicyNever,
1327-
SecurityContext: &api.PodSecurityContext{},
1328-
Containers: []api.Container{{Name: "container1", Image: "testimage", SecurityContext: defaultContainerSecurityContextFactory()}},
1329-
InitContainers: []api.Container{{Name: "initContainer1", Image: "testimage", SecurityContext: defaultContainerSecurityContextFactory()}},
1330-
},
1331-
}
1332-
}
1333-
1334-
type podFactoryInfo struct {
1335-
description string
1336-
hasGMSAField bool
1337-
// this factory should generate the input pod whose spec will be fed to dropDisabledFields
1338-
podFactory func() *api.Pod
1339-
// this factory should generate the expected pod after the GMSA fields have been dropped
1340-
// we can't just use podWithoutWindowsOptionsFactory as is for this, since in some cases
1341-
// we'll be left with a WindowsSecurityContextOptions struct with no GMSA field set, as opposed
1342-
// to a nil pointer in the pod generated by podWithoutWindowsOptionsFactory
1343-
// if this field is not set, it will default to the podFactory
1344-
strippedPodFactory func() *api.Pod
1345-
}
1346-
podFactoryInfos := []podFactoryInfo{
1347-
{
1348-
description: "does not have any GMSA field set",
1349-
hasGMSAField: false,
1350-
podFactory: podWithoutWindowsOptionsFactory,
1351-
},
1352-
{
1353-
description: "has a pod-level WindowsSecurityContextOptions struct with no GMSA field set",
1354-
hasGMSAField: false,
1355-
podFactory: func() *api.Pod {
1356-
pod := podWithoutWindowsOptionsFactory()
1357-
pod.Spec.SecurityContext.WindowsOptions = &api.WindowsSecurityContextOptions{}
1358-
return pod
1359-
},
1360-
},
1361-
{
1362-
description: "has a WindowsSecurityContextOptions struct with no GMSA field set on a container",
1363-
hasGMSAField: false,
1364-
podFactory: func() *api.Pod {
1365-
pod := podWithoutWindowsOptionsFactory()
1366-
pod.Spec.Containers[0].SecurityContext.WindowsOptions = &api.WindowsSecurityContextOptions{}
1367-
return pod
1368-
},
1369-
},
1370-
{
1371-
description: "has a WindowsSecurityContextOptions struct with no GMSA field set on an init container",
1372-
hasGMSAField: false,
1373-
podFactory: func() *api.Pod {
1374-
pod := podWithoutWindowsOptionsFactory()
1375-
pod.Spec.InitContainers[0].SecurityContext.WindowsOptions = &api.WindowsSecurityContextOptions{}
1376-
return pod
1377-
},
1378-
},
1379-
{
1380-
description: "is nil",
1381-
hasGMSAField: false,
1382-
podFactory: func() *api.Pod { return nil },
1383-
},
1384-
}
1385-
1386-
toPtr := func(s string) *string {
1387-
return &s
1388-
}
1389-
addGMSACredentialSpecName := func(windowsOptions *api.WindowsSecurityContextOptions) {
1390-
windowsOptions.GMSACredentialSpecName = toPtr("dummy-gmsa-cred-spec-name")
1391-
}
1392-
addGMSACredentialSpec := func(windowsOptions *api.WindowsSecurityContextOptions) {
1393-
windowsOptions.GMSACredentialSpec = toPtr("dummy-gmsa-cred-spec-contents")
1394-
}
1395-
addBothGMSAFields := func(windowsOptions *api.WindowsSecurityContextOptions) {
1396-
addGMSACredentialSpecName(windowsOptions)
1397-
addGMSACredentialSpec(windowsOptions)
1398-
}
1399-
1400-
for fieldName, windowsOptionsTransformingFunc := range map[string]func(*api.WindowsSecurityContextOptions){
1401-
"GMSACredentialSpecName field": addGMSACredentialSpecName,
1402-
"GMSACredentialSpec field": addGMSACredentialSpec,
1403-
"both GMSA fields": addBothGMSAFields,
1404-
} {
1405-
// yes, these variables are indeed needed for the closure to work
1406-
// properly, please do NOT remove them
1407-
name := fieldName
1408-
transformingFunc := windowsOptionsTransformingFunc
1409-
1410-
windowsOptionsWithGMSAFieldFactory := func() *api.WindowsSecurityContextOptions {
1411-
windowsOptions := &api.WindowsSecurityContextOptions{}
1412-
transformingFunc(windowsOptions)
1413-
return windowsOptions
1414-
}
1415-
1416-
podFactoryInfos = append(podFactoryInfos,
1417-
podFactoryInfo{
1418-
description: fmt.Sprintf("has %s in Pod", name),
1419-
hasGMSAField: true,
1420-
podFactory: func() *api.Pod {
1421-
pod := podWithoutWindowsOptionsFactory()
1422-
pod.Spec.SecurityContext.WindowsOptions = windowsOptionsWithGMSAFieldFactory()
1423-
return pod
1424-
},
1425-
strippedPodFactory: func() *api.Pod {
1426-
pod := podWithoutWindowsOptionsFactory()
1427-
pod.Spec.SecurityContext.WindowsOptions = &api.WindowsSecurityContextOptions{}
1428-
return pod
1429-
},
1430-
},
1431-
podFactoryInfo{
1432-
description: fmt.Sprintf("has %s in Container", name),
1433-
hasGMSAField: true,
1434-
podFactory: func() *api.Pod {
1435-
pod := podWithoutWindowsOptionsFactory()
1436-
pod.Spec.Containers[0].SecurityContext.WindowsOptions = windowsOptionsWithGMSAFieldFactory()
1437-
return pod
1438-
},
1439-
strippedPodFactory: func() *api.Pod {
1440-
pod := podWithoutWindowsOptionsFactory()
1441-
pod.Spec.Containers[0].SecurityContext.WindowsOptions = &api.WindowsSecurityContextOptions{}
1442-
return pod
1443-
},
1444-
},
1445-
podFactoryInfo{
1446-
description: fmt.Sprintf("has %s in InitContainer", name),
1447-
hasGMSAField: true,
1448-
podFactory: func() *api.Pod {
1449-
pod := podWithoutWindowsOptionsFactory()
1450-
pod.Spec.InitContainers[0].SecurityContext.WindowsOptions = windowsOptionsWithGMSAFieldFactory()
1451-
return pod
1452-
},
1453-
strippedPodFactory: func() *api.Pod {
1454-
pod := podWithoutWindowsOptionsFactory()
1455-
pod.Spec.InitContainers[0].SecurityContext.WindowsOptions = &api.WindowsSecurityContextOptions{}
1456-
return pod
1457-
},
1458-
})
1459-
}
1460-
1461-
for _, enabled := range []bool{true, false} {
1462-
for _, oldPodFactoryInfo := range podFactoryInfos {
1463-
for _, newPodFactoryInfo := range podFactoryInfos {
1464-
newPodHasGMSAField, newPod := newPodFactoryInfo.hasGMSAField, newPodFactoryInfo.podFactory()
1465-
if newPod == nil {
1466-
continue
1467-
}
1468-
oldPodHasGMSAField, oldPod := oldPodFactoryInfo.hasGMSAField, oldPodFactoryInfo.podFactory()
1469-
1470-
t.Run(fmt.Sprintf("feature enabled=%v, old pod %s, new pod %s", enabled, oldPodFactoryInfo.description, newPodFactoryInfo.description), func(t *testing.T) {
1471-
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WindowsGMSA, enabled)()
1472-
1473-
var oldPodSpec *api.PodSpec
1474-
if oldPod != nil {
1475-
oldPodSpec = &oldPod.Spec
1476-
}
1477-
dropDisabledFields(&newPod.Spec, nil, oldPodSpec, nil)
1478-
1479-
// old pod should never be changed
1480-
if !reflect.DeepEqual(oldPod, oldPodFactoryInfo.podFactory()) {
1481-
t.Errorf("old pod changed: %v", diff.ObjectReflectDiff(oldPod, oldPodFactoryInfo.podFactory()))
1482-
}
1483-
1484-
switch {
1485-
case enabled || oldPodHasGMSAField:
1486-
// new pod should not be changed if the feature is enabled, or if the old pod had any GMSA field set
1487-
if !reflect.DeepEqual(newPod, newPodFactoryInfo.podFactory()) {
1488-
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodFactoryInfo.podFactory()))
1489-
}
1490-
case newPodHasGMSAField:
1491-
// new pod should be changed
1492-
if reflect.DeepEqual(newPod, newPodFactoryInfo.podFactory()) {
1493-
t.Errorf("%v", oldPod)
1494-
t.Errorf("%v", newPod)
1495-
t.Errorf("new pod was not changed")
1496-
}
1497-
// new pod should not have any GMSA field set
1498-
var expectedStrippedPod *api.Pod
1499-
if newPodFactoryInfo.strippedPodFactory == nil {
1500-
expectedStrippedPod = newPodFactoryInfo.podFactory()
1501-
} else {
1502-
expectedStrippedPod = newPodFactoryInfo.strippedPodFactory()
1503-
}
1504-
1505-
if !reflect.DeepEqual(newPod, expectedStrippedPod) {
1506-
t.Errorf("new pod had some GMSA field set: %v", diff.ObjectReflectDiff(newPod, expectedStrippedPod))
1507-
}
1508-
default:
1509-
// new pod should not need to be changed
1510-
if !reflect.DeepEqual(newPod, newPodFactoryInfo.podFactory()) {
1511-
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodFactoryInfo.podFactory()))
1512-
}
1513-
}
1514-
})
1515-
}
1516-
}
1517-
}
1518-
}
1519-
15201318
func TestDropPodSysctls(t *testing.T) {
15211319
podWithSysctls := func() *api.Pod {
15221320
return &api.Pod{

pkg/apis/core/types.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5096,14 +5096,12 @@ type SELinuxOptions struct {
50965096
// WindowsSecurityContextOptions contain Windows-specific options and credentials.
50975097
type WindowsSecurityContextOptions struct {
50985098
// GMSACredentialSpecName is the name of the GMSA credential spec to use.
5099-
// This field is alpha-level and is only honored by servers that enable the WindowsGMSA feature flag.
51005099
// +optional
51015100
GMSACredentialSpecName *string
51025101

51035102
// GMSACredentialSpec is where the GMSA admission webhook
51045103
// (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the
51055104
// GMSA credential spec named by the GMSACredentialSpecName field.
5106-
// This field is alpha-level and is only honored by servers that enable the WindowsGMSA feature flag.
51075105
// +optional
51085106
GMSACredentialSpec *string
51095107

pkg/features/kube_features.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
623623
ProcMountType: {Default: false, PreRelease: featuregate.Alpha},
624624
TTLAfterFinished: {Default: false, PreRelease: featuregate.Alpha},
625625
KubeletPodResources: {Default: true, PreRelease: featuregate.Beta},
626-
WindowsGMSA: {Default: true, PreRelease: featuregate.Beta},
626+
WindowsGMSA: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.20
627627
WindowsRunAsUserName: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.20
628628
ServiceLoadBalancerFinalizer: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
629629
LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha},

staging/src/k8s.io/api/core/v1/generated.proto

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/api/core/v1/types.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5843,14 +5843,12 @@ type SELinuxOptions struct {
58435843
// WindowsSecurityContextOptions contain Windows-specific options and credentials.
58445844
type WindowsSecurityContextOptions struct {
58455845
// GMSACredentialSpecName is the name of the GMSA credential spec to use.
5846-
// This field is alpha-level and is only honored by servers that enable the WindowsGMSA feature flag.
58475846
// +optional
58485847
GMSACredentialSpecName *string `json:"gmsaCredentialSpecName,omitempty" protobuf:"bytes,1,opt,name=gmsaCredentialSpecName"`
58495848

58505849
// GMSACredentialSpec is where the GMSA admission webhook
58515850
// (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the
58525851
// GMSA credential spec named by the GMSACredentialSpecName field.
5853-
// This field is alpha-level and is only honored by servers that enable the WindowsGMSA feature flag.
58545852
// +optional
58555853
GMSACredentialSpec *string `json:"gmsaCredentialSpec,omitempty" protobuf:"bytes,2,opt,name=gmsaCredentialSpec"`
58565854

staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/e2e/windows/gmsa_full.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const (
7979
gmsaWebhookDeployScriptURL = "https://raw.githubusercontent.com/kubernetes-sigs/windows-gmsa/master/admission-webhook/deploy/deploy-gmsa-webhook.sh"
8080
)
8181

82-
var _ = SIGDescribe("[Feature:Windows] [Feature:WindowsGMSA] GMSA Full [Slow]", func() {
82+
var _ = SIGDescribe("[Feature:Windows] GMSA Full [Slow]", func() {
8383
f := framework.NewDefaultFramework("gmsa-full-test-windows")
8484

8585
ginkgo.Describe("GMSA support", func() {

test/e2e/windows/gmsa_kubelet.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import (
3535
"github.com/onsi/gomega"
3636
)
3737

38-
var _ = SIGDescribe("[Feature:Windows] [Feature:WindowsGMSA] GMSA Kubelet [Slow]", func() {
38+
var _ = SIGDescribe("[Feature:Windows] GMSA Kubelet [Slow]", func() {
3939
f := framework.NewDefaultFramework("gmsa-kubelet-test-windows")
4040

4141
ginkgo.Describe("kubelet GMSA support", func() {

0 commit comments

Comments
 (0)