diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4bd1c5569..7808b5a7d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -92,7 +92,7 @@ jobs: fail-fast: false matrix: WEAVIATE_VERSION: - ["1.32.24", "1.33.11", "1.34.7", "1.35.2", "1.36.9", "1.37.0-rc.0"] + ["1.32.24", "1.33.11", "1.34.7", "1.35.2", "1.36.9", "1.37.1"] steps: - uses: actions/checkout@v4 diff --git a/src/it/java/io/weaviate/containers/Weaviate.java b/src/it/java/io/weaviate/containers/Weaviate.java index f0730fb4d..d7c7fcd03 100644 --- a/src/it/java/io/weaviate/containers/Weaviate.java +++ b/src/it/java/io/weaviate/containers/Weaviate.java @@ -45,7 +45,7 @@ public enum Version { V134(1, 34, 7), V135(1, 35, 2), V136(1, 36, 9), - V137(1, 37, "0-rc.0"); + V137(1, 37, 1); public final SemanticVersion semver; @@ -308,6 +308,7 @@ public Weaviate build() { // Required in v1.36.1, but we'll just set it by default. c.withEnv("OBJECTS_TTL_DELETE_SCHEDULE", "@hourly"); + c.withEnv("ENABLE_EXPERIMENTAL_ALTER_SCHEMA_DROP_VECTOR_INDEX_ENDPOINT", "true"); var apiKeyUsers = new HashSet(); apiKeyUsers.addAll(adminUsers); diff --git a/src/it/java/io/weaviate/integration/RbacITest.java b/src/it/java/io/weaviate/integration/RbacITest.java index 55a20ece7..f3c183355 100644 --- a/src/it/java/io/weaviate/integration/RbacITest.java +++ b/src/it/java/io/weaviate/integration/RbacITest.java @@ -14,6 +14,7 @@ import io.weaviate.client6.v1.api.rbac.AliasesPermission; import io.weaviate.client6.v1.api.rbac.BackupsPermission; import io.weaviate.client6.v1.api.rbac.ClusterPermission; +import io.weaviate.client6.v1.api.rbac.McpPermission; import io.weaviate.client6.v1.api.rbac.CollectionsPermission; import io.weaviate.client6.v1.api.rbac.DataPermission; import io.weaviate.client6.v1.api.rbac.GroupsPermission; @@ -83,6 +84,12 @@ public void test_roles_Lifecycle() throws IOException { permissions.add( Permission.groups("my-group", GroupType.OIDC, GroupsPermission.Action.READ)); }); + requireAtLeast(Weaviate.Version.V137, () -> { + permissions.add(Permission.mcp( + McpPermission.Action.CREATE, + McpPermission.Action.READ, + McpPermission.Action.UPDATE)); + }); // Act: create role client.roles.create(nsRole, permissions); diff --git a/src/main/java/io/weaviate/client6/v1/api/rbac/McpPermission.java b/src/main/java/io/weaviate/client6/v1/api/rbac/McpPermission.java new file mode 100644 index 000000000..133c2b7ee --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/rbac/McpPermission.java @@ -0,0 +1,46 @@ +package io.weaviate.client6.v1.api.rbac; + +import java.util.Arrays; +import java.util.List; + +import com.google.gson.annotations.SerializedName; + +public record McpPermission( + @SerializedName("actions") List actions) implements Permission { + + public McpPermission(Action... actions) { + this(Arrays.asList(actions)); + } + + @Override + public Permission.Kind _kind() { + return Permission.Kind.MCP; + } + + @Override + public Object self() { + return this; + } + + public enum Action implements RbacAction { + @SerializedName("create_mcp") + CREATE("create_mcp"), + + @SerializedName("read_mcp") + READ("read_mcp"), + + @SerializedName("update_mcp") + UPDATE("update_mcp"); + + private final String jsonValue; + + private Action(String jsonValue) { + this.jsonValue = jsonValue; + } + + @Override + public String jsonValue() { + return jsonValue; + } + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/rbac/Permission.java b/src/main/java/io/weaviate/client6/v1/api/rbac/Permission.java index 9374c4e35..573a2fed6 100644 --- a/src/main/java/io/weaviate/client6/v1/api/rbac/Permission.java +++ b/src/main/java/io/weaviate/client6/v1/api/rbac/Permission.java @@ -41,7 +41,8 @@ enum Kind implements JsonEnum { USERS("users"), // Fake permission kinds: Weaviate does not use those. - CLUSTER("cluster"); + CLUSTER("cluster"), + MCP("mcp"); private static final Map jsonValueMap = JsonEnum.collectNames(Kind.values()); private final String jsonValue; @@ -153,6 +154,14 @@ public static UsersPermission users(String userId, UsersPermission.Action... act return new UsersPermission(userId, actions); } + /** + * Create {@link McpPermission}. + */ + public static McpPermission mcp(McpPermission.Action... actions) { + checkDeprecation(actions); + return new McpPermission(actions); + } + /** * Create {@link ReplicatePermission}. * @@ -222,6 +231,7 @@ private final void init(Gson gson) { addAdapter(gson, Permission.Kind.ROLES, RolesPermission.class); addAdapter(gson, Permission.Kind.NODES, NodesPermission.class); addAdapter(gson, Permission.Kind.TENANTS, TenantsPermission.class); + addAdapter(gson, Permission.Kind.MCP, McpPermission.class); addAdapter(gson, Permission.Kind.REPLICATE, ReplicatePermission.class); addAdapter(gson, Permission.Kind.USERS, UsersPermission.class); addAdapter(gson, Permission.Kind.CLUSTER, ClusterPermission.class); @@ -283,6 +293,8 @@ public Permission read(JsonReader in) throws IOException { var actionString = action.getAsString(); if (actionString.endsWith("_cluster")) { kind = Permission.Kind.CLUSTER; + } else if (actionString.endsWith("_mcp")) { + kind = Permission.Kind.MCP; } else { throw new IllegalArgumentException("unknown RBAC action " + actionString); } diff --git a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java index ffb39f6cd..23a5b4c5b 100644 --- a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java +++ b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java @@ -66,6 +66,7 @@ import io.weaviate.client6.v1.api.rbac.AliasesPermission; import io.weaviate.client6.v1.api.rbac.BackupsPermission; import io.weaviate.client6.v1.api.rbac.ClusterPermission; +import io.weaviate.client6.v1.api.rbac.McpPermission; import io.weaviate.client6.v1.api.rbac.CollectionsPermission; import io.weaviate.client6.v1.api.rbac.DataPermission; import io.weaviate.client6.v1.api.rbac.GroupsPermission; @@ -1473,6 +1474,24 @@ public static Object[][] testCases() { } """ }, + { + Role.class, + new Role( + "rock-n-role", + List.of( + new McpPermission( + List.of(McpPermission.Action.CREATE, McpPermission.Action.READ, McpPermission.Action.UPDATE)))), + """ + { + "name": "rock-n-role", + "permissions": [ + { "action": "create_mcp" }, + { "action": "read_mcp" }, + { "action": "update_mcp" } + ] + } + """ + }, { Role.class, new Role(