Skip to content

Commit

Permalink
Merge pull request #169 from lsst-sqre/tickets/DM-35881
Browse files Browse the repository at this point in the history
[DM-35881] Add GID support
  • Loading branch information
rra authored Aug 19, 2022
2 parents 9ebb1b7 + 76ae23d commit c71a927
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 56 deletions.
105 changes: 57 additions & 48 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,48 +130,57 @@ charset-normalizer==2.1.0 \
# via
# -c requirements/main.txt
# aiohttp
coverage[toml]==6.4.3 \
--hash=sha256:04010af3c06ce2bfeb3b1e4e05d136f88d88c25f76cd4faff5d1fd84d11581ea \
--hash=sha256:05de0762c1caed4a162b3e305f36cf20a548ff4da0be6766ad5c870704be3660 \
--hash=sha256:068d6f2a893af838291b8809c876973d885543411ea460f3e6886ac0ee941732 \
--hash=sha256:0a84376e4fd13cebce2c0ef8c2f037929c8307fb94af1e5dbe50272a1c651b5d \
--hash=sha256:0e34247274bde982bbc613894d33f9e36358179db2ed231dd101c48dd298e7b0 \
--hash=sha256:0e3a41aad5919613483aad9ebd53336905cab1bd6788afd3995c2a972d89d795 \
--hash=sha256:306788fd019bb90e9cbb83d3f3c6becad1c048dd432af24f8320cf38ac085684 \
--hash=sha256:39ebd8e120cb77a06ee3d5fc26f9732670d1c397d7cd3acf02f6f62693b89b80 \
--hash=sha256:411fdd9f4203afd93b056c0868c8f9e5e16813e765de962f27e4e5798356a052 \
--hash=sha256:4822327b35cb032ff16af3bec27f73985448f08e874146b5b101e0e558b613dd \
--hash=sha256:52f8b9fcf3c5e427d51bbab1fb92b575a9a9235d516f175b24712bcd4b5be917 \
--hash=sha256:53c8edd3b83a4ddba3d8c506f1359401e7770b30f2188f15c17a338adf5a14db \
--hash=sha256:555a498999c44f5287cc95500486cd0d4f021af9162982cbe504d4cb388f73b5 \
--hash=sha256:59fc88bc13e30f25167e807b8cad3c41b7218ef4473a20c86fd98a7968733083 \
--hash=sha256:5a559aab40c716de80c7212295d0dc96bc1b6c719371c20dd18c5187c3155518 \
--hash=sha256:5de1e9335e2569974e20df0ce31493d315a830d7987e71a24a2a335a8d8459d3 \
--hash=sha256:6630d8d943644ea62132789940ca97d05fac83f73186eaf0930ffa715fbdab6b \
--hash=sha256:73a10939dc345460ca0655356a470dd3de9759919186a82383c87b6eb315faf2 \
--hash=sha256:7856ea39059d75f822ff0df3a51ea6d76307c897048bdec3aad1377e4e9dca20 \
--hash=sha256:877ee5478fd78e100362aed56db47ccc5f23f6e7bb035a8896855f4c3e49bc9b \
--hash=sha256:920a734fe3d311ca01883b4a19aa386c97b82b69fbc023458899cff0a0d621b9 \
--hash=sha256:923f9084d7e1d31b5f74c92396b05b18921ed01ee5350402b561a79dce3ea48d \
--hash=sha256:a0d2df4227f645a879010461df2cea6b7e3fb5a97d7eafa210f7fb60345af9e8 \
--hash=sha256:a2738ba1ee544d6f294278cfb6de2dc1f9a737a780469b5366e662a218f806c3 \
--hash=sha256:a42eaaae772f14a5194f181740a67bfd48e8806394b8c67aa4399e09d0d6b5db \
--hash=sha256:ab2b1a89d2bc7647622e9eaf06128a5b5451dccf7c242deaa31420b055716481 \
--hash=sha256:ab9ef0187d6c62b09dec83a84a3b94f71f9690784c84fd762fb3cf2d2b44c914 \
--hash=sha256:adf1a0d272633b21d645dd6e02e3293429c1141c7d65a58e4cbcd592d53b8e01 \
--hash=sha256:b104b6b1827d6a22483c469e3983a204bcf9c6bf7544bf90362c4654ebc2edf3 \
--hash=sha256:bc698580216050b5f4a34d2cdd2838b429c53314f1c4835fab7338200a8396f2 \
--hash=sha256:cdf7b83f04a313a21afb1f8730fe4dd09577fefc53bbdfececf78b2006f4268e \
--hash=sha256:d5191d53afbe5b6059895fa7f58223d3751c42b8101fb3ce767e1a0b1a1d8f87 \
--hash=sha256:d75314b00825d70e1e34b07396e23f47ed1d4feedc0122748f9f6bd31a544840 \
--hash=sha256:e4d64304acf79766e650f7acb81d263a3ea6e2d0d04c5172b7189180ff2c023c \
--hash=sha256:ec2ae1f398e5aca655b7084392d23e80efb31f7a660d2eecf569fb9f79b3fb94 \
--hash=sha256:eff095a5aac7011fdb51a2c82a8fae9ec5211577f4b764e1e59cfa27ceeb1b59 \
--hash=sha256:f1eda5cae434282712e40b42aaf590b773382afc3642786ac3ed39053973f61f \
--hash=sha256:f217850ac0e046ede611312703423767ca032a7b952b5257efac963942c055de \
--hash=sha256:f50d3a822947572496ea922ee7825becd8e3ae6fbd2400cd8236b7d64b17f285 \
--hash=sha256:fc294de50941d3da66a09dca06e206297709332050973eca17040278cb0918ff \
--hash=sha256:ff9832434a9193fbd716fbe05f9276484e18d26cc4cf850853594bb322807ac3
coverage[toml]==6.4.4 \
--hash=sha256:01778769097dbd705a24e221f42be885c544bb91251747a8a3efdec6eb4788f2 \
--hash=sha256:08002f9251f51afdcc5e3adf5d5d66bb490ae893d9e21359b085f0e03390a820 \
--hash=sha256:1238b08f3576201ebf41f7c20bf59baa0d05da941b123c6656e42cdb668e9827 \
--hash=sha256:14a32ec68d721c3d714d9b105c7acf8e0f8a4f4734c811eda75ff3718570b5e3 \
--hash=sha256:15e38d853ee224e92ccc9a851457fb1e1f12d7a5df5ae44544ce7863691c7a0d \
--hash=sha256:354df19fefd03b9a13132fa6643527ef7905712109d9c1c1903f2133d3a4e145 \
--hash=sha256:35ef1f8d8a7a275aa7410d2f2c60fa6443f4a64fae9be671ec0696a68525b875 \
--hash=sha256:4179502f210ebed3ccfe2f78bf8e2d59e50b297b598b100d6c6e3341053066a2 \
--hash=sha256:42c499c14efd858b98c4e03595bf914089b98400d30789511577aa44607a1b74 \
--hash=sha256:4b7101938584d67e6f45f0015b60e24a95bf8dea19836b1709a80342e01b472f \
--hash=sha256:564cd0f5b5470094df06fab676c6d77547abfdcb09b6c29c8a97c41ad03b103c \
--hash=sha256:5f444627b3664b80d078c05fe6a850dd711beeb90d26731f11d492dcbadb6973 \
--hash=sha256:6113e4df2fa73b80f77663445be6d567913fb3b82a86ceb64e44ae0e4b695de1 \
--hash=sha256:61b993f3998ee384935ee423c3d40894e93277f12482f6e777642a0141f55782 \
--hash=sha256:66e6df3ac4659a435677d8cd40e8eb1ac7219345d27c41145991ee9bf4b806a0 \
--hash=sha256:67f9346aeebea54e845d29b487eb38ec95f2ecf3558a3cffb26ee3f0dcc3e760 \
--hash=sha256:6913dddee2deff8ab2512639c5168c3e80b3ebb0f818fed22048ee46f735351a \
--hash=sha256:6a864733b22d3081749450466ac80698fe39c91cb6849b2ef8752fd7482011f3 \
--hash=sha256:7026f5afe0d1a933685d8f2169d7c2d2e624f6255fb584ca99ccca8c0e966fd7 \
--hash=sha256:783bc7c4ee524039ca13b6d9b4186a67f8e63d91342c713e88c1865a38d0892a \
--hash=sha256:7a98d6bf6d4ca5c07a600c7b4e0c5350cd483c85c736c522b786be90ea5bac4f \
--hash=sha256:8d032bfc562a52318ae05047a6eb801ff31ccee172dc0d2504614e911d8fa83e \
--hash=sha256:98c0b9e9b572893cdb0a00e66cf961a238f8d870d4e1dc8e679eb8bdc2eb1b86 \
--hash=sha256:9c7b9b498eb0c0d48b4c2abc0e10c2d78912203f972e0e63e3c9dc21f15abdaa \
--hash=sha256:9cc4f107009bca5a81caef2fca843dbec4215c05e917a59dec0c8db5cff1d2aa \
--hash=sha256:9d6e1f3185cbfd3d91ac77ea065d85d5215d3dfa45b191d14ddfcd952fa53796 \
--hash=sha256:a095aa0a996ea08b10580908e88fbaf81ecf798e923bbe64fb98d1807db3d68a \
--hash=sha256:a3b2752de32c455f2521a51bd3ffb53c5b3ae92736afde67ce83477f5c1dd928 \
--hash=sha256:ab066f5ab67059d1f1000b5e1aa8bbd75b6ed1fc0014559aea41a9eb66fc2ce0 \
--hash=sha256:c1328d0c2f194ffda30a45f11058c02410e679456276bfa0bbe0b0ee87225fac \
--hash=sha256:c35cca192ba700979d20ac43024a82b9b32a60da2f983bec6c0f5b84aead635c \
--hash=sha256:cbbb0e4cd8ddcd5ef47641cfac97d8473ab6b132dd9a46bacb18872828031685 \
--hash=sha256:cdbb0d89923c80dbd435b9cf8bba0ff55585a3cdb28cbec65f376c041472c60d \
--hash=sha256:cf2afe83a53f77aec067033199797832617890e15bed42f4a1a93ea24794ae3e \
--hash=sha256:d5dd4b8e9cd0deb60e6fcc7b0647cbc1da6c33b9e786f9c79721fd303994832f \
--hash=sha256:dfa0b97eb904255e2ab24166071b27408f1f69c8fbda58e9c0972804851e0558 \
--hash=sha256:e16c45b726acb780e1e6f88b286d3c10b3914ab03438f32117c4aa52d7f30d58 \
--hash=sha256:e1fabd473566fce2cf18ea41171d92814e4ef1495e04471786cbc943b89a3781 \
--hash=sha256:e3d3c4cc38b2882f9a15bafd30aec079582b819bec1b8afdbde8f7797008108a \
--hash=sha256:e431e305a1f3126477abe9a184624a85308da8edf8486a863601d58419d26ffa \
--hash=sha256:e7b4da9bafad21ea45a714d3ea6f3e1679099e420c8741c74905b92ee9bfa7cc \
--hash=sha256:ee2b2fb6eb4ace35805f434e0f6409444e1466a47f620d1d5763a22600f0f892 \
--hash=sha256:ee6ae6bbcac0786807295e9687169fba80cb0617852b2fa118a99667e8e6815d \
--hash=sha256:ef6f44409ab02e202b31a05dd6666797f9de2aa2b4b3534e9d450e42dea5e817 \
--hash=sha256:f67cf9f406cf0d2f08a3515ce2db5b82625a7257f88aad87904674def6ddaec1 \
--hash=sha256:f855b39e4f75abd0dfbcf74a82e84ae3fc260d523fcb3532786bcbbcb158322c \
--hash=sha256:fc600f6ec19b273da1d85817eda339fb46ce9eef3e89f220055d8696e0a06908 \
--hash=sha256:fcbe3d9a53e013f8ab88734d7e517eb2cd06b7e689bedf22c0eb68db5e4a0a19 \
--hash=sha256:fde17bc42e0716c94bf19d92e4c9f5a00c5feb401f5bc01101fdf2a8b7cacf60 \
--hash=sha256:ff934ced84054b9018665ca3967fc48e1ac99e811f6cc99ea65978e1d384454b
# via
# -r requirements/dev.in
# pytest-cov
Expand Down Expand Up @@ -495,13 +504,13 @@ types-pyyaml==6.0.11 \
--hash=sha256:7f7da2fd11e9bc1e5e9eb3ea1be84f4849747017a59fc2eee0ea34ed1147c2e0 \
--hash=sha256:8f890028123607379c63550179ddaec4517dc751f4c527a52bb61934bf495989
# via -r requirements/dev.in
types-requests==2.28.8 \
--hash=sha256:7a9f7b152d594a1c18dd4932cdd2596b8efbeedfd73caa4e4abb3755805b4685 \
--hash=sha256:b0421f9f2d0dd0f8df2c75f974686517ca67473f05b466232d4c6384d765ad7a
types-requests==2.28.9 \
--hash=sha256:86cb66d3de2f53eac5c09adc42cf6547eefbd0c7e1210beca1ee751c35d96083 \
--hash=sha256:feaf581bd580497a47fe845d506fa3b91b484cf706ff27774e87659837de9962
# via -r requirements/dev.in
types-urllib3==1.26.22 \
--hash=sha256:09a8783e1002472e8d1e1f3792d4c5cca1fffebb9b48ee1512aae6d16fe186bc \
--hash=sha256:b05af90e73889e688094008a97ca95788db8bf3736e2776fd43fb6b171485d94
types-urllib3==1.26.23 \
--hash=sha256:333e675b188a1c1fd980b4b352f9e40572413a4c1ac689c23cd546e96310070a \
--hash=sha256:b78e819f0e350221d0689a5666162e467ba3910737bafda14b5c2c85e9bb1e56
# via types-requests
typing-extensions==4.3.0 \
--hash=sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02 \
Expand Down
6 changes: 3 additions & 3 deletions requirements/main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ click==8.1.3 \
# via
# -r requirements/main.in
# uvicorn
fastapi==0.79.0 \
--hash=sha256:cf0ff6db25b91d321050c4112baab0908c90f19b40bf257f9591d2f9780d1f22 \
--hash=sha256:d337563424ceada23857f73d5abe8dae0c28e4cccb53b2af06e78b7bb4a1c7d7
fastapi==0.79.1 \
--hash=sha256:006862dec0f0f5683ac21fb0864af2ff12a931e7ba18920f28cc8eceed51896b \
--hash=sha256:3c584179c64e265749e88221c860520fc512ea37e253282dab378cc503dfd7fd
# via
# -r requirements/main.in
# safir
Expand Down
6 changes: 5 additions & 1 deletion src/mobu/flock.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ def _users_from_spec(self, spec: UserSpec, count: int) -> List[User]:
uid = spec.uid_start + i - 1
else:
uid = None
user = User(username=username, uidnumber=uid)
if spec.gid_start is not None:
gid = spec.gid_start + i - 1
else:
gid = None
user = User(username=username, uidnumber=uid, gidnumber=gid)
users.append(user)
return users
34 changes: 33 additions & 1 deletion src/mobu/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ class User(BaseModel):
example=60001,
)

gidnumber: Optional[int] = Field(
None,
title="Primary GID",
description=(
"If omitted but a UID was specified, use a GID equal to the UID."
" If both are omitted, Gafaelfawr will assign a UID and GID."
" (Gafaelfawr UID and GID assignment requires Firestore and"
" synthetic user private groups to be configured.)"
),
example=60001,
)


class UserSpec(BaseModel):
"""Configuration to generate a set of users."""
Expand All @@ -48,6 +60,19 @@ class UserSpec(BaseModel):
example=60000,
)

gid_start: Optional[int] = Field(
None,
title="Starting GID",
description=(
"Users will be given consecutive primary GIDs starting with this."
" If omitted but UIDs were given, the GIDs will be equal to the"
" UIDs. If both are omitted, Gafaelfawr will assign UIDs and GIDs"
" (which requires Firestore and synthetic user private groups to"
" be configured)."
),
example=60000,
)


class AuthenticatedUser(User):
"""Represents an authenticated user with a token."""
Expand Down Expand Up @@ -79,6 +104,12 @@ async def create(
}
if user.uidnumber is not None:
data["uid"] = user.uidnumber
if user.gidnumber is not None:
data["gid"] = user.gidnumber
else:
data["gid"] = user.uidnumber
elif user.gidnumber is not None:
data["gid"] = user.gidnumber
r = await session.post(
token_url,
headers={"Authorization": f"Bearer {config.gafaelfawr_token}"},
Expand All @@ -88,7 +119,8 @@ async def create(
body = await r.json()
return cls(
username=user.username,
uidnumber=user.uidnumber,
uidnumber=data["uid"] if "uid" in data else None,
gidnumber=data["gid"] if "gid" in data else None,
token=body["token"],
scopes=scopes,
)
10 changes: 9 additions & 1 deletion tests/autostart_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
user_spec:
username_prefix: testuser
uid_start: 1000
gid_start: 2000
scopes: ["exec:notebook"]
business: Business
- name: python
Expand Down Expand Up @@ -71,6 +72,7 @@ async def test_autostart(client: AsyncClient) -> None:
"scopes": ["exec:notebook"],
"token": ANY,
"uidnumber": 1000 + i - 1,
"gidnumber": 2000 + i - 1,
"username": f"testuser{i:02d}",
},
}
Expand All @@ -81,7 +83,11 @@ async def test_autostart(client: AsyncClient) -> None:
"config": {
"name": "basic",
"count": 10,
"user_spec": {"username_prefix": "testuser", "uid_start": 1000},
"user_spec": {
"username_prefix": "testuser",
"uid_start": 1000,
"gid_start": 2000,
},
"scopes": ["exec:notebook"],
"business": "Business",
},
Expand Down Expand Up @@ -140,6 +146,7 @@ async def test_autostart(client: AsyncClient) -> None:
"token": ANY,
"username": "python",
"uidnumber": 60000,
"gidnumber": 60000,
},
},
{
Expand All @@ -165,6 +172,7 @@ async def test_autostart(client: AsyncClient) -> None:
"token": ANY,
"username": "otherpython",
"uidnumber": 70000,
"gidnumber": 70000,
},
},
],
Expand Down
5 changes: 4 additions & 1 deletion tests/business/jupyterpythonloop_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
async def test_run(
client: AsyncClient, mock_aioresponses: aioresponses
) -> None:
mock_gafaelfawr(mock_aioresponses, username="testuser1", uid=1000)
mock_gafaelfawr(
mock_aioresponses, username="testuser1", uid=1000, gid=1000
)

r = await client.put(
"/mobu/flocks",
Expand Down Expand Up @@ -53,6 +55,7 @@ async def test_run(
"scopes": ["exec:notebook"],
"token": ANY,
"uidnumber": 1000,
"gidnumber": 1000,
"username": "testuser1",
},
}
Expand Down
3 changes: 3 additions & 0 deletions tests/handlers/flock_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ async def test_user_list(
{
"username": "testuser",
"uidnumber": 1000,
"gidnumber": 1056,
},
{
"username": "otheruser",
Expand Down Expand Up @@ -169,6 +170,7 @@ async def test_user_list(
"scopes": ["exec:notebook"],
"token": ANY,
"uidnumber": 1000,
"gidnumber": 1056,
"username": "testuser",
},
},
Expand All @@ -186,6 +188,7 @@ async def test_user_list(
"scopes": ["exec:notebook"],
"token": ANY,
"uidnumber": 60000,
"gidnumber": 60000,
"username": "otheruser",
},
},
Expand Down
4 changes: 4 additions & 0 deletions tests/support/gafaelfawr.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def mock_gafaelfawr(
mocked: aioresponses,
username: Optional[str] = None,
uid: Optional[int] = None,
gid: Optional[int] = None,
*,
any_uid: bool = False,
) -> None:
Expand All @@ -59,8 +60,11 @@ def handler(url: str, **kwargs: Any) -> CallbackResult:
}
if uid:
expected["uid"] = uid
if gid:
expected["gid"] = gid
elif any_uid:
expected["uid"] = ANY
expected["gid"] = ANY
assert kwargs["json"] == expected
assert kwargs["json"]["token_name"].startswith("mobu ")
assert kwargs["json"]["expires"] > time.time()
Expand Down
2 changes: 1 addition & 1 deletion tests/user_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

@pytest.mark.asyncio
async def test_generate_token(mock_aioresponses: aioresponses) -> None:
mock_gafaelfawr(mock_aioresponses, "someuser", 1234)
mock_gafaelfawr(mock_aioresponses, "someuser", 1234, 1234)
config = User(username="someuser", uidnumber=1234)
scopes = ["exec:notebook"]

Expand Down

0 comments on commit c71a927

Please sign in to comment.