Validate transforms expressions in federation_domain_watcher.go

This commit is contained in:
Ryan Richard 2023-07-14 12:06:20 -07:00
parent 013030041a
commit 52925a2a46
3 changed files with 237 additions and 95 deletions

View File

@ -44,6 +44,7 @@ const (
typeIdentityProvidersAPIGroupSuffixValid = "IdentityProvidersObjectRefAPIGroupSuffixValid"
typeIdentityProvidersObjectRefKindValid = "IdentityProvidersObjectRefKindValid"
typeTransformsConstantsNamesUnique = "TransformsConstantsNamesUnique"
typeTransformsExpressionsValid = "TransformsExpressionsValid"
reasonSuccess = "Success"
reasonNotReady = "NotReady"
@ -59,6 +60,7 @@ const (
reasonAPIGroupNameUnrecognized = "APIGroupUnrecognized"
reasonKindUnrecognized = "KindUnrecognized"
reasonDuplicateConstantsNames = "DuplicateConstantsNames"
reasonInvalidTransformsExpressions = "InvalidTransformsExpressions"
kindLDAPIdentityProvider = "LDAPIdentityProvider"
kindOIDCIdentityProvider = "OIDCIdentityProvider"
@ -162,7 +164,7 @@ func (c *federationDomainWatcherController) Sync(ctx controllerlib.Context) erro
}
// Process each FederationDomain to validate its spec and to turn it into a FederationDomainIssuer.
federationDomainIssuers, fdToConditionsMap, err := c.processAllFederationDomains(federationDomains)
federationDomainIssuers, fdToConditionsMap, err := c.processAllFederationDomains(ctx.Context, federationDomains)
if err != nil {
return err
}
@ -185,6 +187,7 @@ func (c *federationDomainWatcherController) Sync(ctx controllerlib.Context) erro
}
func (c *federationDomainWatcherController) processAllFederationDomains(
ctx context.Context,
federationDomains []*configv1alpha1.FederationDomain,
) ([]*federationdomainproviders.FederationDomainIssuer, map[*configv1alpha1.FederationDomain][]*configv1alpha1.Condition, error) {
federationDomainIssuers := make([]*federationdomainproviders.FederationDomainIssuer, 0)
@ -196,7 +199,7 @@ func (c *federationDomainWatcherController) processAllFederationDomains(
conditions = crossDomainConfigValidator.Validate(federationDomain, conditions)
federationDomainIssuer, conditions, err := c.makeFederationDomainIssuer(federationDomain, conditions)
federationDomainIssuer, conditions, err := c.makeFederationDomainIssuer(ctx, federationDomain, conditions)
if err != nil {
return nil, nil, err
}
@ -216,6 +219,7 @@ func (c *federationDomainWatcherController) processAllFederationDomains(
}
func (c *federationDomainWatcherController) makeFederationDomainIssuer(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
conditions []*configv1alpha1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*configv1alpha1.Condition, error) {
@ -230,7 +234,7 @@ func (c *federationDomainWatcherController) makeFederationDomainIssuer(
return nil, nil, err
}
} else {
federationDomainIssuer, conditions, err = c.makeFederationDomainIssuerWithExplicitIDPs(federationDomain, conditions)
federationDomainIssuer, conditions, err = c.makeFederationDomainIssuerWithExplicitIDPs(ctx, federationDomain, conditions)
if err != nil {
return nil, nil, err
}
@ -313,19 +317,23 @@ func (c *federationDomainWatcherController) makeLegacyFederationDomainIssuer(
})
}
// This is the constructor for the backwards compatibility mode.
// This is the constructor for the legacy backwards compatibility mode.
federationDomainIssuer, err := federationdomainproviders.NewFederationDomainIssuerWithDefaultIDP(federationDomain.Spec.Issuer, defaultFederationDomainIdentityProvider)
conditions = appendIssuerURLValidCondition(err, conditions)
// These conditions can only have errors when the list of IDPs is explicitly configured,
// and in this case there are no IDPs explicitly configured, so set these conditions all to have no errors.
conditions = appendIdentityProviderDuplicateDisplayNamesCondition(sets.Set[string]{}, conditions)
conditions = appendIdentityProviderObjectRefAPIGroupSuffixCondition(c.apiGroup, []string{}, conditions)
conditions = appendIdentityProviderObjectRefKindCondition(c.sortedAllowedKinds(), []string{}, conditions)
conditions = appendTransformsConstantsNamesUniqueCondition(sets.Set[string]{}, conditions)
conditions = appendTransformsExpressionsValidCondition([]string{}, conditions)
return federationDomainIssuer, conditions, nil
}
func (c *federationDomainWatcherController) makeFederationDomainIssuerWithExplicitIDPs(
ctx context.Context,
federationDomain *configv1alpha1.FederationDomain,
conditions []*configv1alpha1.Condition,
) (*federationdomainproviders.FederationDomainIssuer, []*configv1alpha1.Condition, error) {
@ -337,10 +345,13 @@ func (c *federationDomainWatcherController) makeFederationDomainIssuerWithExplic
badKinds := []string{}
for index, idp := range federationDomain.Spec.IdentityProviders {
idpIsValid := true
// The CRD requires the displayName field, and validates that it has at least one character,
// so here we only need to validate that they are unique.
if displayNames.Has(idp.DisplayName) {
duplicateDisplayNames.Insert(idp.DisplayName)
idpIsValid = false
}
displayNames.Insert(idp.DisplayName)
@ -361,6 +372,7 @@ func (c *federationDomainWatcherController) makeFederationDomainIssuerWithExplic
canTryToFindIDP = false
}
// When the apiGroup and kind are valid, try to find the IDP CR.
var idpResourceUID types.UID
idpWasFound := false
if canTryToFindIDP {
@ -375,26 +387,31 @@ func (c *federationDomainWatcherController) makeFederationDomainIssuerWithExplic
}
if !canTryToFindIDP || !idpWasFound {
idpNotFoundIndices = append(idpNotFoundIndices, index)
idpIsValid = false
}
var err error
var pipeline *idtransform.TransformationPipeline
pipeline, conditions, err = c.makeTransformationPipelineForIdentityProvider(idp, federationDomain.Name, conditions)
var allExamplesPassed bool
pipeline, allExamplesPassed, conditions, err = c.makeTransformationPipelineAndEvaluateExamplesForIdentityProvider(ctx, idp, index, conditions)
if err != nil {
return nil, nil, err
}
if !allExamplesPassed {
idpIsValid = false
}
// For each valid IDP (unique displayName, valid objectRef + valid transforms), add it to the list.
if !idpIsValid {
// Something about the IDP was not valid. Don't add it.
continue
}
// For a valid IDP (unique displayName, valid objectRef, valid transforms), add it to the list.
federationDomainIdentityProviders = append(federationDomainIdentityProviders, &federationdomainproviders.FederationDomainIdentityProvider{
DisplayName: idp.DisplayName,
UID: idpResourceUID,
Transforms: pipeline,
})
plog.Debug("loaded FederationDomain identity provider",
"federationDomain", federationDomain.Name,
"identityProviderDisplayName", idp.DisplayName,
"identityProviderResourceUID", idpResourceUID,
)
}
if len(idpNotFoundIndices) != 0 {
@ -457,12 +474,31 @@ func (c *federationDomainWatcherController) findIDPsUIDByObjectRef(objectRef cor
return idpResourceUID, true, nil
}
func (c *federationDomainWatcherController) makeTransformationPipelineForIdentityProvider(
func (c *federationDomainWatcherController) makeTransformationPipelineAndEvaluateExamplesForIdentityProvider(
ctx context.Context,
idp configv1alpha1.FederationDomainIdentityProvider,
federationDomainName string,
idpIndex int,
conditions []*configv1alpha1.Condition,
) (*idtransform.TransformationPipeline, []*configv1alpha1.Condition, error) {
pipeline := idtransform.NewTransformationPipeline()
) (*idtransform.TransformationPipeline, bool, []*configv1alpha1.Condition, error) {
consts, conditions, err := c.makeTransformsConstants(idp, conditions)
if err != nil {
return nil, false, nil, err
}
pipeline, conditions, err := c.makeTransformationPipeline(idp, idpIndex, consts, conditions)
if err != nil {
return nil, false, nil, err
}
allExamplesPassed, conditions := c.evaluateExamples(ctx, idp, pipeline, conditions)
return pipeline, allExamplesPassed, conditions, nil
}
func (c *federationDomainWatcherController) makeTransformsConstants(
idp configv1alpha1.FederationDomainIdentityProvider,
conditions []*configv1alpha1.Condition,
) (*celtransformer.TransformationConstants, []*configv1alpha1.Condition, error) {
consts := &celtransformer.TransformationConstants{
StringConstants: map[string]string{},
StringListConstants: map[string][]string{},
@ -488,10 +524,23 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
return nil, nil, fmt.Errorf("one of spec.identityProvider[].transforms.constants[].type is invalid: %q", constant.Type)
}
}
conditions = appendTransformsConstantsNamesUniqueCondition(duplicateConstNames, conditions)
return consts, conditions, nil
}
func (c *federationDomainWatcherController) makeTransformationPipeline(
idp configv1alpha1.FederationDomainIdentityProvider,
idpIndex int,
consts *celtransformer.TransformationConstants,
conditions []*configv1alpha1.Condition,
) (*idtransform.TransformationPipeline, []*configv1alpha1.Condition, error) {
pipeline := idtransform.NewTransformationPipeline()
expressionsCompileErrors := []string{}
// Compile all the expressions and add them to the pipeline.
for idx, expr := range idp.Transforms.Expressions {
for exprIndex, expr := range idp.Transforms.Expressions {
var rawTransform celtransformer.CELTransformation
switch expr.Type {
case "username/v1":
@ -507,37 +556,50 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
// This shouldn't really happen since the CRD validates it, but handle it as an error.
return nil, nil, fmt.Errorf("one of spec.identityProvider[].transforms.expressions[].type is invalid: %q", expr.Type)
}
compiledTransform, err := c.celTransformer.CompileTransformation(rawTransform, consts)
if err != nil {
// TODO: handle compile err
plog.Error("error compiling identity transformation", err,
"federationDomain", federationDomainName,
"idpDisplayName", idp.DisplayName,
"transformationIndex", idx,
"transformationType", expr.Type,
"transformationExpression", expr.Expression,
)
expressionsCompileErrors = append(expressionsCompileErrors,
fmt.Sprintf("spec.identityProvider[%d].transforms.expressions[%d].expression was invalid:\n%s",
idpIndex, exprIndex, err.Error()))
}
pipeline.AppendTransformation(compiledTransform)
plog.Debug("successfully compiled identity transformation expression",
"type", expr.Type,
"expr", expr.Expression,
"policyMessage", expr.Message,
)
}
conditions = appendTransformsExpressionsValidCondition(expressionsCompileErrors, conditions)
if len(expressionsCompileErrors) > 0 {
// One or more of the expressions did not compile, so we don't have a useful pipeline to return.
return nil, conditions, nil
}
return pipeline, conditions, nil
}
func (c *federationDomainWatcherController) evaluateExamples(
ctx context.Context,
idp configv1alpha1.FederationDomainIdentityProvider,
pipeline *idtransform.TransformationPipeline,
conditions []*configv1alpha1.Condition,
) (bool, []*configv1alpha1.Condition) {
if pipeline == nil {
// TODO cannot evaluate examples, but still need to write a condition for it
return false, conditions
}
// Run all the provided transform examples. If any fail, put errors on the FederationDomain status.
for idx, e := range idp.Transforms.Examples {
// TODO: use a real context param below
result, _ := pipeline.Evaluate(context.TODO(), e.Username, e.Groups)
examplesErrors := []string{}
for examplesIndex, e := range idp.Transforms.Examples {
result, _ := pipeline.Evaluate(ctx, e.Username, e.Groups)
// TODO: handle err
resultWasAuthRejected := !result.AuthenticationAllowed
if e.Expects.Rejected && !resultWasAuthRejected { //nolint:gocritic,nestif
// TODO: handle this failed example
examplesErrors = append(examplesErrors, "TODO")
plog.Warning("FederationDomain identity provider transformations example failed: expected authentication to be rejected but it was not",
"federationDomain", federationDomainName,
"idpDisplayName", idp.DisplayName,
"exampleIndex", idx,
"exampleIndex", examplesIndex,
"expectedRejected", e.Expects.Rejected,
"actualRejectedResult", resultWasAuthRejected,
"expectedMessage", e.Expects.Message,
@ -545,10 +607,10 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
)
} else if !e.Expects.Rejected && resultWasAuthRejected {
// TODO: handle this failed example
examplesErrors = append(examplesErrors, "TODO")
plog.Warning("FederationDomain identity provider transformations example failed: expected authentication not to be rejected but it was rejected",
"federationDomain", federationDomainName,
"idpDisplayName", idp.DisplayName,
"exampleIndex", idx,
"exampleIndex", examplesIndex,
"expectedRejected", e.Expects.Rejected,
"actualRejectedResult", resultWasAuthRejected,
"expectedMessage", e.Expects.Message,
@ -557,10 +619,10 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
} else if e.Expects.Rejected && resultWasAuthRejected && e.Expects.Message != result.RejectedAuthenticationMessage {
// TODO: when expected message is blank, then treat it like it expects the default message
// TODO: handle this failed example
examplesErrors = append(examplesErrors, "TODO")
plog.Warning("FederationDomain identity provider transformations example failed: expected a different authentication rejection message",
"federationDomain", federationDomainName,
"idpDisplayName", idp.DisplayName,
"exampleIndex", idx,
"exampleIndex", examplesIndex,
"expectedRejected", e.Expects.Rejected,
"actualRejectedResult", resultWasAuthRejected,
"expectedMessage", e.Expects.Message,
@ -572,10 +634,10 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
// TODO: when both of these fail, put both errors onto the status (not just the first one)
if e.Expects.Username != result.Username {
// TODO: handle this failed example
examplesErrors = append(examplesErrors, "TODO")
plog.Warning("FederationDomain identity provider transformations example failed: expected a different transformed username",
"federationDomain", federationDomainName,
"idpDisplayName", idp.DisplayName,
"exampleIndex", idx,
"exampleIndex", examplesIndex,
"expectedUsername", e.Expects.Username,
"actualUsernameResult", result.Username,
)
@ -584,10 +646,10 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
// TODO: Do we need to make this insensitive to ordering, or should the transformations evaluator be changed to always return sorted group names at the end of the pipeline?
// TODO: What happens if the user did not write any group expectation? Treat it like expecting an empty list of groups?
// TODO: handle this failed example
examplesErrors = append(examplesErrors, "TODO")
plog.Warning("FederationDomain identity provider transformations example failed: expected a different transformed groups list",
"federationDomain", federationDomainName,
"idpDisplayName", idp.DisplayName,
"exampleIndex", idx,
"exampleIndex", examplesIndex,
"expectedGroups", e.Expects.Groups,
"actualGroupsResult", result.Groups,
)
@ -595,7 +657,7 @@ func (c *federationDomainWatcherController) makeTransformationPipelineForIdentit
}
}
return pipeline, conditions, nil
return len(examplesErrors) == 0, conditions
}
func (c *federationDomainWatcherController) sortedAllowedKinds() []string {
@ -642,6 +704,26 @@ func appendIdentityProviderObjectRefAPIGroupSuffixCondition(expectedSuffixName s
return conditions
}
func appendTransformsExpressionsValidCondition(errors []string, conditions []*configv1alpha1.Condition) []*configv1alpha1.Condition {
if len(errors) > 0 {
conditions = append(conditions, &configv1alpha1.Condition{
Type: typeTransformsExpressionsValid,
Status: configv1alpha1.ConditionFalse,
Reason: reasonInvalidTransformsExpressions,
Message: fmt.Sprintf("the expressions specified by .spec.identityProviders[].transforms.expressions[] were invalid:\n\n%s",
strings.Join(errors, "\n\n")),
})
} else {
conditions = append(conditions, &configv1alpha1.Condition{
Type: typeTransformsExpressionsValid,
Status: configv1alpha1.ConditionTrue,
Reason: reasonSuccess,
Message: "the expressions specified by .spec.identityProviders[].transforms.expressions[] are valid",
})
}
return conditions
}
func appendIdentityProviderDuplicateDisplayNamesCondition(duplicateDisplayNames sets.Set[string], conditions []*configv1alpha1.Condition) []*configv1alpha1.Condition {
if duplicateDisplayNames.Len() > 0 {
conditions = append(conditions, &configv1alpha1.Condition{

View File

@ -27,6 +27,7 @@ import (
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
"go.pinniped.dev/internal/controllerlib"
"go.pinniped.dev/internal/federationdomain/federationdomainproviders"
"go.pinniped.dev/internal/here"
"go.pinniped.dev/internal/idtransform"
"go.pinniped.dev/internal/testutil"
)
@ -419,6 +420,28 @@ func TestTestFederationDomainWatcherControllerSync(t *testing.T) {
}
}
happyTransformationExpressionsCondition := func(time metav1.Time, observedGeneration int64) configv1alpha1.Condition {
return configv1alpha1.Condition{
Type: "TransformsExpressionsValid",
Status: "True",
ObservedGeneration: observedGeneration,
LastTransitionTime: time,
Reason: "Success",
Message: "the expressions specified by .spec.identityProviders[].transforms.expressions[] are valid",
}
}
sadTransformationExpressionsCondition := func(errorMessages string, time metav1.Time, observedGeneration int64) configv1alpha1.Condition {
return configv1alpha1.Condition{
Type: "TransformsExpressionsValid",
Status: "False",
ObservedGeneration: observedGeneration,
LastTransitionTime: time,
Reason: "InvalidTransformsExpressions",
Message: fmt.Sprintf("the expressions specified by .spec.identityProviders[].transforms.expressions[] were invalid:\n\n%s", errorMessages),
}
}
happyAPIGroupSuffixCondition := func(time metav1.Time, observedGeneration int64) configv1alpha1.Condition {
return configv1alpha1.Condition{
Type: "IdentityProvidersObjectRefAPIGroupSuffixValid",
@ -474,22 +497,21 @@ func TestTestFederationDomainWatcherControllerSync(t *testing.T) {
return cp
}
allHappyConditionsLegacyConfigurationSuccess := func(issuer string, idpName string, time metav1.Time, observedGeneration int64) []configv1alpha1.Condition {
return sortConditionsByType([]configv1alpha1.Condition{
happyConstNamesUniqueCondition(frozenMetav1Now, 123),
happyKindCondition(frozenMetav1Now, 123),
happyAPIGroupSuffixCondition(frozenMetav1Now, 123),
happyDisplayNamesUniqueCondition(frozenMetav1Now, 123),
happyIdentityProvidersFoundConditionLegacyConfigurationSuccess(idpName, time, observedGeneration),
happyIssuerIsUniqueCondition(time, observedGeneration),
happyIssuerURLValidCondition(time, observedGeneration),
happyOneTLSSecretPerIssuerHostnameCondition(time, observedGeneration),
happyReadyCondition(issuer, time, observedGeneration),
})
replaceConditions := func(conditions []configv1alpha1.Condition, sadConditions []configv1alpha1.Condition) []configv1alpha1.Condition {
for _, sadReplaceCondition := range sadConditions {
for origIndex, origCondition := range conditions {
if origCondition.Type == sadReplaceCondition.Type {
conditions[origIndex] = sadReplaceCondition
break
}
}
}
return conditions
}
allHappyConditionsSuccess := func(issuer string, time metav1.Time, observedGeneration int64) []configv1alpha1.Condition {
return sortConditionsByType([]configv1alpha1.Condition{
happyTransformationExpressionsCondition(frozenMetav1Now, 123),
happyConstNamesUniqueCondition(frozenMetav1Now, 123),
happyKindCondition(frozenMetav1Now, 123),
happyAPIGroupSuffixCondition(frozenMetav1Now, 123),
@ -502,16 +524,13 @@ func TestTestFederationDomainWatcherControllerSync(t *testing.T) {
})
}
replaceConditions := func(conditions []configv1alpha1.Condition, sadConditions []configv1alpha1.Condition) []configv1alpha1.Condition {
for _, sadReplaceCondition := range sadConditions {
for origIndex, origCondition := range conditions {
if origCondition.Type == sadReplaceCondition.Type {
conditions[origIndex] = sadReplaceCondition
break
}
}
}
return conditions
allHappyConditionsLegacyConfigurationSuccess := func(issuer string, idpName string, time metav1.Time, observedGeneration int64) []configv1alpha1.Condition {
return replaceConditions(
allHappyConditionsSuccess(issuer, time, observedGeneration),
[]configv1alpha1.Condition{
happyIdentityProvidersFoundConditionLegacyConfigurationSuccess(idpName, time, observedGeneration),
},
)
}
invalidIssuerURL := ":/host//path"
@ -1228,36 +1247,12 @@ func TestTestFederationDomainWatcherControllerSync(t *testing.T) {
},
Transforms: configv1alpha1.FederationDomainTransforms{
Constants: []configv1alpha1.FederationDomainTransformsConstant{
{
Name: "duplicate1",
Type: "string",
StringValue: "abc",
},
{
Name: "duplicate1",
Type: "string",
StringValue: "def",
},
{
Name: "duplicate1",
Type: "string",
StringValue: "efg",
},
{
Name: "duplicate2",
Type: "string",
StringValue: "123",
},
{
Name: "duplicate2",
Type: "string",
StringValue: "456",
},
{
Name: "unique",
Type: "string",
StringValue: "hij",
},
{Name: "duplicate1", Type: "string", StringValue: "abc"},
{Name: "duplicate1", Type: "string", StringValue: "def"},
{Name: "duplicate1", Type: "string", StringValue: "efg"},
{Name: "duplicate2", Type: "string", StringValue: "123"},
{Name: "duplicate2", Type: "string", StringValue: "456"},
{Name: "uniqueName", Type: "string", StringValue: "hij"},
},
},
},
@ -1281,6 +1276,67 @@ func TestTestFederationDomainWatcherControllerSync(t *testing.T) {
),
},
},
{
name: "the federation domain has transformation expressions which don't compile",
inputObjects: []runtime.Object{
oidcIdentityProvider,
&configv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{Name: "config1", Namespace: namespace, Generation: 123},
Spec: configv1alpha1.FederationDomainSpec{
Issuer: "https://issuer1.com",
IdentityProviders: []configv1alpha1.FederationDomainIdentityProvider{
{
DisplayName: "name1",
ObjectRef: corev1.TypedLocalObjectReference{
APIGroup: pointer.String(apiGroupSupervisor),
Kind: "OIDCIdentityProvider",
Name: oidcIdentityProvider.Name,
},
Transforms: configv1alpha1.FederationDomainTransforms{
Expressions: []configv1alpha1.FederationDomainTransformsExpression{
{Type: "username/v1", Expression: "this is not a valid cel expression"},
{Type: "groups/v1", Expression: "this is also not a valid cel expression"},
{Type: "username/v1", Expression: "username"}, // valid
{Type: "policy/v1", Expression: "still not a valid cel expression"},
},
},
},
},
},
},
},
wantFDIssuers: []*federationdomainproviders.FederationDomainIssuer{},
wantStatusUpdates: []*configv1alpha1.FederationDomain{
expectedFederationDomainStatusUpdate(
&configv1alpha1.FederationDomain{
ObjectMeta: metav1.ObjectMeta{Name: "config1", Namespace: namespace, Generation: 123},
},
configv1alpha1.FederationDomainPhaseError,
replaceConditions(
allHappyConditionsSuccess("https://issuer1.com", frozenMetav1Now, 123),
[]configv1alpha1.Condition{
sadTransformationExpressionsCondition(
here.Doc(
`spec.identityProvider[0].transforms.expressions[0].expression was invalid:
CEL expression compile error: ERROR: <input>:1:6: Syntax error: mismatched input 'is' expecting <EOF>
| this is not a valid cel expression
| .....^
spec.identityProvider[0].transforms.expressions[1].expression was invalid:
CEL expression compile error: ERROR: <input>:1:6: Syntax error: mismatched input 'is' expecting <EOF>
| this is also not a valid cel expression
| .....^
spec.identityProvider[0].transforms.expressions[3].expression was invalid:
CEL expression compile error: ERROR: <input>:1:7: Syntax error: mismatched input 'not' expecting <EOF>
| still not a valid cel expression
| ......^`),
frozenMetav1Now, 123),
sadReadyCondition(frozenMetav1Now, 123),
}),
),
},
},
{
name: "the federation domain specifies illegal const type, which shouldn't really happen since the CRD validates it",
inputObjects: []runtime.Object{

View File

@ -142,6 +142,7 @@ func TestSupervisorOIDCDiscovery_Disruptive(t *testing.T) {
"IdentityProvidersObjectRefAPIGroupSuffixValid": v1alpha1.ConditionTrue,
"IdentityProvidersDisplayNamesUnique": v1alpha1.ConditionTrue,
"TransformsConstantsNamesUnique": v1alpha1.ConditionTrue,
"TransformsExpressionsValid": v1alpha1.ConditionTrue,
})
requireStatus(t, client, ns, config6Duplicate2.Name, v1alpha1.FederationDomainPhaseError, map[string]v1alpha1.ConditionStatus{
"Ready": v1alpha1.ConditionFalse,
@ -153,6 +154,7 @@ func TestSupervisorOIDCDiscovery_Disruptive(t *testing.T) {
"IdentityProvidersObjectRefAPIGroupSuffixValid": v1alpha1.ConditionTrue,
"IdentityProvidersDisplayNamesUnique": v1alpha1.ConditionTrue,
"TransformsConstantsNamesUnique": v1alpha1.ConditionTrue,
"TransformsExpressionsValid": v1alpha1.ConditionTrue,
})
requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, issuer6)
@ -181,6 +183,7 @@ func TestSupervisorOIDCDiscovery_Disruptive(t *testing.T) {
"IdentityProvidersObjectRefAPIGroupSuffixValid": v1alpha1.ConditionTrue,
"IdentityProvidersDisplayNamesUnique": v1alpha1.ConditionTrue,
"TransformsConstantsNamesUnique": v1alpha1.ConditionTrue,
"TransformsExpressionsValid": v1alpha1.ConditionTrue,
})
requireDiscoveryEndpointsAreNotFound(t, scheme, addr, caBundle, badIssuer)
requireDeletingFederationDomainCausesDiscoveryEndpointsToDisappear(t, badConfig, client, ns, scheme, addr, caBundle, badIssuer)
@ -698,6 +701,7 @@ func requireFullySuccessfulStatus(t *testing.T, client pinnipedclientset.Interfa
"IdentityProvidersObjectRefAPIGroupSuffixValid": v1alpha1.ConditionTrue,
"IdentityProvidersDisplayNamesUnique": v1alpha1.ConditionTrue,
"TransformsConstantsNamesUnique": v1alpha1.ConditionTrue,
"TransformsExpressionsValid": v1alpha1.ConditionTrue,
})
}