-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Add platform property to files entitlement #123212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1e23a29
61cd09b
eb5d5d8
342a23a
db4f96b
d81923c
d2f3c19
2c03f64
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,26 +42,55 @@ public enum BaseDir { | |
| HOME | ||
| } | ||
|
|
||
| public enum Platform { | ||
| LINUX, | ||
| MACOS, | ||
| WINDOWS; | ||
|
|
||
| private static final Platform current = findCurrent(); | ||
|
|
||
| private static Platform findCurrent() { | ||
| String os = System.getProperty("os.name"); | ||
| if (os.startsWith("Linux")) { | ||
| return LINUX; | ||
| } else if (os.startsWith("Mac OS")) { | ||
| return MACOS; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect we'll want a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had a version of this (calling it POSIX because these aren't actually unix), but I'm unsure it will actually be necessary because the location of system files on linux/mac are usually very different, even though they begin with
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. FWIW the JDK calls it the |
||
| } else if (os.startsWith("Windows")) { | ||
| return WINDOWS; | ||
| } else { | ||
| throw new AssertionError("Unsupported platform [" + os + "]"); | ||
| } | ||
| } | ||
|
|
||
| public boolean isCurrent() { | ||
| return this == current; | ||
| } | ||
| } | ||
|
|
||
| public sealed interface FileData { | ||
|
|
||
| Stream<Path> resolvePaths(PathLookup pathLookup); | ||
|
|
||
| Mode mode(); | ||
|
|
||
| Platform platform(); | ||
|
|
||
| FileData withPlatform(Platform platform); | ||
|
|
||
| static FileData ofPath(Path path, Mode mode) { | ||
| return new AbsolutePathFileData(path, mode); | ||
| return new AbsolutePathFileData(path, mode, null); | ||
ldematte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| static FileData ofRelativePath(Path relativePath, BaseDir baseDir, Mode mode) { | ||
| return new RelativePathFileData(relativePath, baseDir, mode); | ||
| return new RelativePathFileData(relativePath, baseDir, mode, null); | ||
| } | ||
|
|
||
| static FileData ofPathSetting(String setting, Mode mode) { | ||
| return new PathSettingFileData(setting, mode); | ||
| return new PathSettingFileData(setting, mode, null); | ||
| } | ||
|
|
||
| static FileData ofRelativePathSetting(String setting, BaseDir baseDir, Mode mode) { | ||
| return new RelativePathSettingFileData(setting, baseDir, mode); | ||
| return new RelativePathSettingFileData(setting, baseDir, mode, null); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -145,32 +174,70 @@ private static Stream<Path> relativePathsCombination(Path[] baseDirs, Stream<Pat | |
| return paths.stream(); | ||
| } | ||
|
|
||
| private record AbsolutePathFileData(Path path, Mode mode) implements FileData { | ||
| private record AbsolutePathFileData(Path path, Mode mode, Platform platform) implements FileData { | ||
| @Override | ||
| public Stream<Path> resolvePaths(PathLookup pathLookup) { | ||
| return Stream.of(path); | ||
| } | ||
|
|
||
| @Override | ||
| public FileData withPlatform(Platform platform) { | ||
| if (platform == platform()) { | ||
| return this; | ||
| } | ||
| return new AbsolutePathFileData(path, mode, platform); | ||
| } | ||
| } | ||
|
|
||
| private record RelativePathFileData(Path relativePath, BaseDir baseDir, Mode mode) implements FileData, RelativeFileData { | ||
| private record RelativePathFileData(Path relativePath, BaseDir baseDir, Mode mode, Platform platform) | ||
| implements | ||
| FileData, | ||
| RelativeFileData { | ||
| @Override | ||
| public Stream<Path> resolveRelativePaths(PathLookup pathLookup) { | ||
| return Stream.of(relativePath); | ||
| } | ||
|
|
||
| @Override | ||
| public FileData withPlatform(Platform platform) { | ||
| if (platform == platform()) { | ||
| return this; | ||
| } | ||
| return new RelativePathFileData(relativePath, baseDir, mode, platform); | ||
| } | ||
| } | ||
|
|
||
| private record PathSettingFileData(String setting, Mode mode) implements FileData { | ||
| private record PathSettingFileData(String setting, Mode mode, Platform platform) implements FileData { | ||
| @Override | ||
| public Stream<Path> resolvePaths(PathLookup pathLookup) { | ||
| return resolvePathSettings(pathLookup, setting); | ||
| } | ||
|
|
||
| @Override | ||
| public FileData withPlatform(Platform platform) { | ||
| if (platform == platform()) { | ||
| return this; | ||
| } | ||
| return new PathSettingFileData(setting, mode, platform); | ||
| } | ||
| } | ||
|
|
||
| private record RelativePathSettingFileData(String setting, BaseDir baseDir, Mode mode) implements FileData, RelativeFileData { | ||
| private record RelativePathSettingFileData(String setting, BaseDir baseDir, Mode mode, Platform platform) | ||
| implements | ||
| FileData, | ||
| RelativeFileData { | ||
| @Override | ||
| public Stream<Path> resolveRelativePaths(PathLookup pathLookup) { | ||
| return resolvePathSettings(pathLookup, setting); | ||
| } | ||
|
|
||
| @Override | ||
| public FileData withPlatform(Platform platform) { | ||
| if (platform == platform()) { | ||
| return this; | ||
| } | ||
| return new RelativePathSettingFileData(setting, baseDir, mode, platform); | ||
| } | ||
| } | ||
|
|
||
| private static Stream<Path> resolvePathSettings(PathLookup pathLookup, String setting) { | ||
|
|
@@ -191,6 +258,18 @@ private static Mode parseMode(String mode) { | |
| } | ||
| } | ||
|
|
||
| private static Platform parsePlatform(String platform) { | ||
| if (platform.equals("linux")) { | ||
| return Platform.LINUX; | ||
| } else if (platform.equals("macos")) { | ||
| return Platform.MACOS; | ||
| } else if (platform.equals("windows")) { | ||
| return Platform.WINDOWS; | ||
| } else { | ||
| throw new PolicyValidationException("invalid platform: " + platform + ", valid values: [linux, macos, windows]"); | ||
| } | ||
| } | ||
|
|
||
| private static BaseDir parseBaseDir(String baseDir) { | ||
| return switch (baseDir) { | ||
| case "config" -> BaseDir.CONFIG; | ||
|
|
@@ -218,6 +297,7 @@ public static FilesEntitlement build(List<Object> paths) { | |
| String pathSetting = file.remove("path_setting"); | ||
| String relativePathSetting = file.remove("relative_path_setting"); | ||
| String modeAsString = file.remove("mode"); | ||
| String platformAsString = file.remove("platform"); | ||
|
|
||
| if (file.isEmpty() == false) { | ||
| throw new PolicyValidationException("unknown key(s) [" + file + "] in a listed file for files entitlement"); | ||
|
|
@@ -234,36 +314,45 @@ public static FilesEntitlement build(List<Object> paths) { | |
| throw new PolicyValidationException("files entitlement must contain 'mode' for every listed file"); | ||
| } | ||
| Mode mode = parseMode(modeAsString); | ||
| Platform platform = null; | ||
| if (platformAsString != null) { | ||
| platform = parsePlatform(platformAsString); | ||
| } | ||
|
|
||
| BaseDir baseDir = null; | ||
| if (relativeTo != null) { | ||
| baseDir = parseBaseDir(relativeTo); | ||
| } | ||
|
|
||
| final FileData fileData; | ||
| if (relativePathAsString != null) { | ||
| if (baseDir == null) { | ||
| throw new PolicyValidationException("files entitlement with a 'relative_path' must specify 'relative_to'"); | ||
| } | ||
|
|
||
| Path relativePath = Path.of(relativePathAsString); | ||
| if (FileData.isAbsolutePath(relativePathAsString)) { | ||
| throw new PolicyValidationException("'relative_path' [" + relativePathAsString + "] must be relative"); | ||
| } | ||
| filesData.add(FileData.ofRelativePath(Path.of(relativePathAsString), baseDir, mode)); | ||
| fileData = FileData.ofRelativePath(relativePath, baseDir, mode); | ||
| } else if (pathAsString != null) { | ||
| Path path = Path.of(pathAsString); | ||
| if (FileData.isAbsolutePath(pathAsString) == false) { | ||
| throw new PolicyValidationException("'path' [" + pathAsString + "] must be absolute"); | ||
| } | ||
| filesData.add(FileData.ofPath(Path.of(pathAsString), mode)); | ||
| fileData = FileData.ofPath(path, mode); | ||
| } else if (pathSetting != null) { | ||
| filesData.add(FileData.ofPathSetting(pathSetting, mode)); | ||
| fileData = FileData.ofPathSetting(pathSetting, mode); | ||
| } else if (relativePathSetting != null) { | ||
| if (baseDir == null) { | ||
| throw new PolicyValidationException("files entitlement with a 'relative_path_setting' must specify 'relative_to'"); | ||
| } | ||
| filesData.add(FileData.ofRelativePathSetting(relativePathSetting, baseDir, mode)); | ||
| fileData = FileData.ofRelativePathSetting(relativePathSetting, baseDir, mode); | ||
| } else { | ||
| throw new AssertionError("File entry validation error"); | ||
| } | ||
|
|
||
| filesData.add(fileData.withPlatform(platform)); | ||
| } | ||
| return new FilesEntitlement(filesData); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Elasticsearch already have a way to determine the platform? (Are we really the first to need this?)
If it does, should we use that instead of parsing the
os.namesystem property?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several places we repeat this logic, including inside Lucene. Here we don't have access to Lucene classes. I originally had a comment in this change to move this logic to elasticsearch.core, but I removed it. We could consider moving it still, though, but as a followup.