Skip to content
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

Deploy userinfofetcher regorules #580

Draft
wants to merge 9 commits into
base: spike/bundle-builder-v2
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions Cargo.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rust/bundle-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ flate2.workspace = true
futures.workspace = true
hyper.workspace = true
snafu.workspace = true
stackable-opa-regorule-library = { version = "0.0.0-dev", path = "../regorule-library" }
stackable-operator.workspace = true
tar.workspace = true
tokio.workspace = true
Expand Down
32 changes: 21 additions & 11 deletions rust/bundle-builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,19 @@ enum BundleError {
#[snafu(display("ConfigMap is missing required metadata"))]
ConfigMapMetadataMissing,

#[snafu(display("file {file_name:?} in {config_map} is too large ({file_size} bytes)"))]
#[snafu(display("file {file_path:?} is too large ({file_size} bytes)"))]
FileSizeOverflow {
source: TryFromIntError,
config_map: ObjectRef<ConfigMap>,
file_name: String,
file_path: String,
file_size: usize,
},

#[snafu(display("failed to add static file {file_path:?} to tarball"))]
AddStaticRuleToTarball {
source: std::io::Error,
file_path: String,
},

#[snafu(display("failed to add file {file_name:?} from {config_map} to tarball"))]
AddFileToTarball {
source: std::io::Error,
Expand All @@ -201,20 +206,15 @@ impl BundleError {

async fn build_bundle(store: Store<ConfigMap>) -> Result<Vec<u8>, BundleError> {
use bundle_error::*;
fn file_header(
config_map: &ObjectRef<ConfigMap>,
file_name: &str,
data: &[u8],
) -> Result<tar::Header, BundleError> {
fn file_header(file_path: &str, data: &[u8]) -> Result<tar::Header, BundleError> {
let mut header = tar::Header::new_gnu();
header.set_mode(0o644);
let file_size = data.len();
header.set_size(
file_size
.try_into()
.with_context(|_| FileSizeOverflowSnafu {
config_map: config_map.clone(),
file_name,
file_path,
file_size,
})?,
);
Expand All @@ -227,6 +227,16 @@ async fn build_bundle(store: Store<ConfigMap>) -> Result<Vec<u8>, BundleError> {
let mut tar = tar::Builder::new(GzEncoder::new(Vec::new(), flate2::Compression::default()));
let mut resource_versions = BTreeMap::<String, String>::new();
let mut bundle_file_paths = BTreeSet::<String>::new();

for (file_path, data) in stackable_opa_regorule_library::REGORULES {
let mut header = file_header(file_path, data.as_bytes())?;
tar.append_data(&mut header, file_path, data.as_bytes())
.context(AddStaticRuleToTarballSnafu {
file_path: *file_path,
})?;
bundle_file_paths.insert(file_path.to_string());
}

for cm in store.state() {
let ObjectMeta {
name: Some(cm_ns),
Expand All @@ -239,8 +249,8 @@ async fn build_bundle(store: Store<ConfigMap>) -> Result<Vec<u8>, BundleError> {
};
let cm_ref = ObjectRef::from_obj(&*cm);
for (file_name, data) in cm.data.iter().flatten() {
let mut header = file_header(&cm_ref, file_name, data.as_bytes())?;
let file_path = format!("configmap/{cm_ns}/{cm_name}/{file_name}");
let mut header = file_header(&file_path, data.as_bytes())?;
tar.append_data(&mut header, &file_path, data.as_bytes())
.with_context(|_| AddFileToTarballSnafu {
config_map: cm_ref.clone(),
Expand Down
13 changes: 13 additions & 0 deletions rust/regorule-library/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "stackable-opa-regorule-library"
description = "Contains Stackable's library of common regorules"
version.workspace = true
authors.workspace = true
license.workspace = true
edition.workspace = true
repository.workspace = true
publish = false

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
16 changes: 16 additions & 0 deletions rust/regorule-library/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Stackable library of shared regorules

This contains regorules that are shipped by the Stackable Data Platform (SDP) as libraries to help simplify writing authorization rules.

## What this is not

This library should *not* contain rules that only concern one SDP product. Those are the responsibility of their individual operators.
nightkr marked this conversation as resolved.
Show resolved Hide resolved

## Versioning

All regorules exposed by this library should be versioned, according to Kubernetes conventions.

This version covers _breaking changes to the interface_, not the implementation. If a proposed change breaks existing clients,

Check failure on line 13 in rust/regorule-library/README.md

View workflow job for this annotation

GitHub Actions / markdownlint

[markdownlint] rust/regorule-library/README.md#L13

MD049/emphasis-style Emphasis style [Expected: asterisk; Actual: underscore]
Raw output
rust/regorule-library/README.md:13:21 MD049/emphasis-style Emphasis style [Expected: asterisk; Actual: underscore]

Check failure on line 13 in rust/regorule-library/README.md

View workflow job for this annotation

GitHub Actions / markdownlint

[markdownlint] rust/regorule-library/README.md#L13

MD049/emphasis-style Emphasis style [Expected: asterisk; Actual: underscore]
Raw output
rust/regorule-library/README.md:13:55 MD049/emphasis-style Emphasis style [Expected: asterisk; Actual: underscore]
add a new version. Otherwise, change the latest version inline.

Ideally, old versions should be implemented on top of newer versions, rather than carry independent implementations.
NickLarsenNZ marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions rust/regorule-library/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub const REGORULES: &[(&str, &str)] = &[(
"stackable/opa/userinfo/v1.rego",
include_str!("userinfo/v1.rego"),
)];
23 changes: 23 additions & 0 deletions rust/regorule-library/src/userinfo/v1.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package stackable.opa.userinfo.v1

# Lookup by (human-readable) username
userInfoByUsername(username) := http.send({
nightkr marked this conversation as resolved.
Show resolved Hide resolved
"method": "POST",
"url": "http://127.0.0.1:9476/user",
"body": {"username": username}, <2>
"headers": {"Content-Type": "application/json"},
"raise_error": true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanted to mention that we other examples where we assert on the return code and don't use raise_error:
https://github.com/stackabletech/demos/blob/61601f8ed879c4e8ba0766ec0fe0320ee959bdb7/stacks/end-to-end-security/trino-policies.yaml#L176-L184

I don't have any preference, but other ones might have and we should agree on one.

}).body

# Lookup by stable user identifier
userInfoById(id) := http.send({
"method": "POST",
"url": "http://127.0.0.1:9476/user",
"body": {"id": id}, <3>
"headers": {"Content-Type": "application/json"},
"raise_error": true
}).body

# Lookup by context
currentUserInfoByUsername := userInfoByUsername(input.username)
currentUserInfoById := userInfoById(input.id)
Loading