Skip to content

Commit

Permalink
fix(rbac): do not mix apigroups.
Browse files Browse the repository at this point in the history
This fixes [bug]: RBAC roles get mixed between apigroups #583.
  • Loading branch information
buehler committed Jan 17, 2024
1 parent 7ce6a9b commit 8b024b1
Show file tree
Hide file tree
Showing 11 changed files with 32 additions and 21 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Expand Up @@ -27,6 +27,7 @@ insert_final_newline = true
dotnet_diagnostic.S3604.severity = none

dotnet_diagnostic.SA0001.severity = none
dotnet_diagnostic.SA1010.severity = none
dotnet_diagnostic.SA1600.severity = none
dotnet_diagnostic.CS1591.severity = none
dotnet_diagnostic.SA1008.severity = suggestion
Expand Down
Expand Up @@ -5,7 +5,7 @@ namespace KubeOps.Generator.SyntaxReceiver;

internal class EntityControllerSyntaxReceiver : ISyntaxContextReceiver
{
public List<(ClassDeclarationSyntax Controller, string EntityName)> Controllers { get; } = new();
public List<(ClassDeclarationSyntax Controller, string EntityName)> Controllers { get; } = [];

public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
{
Expand Down
Expand Up @@ -5,7 +5,7 @@ namespace KubeOps.Generator.SyntaxReceiver;

internal class EntityFinalizerSyntaxReceiver : ISyntaxContextReceiver
{
public List<(ClassDeclarationSyntax Finalizer, string EntityName)> Finalizer { get; } = new();
public List<(ClassDeclarationSyntax Finalizer, string EntityName)> Finalizer { get; } = [];

public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
{
Expand Down
Expand Up @@ -11,7 +11,7 @@ internal class KubernetesEntitySyntaxReceiver : ISyntaxContextReceiver
private const string VersionName = "ApiVersion";
private const string DefaultVersion = "v1";

public List<AttributedEntity> Entities { get; } = new();
public List<AttributedEntity> Entities { get; } = [];

public void OnVisitSyntaxNode(GeneratorSyntaxContext context)
{
Expand Down
2 changes: 1 addition & 1 deletion src/KubeOps.Transpiler/Crds.cs
Expand Up @@ -31,7 +31,7 @@ public static class Crds
private const string Decimal = "decimal";
private const string DateTime = "date-time";

private static readonly string[] IgnoredToplevelProperties = { "metadata", "apiversion", "kind" };
private static readonly string[] IgnoredToplevelProperties = ["metadata", "apiversion", "kind"];

/// <summary>
/// Transpile a single type to a CRD.
Expand Down
18 changes: 7 additions & 11 deletions src/KubeOps.Transpiler/Rbac.cs
Expand Up @@ -48,17 +48,13 @@ public static class Rbac
group => (
Crd: context.ToEntityMetadata(group.Key),
Verbs: group.Aggregate(RbacVerb.None, (accumulator, element) => accumulator | element.Verbs)))
.GroupBy(group => group.Verbs)
.Select(
group => (
Verbs: group.Key,
Crds: group.Select(element => element.Crd).ToList()))
.GroupBy(group => (group.Crd.Metadata.Group, group.Verbs))
.Select(
group => new V1PolicyRule
{
ApiGroups = group.Crds.Select(crd => crd.Metadata.Group).Distinct().ToList(),
Resources = group.Crds.Select(crd => crd.Metadata.PluralName).Distinct().ToList(),
Verbs = ConvertToStrings(group.Verbs),
ApiGroups = [group.Key.Group],
Resources = group.Select(crd => crd.Crd.Metadata.PluralName).Distinct().ToList(),
Verbs = ConvertToStrings(group.Key.Verbs),
});

var entityStatus = list
Expand All @@ -75,8 +71,8 @@ public static class Rbac
.Select(
crd => new V1PolicyRule
{
ApiGroups = new[] { crd.Metadata.Group },
Resources = new[] { $"{crd.Metadata.PluralName}/status" },
ApiGroups = [crd.Metadata.Group],
Resources = [$"{crd.Metadata.PluralName}/status"],
Verbs = ConvertToStrings(RbacVerb.Get | RbacVerb.Patch | RbacVerb.Update),
});

Expand All @@ -86,7 +82,7 @@ public static class Rbac
private static string[] ConvertToStrings(RbacVerb verbs) => verbs switch
{
RbacVerb.None => Array.Empty<string>(),
_ when verbs.HasFlag(RbacVerb.All) => new[] { "*" },
_ when verbs.HasFlag(RbacVerb.All) => ["*"],
_ =>
Enum.GetValues<RbacVerb>()
.Where(v => verbs.HasFlag(v) && v != RbacVerb.All && v != RbacVerb.None)
Expand Down
4 changes: 2 additions & 2 deletions src/KubeOps.Transpiler/Utilities.cs
Expand Up @@ -92,7 +92,7 @@ public static IEnumerable<CustomAttributeData> GetCustomAttributesData<TAttribut
attr.NamedArguments.FirstOrDefault(a => a.MemberName == name).TypedValue.Value is
ReadOnlyCollection<CustomAttributeTypedArgument> value
? value.Select(v => (T)v.Value!).ToList()
: new List<T>();
: [];

/// <summary>
/// Load a specific constructor argument from a custom attribute.
Expand Down Expand Up @@ -145,7 +145,7 @@ ReadOnlyCollection<CustomAttributeTypedArgument> value
attr.ConstructorArguments[index].Value is
ReadOnlyCollection<CustomAttributeTypedArgument> value
? value.Select(v => (T)v.Value!).ToList()
: new List<T>();
: [];

/// <summary>
/// Load a type from a metadata load context.
Expand Down
2 changes: 1 addition & 1 deletion test/KubeOps.Operator.Test/IntegrationTestCollection.cs
Expand Up @@ -72,7 +72,7 @@ public async Task DisposeAsync()

public sealed class CrdInstaller : IAsyncLifetime
{
private List<V1CustomResourceDefinition> _crds = new();
private List<V1CustomResourceDefinition> _crds = [];

public async Task InitializeAsync()
{
Expand Down
2 changes: 1 addition & 1 deletion test/KubeOps.Operator.Test/InvocationCounter.cs
Expand Up @@ -9,7 +9,7 @@ public class InvocationCounter<TEntity>
where TEntity : IKubernetesObject<V1ObjectMeta>
{
private TaskCompletionSource _task = new();
public readonly List<(string Method, TEntity Entity)> Invocations = new();
public readonly List<(string Method, TEntity Entity)> Invocations = [];

public Task WaitForInvocations => _task.Task;

Expand Down
Expand Up @@ -30,7 +30,7 @@ public abstract class IntegrationTestBase;

public sealed class CrdInstaller : IAsyncLifetime
{
private List<V1CustomResourceDefinition> _crds = new();
private List<V1CustomResourceDefinition> _crds = [];

public async Task InitializeAsync()
{
Expand Down
16 changes: 15 additions & 1 deletion test/KubeOps.Transpiler.Test/Rbac.Mlc.Test.cs
Expand Up @@ -75,6 +75,14 @@ public void Should_Group_Types_With_Same_Verbs_Together()
roles.Should().HaveCount(2);
}

[Fact]
public void Should_Not_Mix_ApiGroups()
{
var roles = _mlc
.Transpile(_mlc.GetContextType<RbacTest5>().GetCustomAttributesData<EntityRbacAttribute>()).ToList();
roles.Should().HaveCount(5);
}

[KubernetesEntity(Group = "test", ApiVersion = "v1")]
[EntityRbac(typeof(RbacTest1), Verbs = RbacVerb.Get)]
[EntityRbac(typeof(RbacTest1), Verbs = RbacVerb.Update)]
Expand Down Expand Up @@ -102,7 +110,13 @@ public class RbacTest3 : CustomKubernetesEntity;
public class RbacTest4 : CustomKubernetesEntity;

[KubernetesEntity(Group = "test", ApiVersion = "v1")]
[GenericRbac(Urls = new[] { "url", "foobar" }, Resources = new[] { "configmaps" }, Groups = new[] { "group" },
[EntityRbac(typeof(V1Deployment), Verbs = RbacVerb.All)]
[EntityRbac(typeof(V1Service), Verbs = RbacVerb.All)]
[EntityRbac(typeof(V1Lease), Verbs = RbacVerb.All)]
public class RbacTest5 : CustomKubernetesEntity;

[KubernetesEntity(Group = "test", ApiVersion = "v1")]
[GenericRbac(Urls = ["url", "foobar"], Resources = ["configmaps"], Groups = ["group"],
Verbs = RbacVerb.Delete | RbacVerb.Get)]
public class GenericRbacTest : CustomKubernetesEntity;
}

0 comments on commit 8b024b1

Please sign in to comment.