Skip to content

Commit

Permalink
Merge branch 'main' into fix/authz-sm-list
Browse files Browse the repository at this point in the history
  • Loading branch information
jakedoublev committed Dec 2, 2024
2 parents 59f33d3 + 7c4c74f commit 7f6d5cf
Show file tree
Hide file tree
Showing 15 changed files with 446 additions and 95 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/action-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: "🔦 actionlint"

on:
pull_request:
branches:
- main
paths:
- '.github/workflows/**'

jobs:
actionlint:
runs-on: ubuntu-22.04
name: actionlint
permissions:
contents: read
pull-requests: write
checks: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: "Run reviewdog actionlint"
uses: reviewdog/action-actionlint@053981cb135d7a696bbeec6181d9d5fae6e07dae # v1.57.0
with:
reporter: "github-pr-review"
fail_on_error: true
88 changes: 88 additions & 0 deletions .github/workflows/release-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Build Platform Container Image

on:
release:
types: [published]


jobs:
build:
if: startsWith(github.event.release.tag_name, 'service/')
runs-on: ubuntu-22.04
permissions:
id-token: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683

- name: "Authenticate to Google Cloud (Push to Public registry)"
id: "gcp-auth"
uses: google-github-actions/auth@62cf5bd3e4211a0a0b51f2c6d6a37129d828611d
with:
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
token_format: "access_token"
create_credentials_file: false

- name: Install Cosign
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da

- name: Install Trivy
uses: aquasecurity/setup-trivy@ff1b8b060f23b650436d419b5e13f67f5d4c3087
with:
version: v0.57.1

- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb

- name: 'Docker login to Artifact Registry'
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567
with:
registry: us-docker.pkg.dev
username: oauth2accesstoken
password: ${{ steps.gcp-auth.outputs.access_token }}

- id: docker_meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
with:
images: ${{ secrets.DOCKER_REPO }}
tags: |
type=sha,format=long
type=match,pattern=service/v(\d.\d.\d),group=1,prefix=v
type=match,pattern=service/v(\d.\d),group=1,prefix=v
labels: |
org.opencontainers.image.documentation=https://docs.opentdf.io
- name: Build and Push container images
uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c
id: build-and-push
with:
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.docker_meta.outputs.tags }}

- name: Sign the images with GitHub OIDC Token
env:
DIGEST: ${{ steps.build-and-push.outputs.digest }}
TAGS: ${{ steps.docker_meta.outputs.tags }}
run: |
images=""
for tag in ${TAGS}; do
images+="${tag}@${DIGEST} "
done
# shellcheck disable=SC2086
cosign sign --yes ${images}
- name: Generate Reports
run: |
trivy image --scanners vuln --format cyclonedx --output bom-cyclonedx.json ${{ secrets.DOCKER_REPO }}@${{ steps.build-and-push.outputs.digest }}
trivy image --format spdx-json --output bom-spdx.json ${{ secrets.DOCKER_REPO }}@${{ steps.build-and-push.outputs.digest }}
trivy image --format cosign-vuln --output cosign-vuln.json ${{ secrets.DOCKER_REPO }}@${{ steps.build-and-push.outputs.digest }}
- name: Cosign Attest SBOM
run: |
cosign attest --type cyclonedx --predicate bom-cyclonedx.json '${{ secrets.DOCKER_REPO }}@${{ steps.build-and-push.outputs.digest }}'
cosign attest --type spdxjson -predicate bom-spdx.json '${{ secrets.DOCKER_REPO }}@${{ steps.build-and-push.outputs.digest }}'
cosign attest --type vuln --predicate cosign-vuln.json '${{ secrets.DOCKER_REPO }}@${{ steps.build-and-push.outputs.digest }}'
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"lib/flattening": "0.1.2",
"protocol/go": "0.2.22",
"sdk": "0.3.23",
"service": "0.4.30"
"service": "0.4.31"
}
14 changes: 14 additions & 0 deletions service/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## [0.4.31](https://github.com/opentdf/platform/compare/service/v0.4.30...service/v0.4.31) (2024-12-02)


### Features

* **kas:** collect metrics ([#1702](https://github.com/opentdf/platform/issues/1702)) ([def28d1](https://github.com/opentdf/platform/commit/def28d1984b0b111a07330a3eb59c1285206062d))
* **policy:** 1500 Attribute create with Values (one RPC Call) should employ a db transaction ([#1778](https://github.com/opentdf/platform/issues/1778)) ([90edbde](https://github.com/opentdf/platform/commit/90edbde92ea63ad488b9a6de09fcffbc7a4380de))


### Bug Fixes

* **core:** move auth interceptor to top of chain ([#1790](https://github.com/opentdf/platform/issues/1790)) ([f9f5a75](https://github.com/opentdf/platform/commit/f9f5a7545827c5d8cef7f536963e4f794a7f3f6c))
* **policy:** return fqns in list subject mappings ([#1796](https://github.com/opentdf/platform/issues/1796)) ([c0a9dda](https://github.com/opentdf/platform/commit/c0a9dda975a9384cea8efc413d567edce13f753f))

## [0.4.30](https://github.com/opentdf/platform/compare/service/v0.4.29...service/v0.4.30) (2024-11-27)


Expand Down
34 changes: 21 additions & 13 deletions service/cmd/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,29 @@ var (
panic(fmt.Errorf("could not load config: %w", err))
}

res := dbClient.AttrFqnReindex(context.Background())
cmd.Print("Namespace FQNs reindexed:\n")
for _, r := range res.Namespaces {
cmd.Printf("\t%s: %s\n", r.ID, r.Fqn)
}
ctx := context.Background()

cmd.Print("Attribute FQNs reindexed:\n")
for _, r := range res.Attributes {
cmd.Printf("\t%s: %s\n", r.ID, r.Fqn)
}
// ignore error as dbClient.AttrFqnReindex will panic on error
_ = dbClient.RunInTx(ctx, func(txClient *policydb.PolicyDBClient) error {
res := txClient.AttrFqnReindex(ctx)

cmd.Print("Attribute Value FQNs reindexed:\n")
for _, r := range res.Values {
cmd.Printf("\t%s: %s\n", r.ID, r.Fqn)
}
cmd.Print("Namespace FQNs reindexed:\n")
for _, r := range res.Namespaces {
cmd.Printf("\t%s: %s\n", r.ID, r.Fqn)
}

cmd.Print("Attribute FQNs reindexed:\n")
for _, r := range res.Attributes {
cmd.Printf("\t%s: %s\n", r.ID, r.Fqn)
}

cmd.Print("Attribute Value FQNs reindexed:\n")
for _, r := range res.Values {
cmd.Printf("\t%s: %s\n", r.ID, r.Fqn)
}

return nil
})
},
}
)
Expand Down
128 changes: 128 additions & 0 deletions service/integration/policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package integration

import (
"context"
"fmt"
"log/slog"
"testing"

"github.com/opentdf/platform/service/internal/fixtures"
"github.com/opentdf/platform/service/policy/db"
"github.com/stretchr/testify/suite"
)

type PolicyDBClientSuite struct {
suite.Suite
f fixtures.Fixtures
db fixtures.DBInterface
ctx context.Context //nolint:containedctx // context is used in the test suite
}

func (s *PolicyDBClientSuite) SetupSuite() {
s.ctx = context.Background()
c := *Config
c.DB.Schema = "text_opentdf_policy_db_client"
s.db = fixtures.NewDBInterface(c)
s.f = fixtures.NewFixture(s.db)
s.f.Provision()
}

func (s *PolicyDBClientSuite) TearDownSuite() {
slog.Info("tearing down db.PolicyDbClient test suite")
s.f.TearDown()
}

func (s *PolicyDBClientSuite) Test_RunInTx_CommitsOnSuccess() {
var (
nsName = "success.com"
attrName = fmt.Sprintf("http://%s/attr/attr_one", nsName)
attrValue = fmt.Sprintf("http://%s/attr/%s/value/attr_one_value", nsName, attrName)

nsID string
attrID string
valID string
err error
)

txErr := s.db.PolicyClient.RunInTx(s.ctx, func(txClient *db.PolicyDBClient) error {
nsID, err = txClient.Queries.CreateNamespace(s.ctx, db.CreateNamespaceParams{
Name: nsName,
})
s.Require().NoError(err)
s.Require().NotNil(nsID)

attrID, err = txClient.Queries.CreateAttribute(s.ctx, db.CreateAttributeParams{
NamespaceID: nsID,
Name: attrName,
Rule: db.AttributeDefinitionRuleALLOF,
})
s.Require().NoError(err)
s.Require().NotNil(attrID)

valID, err = txClient.Queries.CreateAttributeValue(s.ctx, db.CreateAttributeValueParams{
AttributeDefinitionID: attrID,
Value: attrValue,
})
s.Require().NoError(err)
s.Require().NotNil(valID)

return nil
})
s.Require().NoError(txErr)

ns, err := s.db.PolicyClient.GetNamespace(s.ctx, nsID)
s.Require().NoError(err)
s.Equal(nsName, ns.GetName())

attr, err := s.db.PolicyClient.GetAttribute(s.ctx, attrID)
s.Require().NoError(err)
s.Equal(attrName, attr.GetName())

attrVal, err := s.db.PolicyClient.GetAttributeValue(s.ctx, valID)
s.Require().NoError(err)
s.Equal(attrValue, attrVal.GetValue())
}

func (s *PolicyDBClientSuite) Test_RunInTx_RollsBackOnFailure() {
var (
nsName = "failure.com"
attrName = fmt.Sprintf("http://%s/attr/attr_one", nsName)

nsID string
attrID string
err error
)

txErr := s.db.PolicyClient.RunInTx(s.ctx, func(txClient *db.PolicyDBClient) error {
nsID, err = txClient.Queries.CreateNamespace(s.ctx, db.CreateNamespaceParams{
Name: nsName,
})
s.Require().NoError(err)
s.Require().NotNil(nsID)

attrID, err = txClient.Queries.CreateAttribute(s.ctx, db.CreateAttributeParams{
NamespaceID: "invalid_ns_id",
Name: attrName,
Rule: db.AttributeDefinitionRuleALLOF,
})
s.Require().Error(err)
s.Require().Zero(attrID)
return err
})
s.Require().Error(txErr)

ns, err := s.db.PolicyClient.GetNamespace(s.ctx, nsID)
s.Require().Error(err)
s.Nil(ns)

attr, err := s.db.PolicyClient.GetAttribute(s.ctx, attrID)
s.Require().Error(err)
s.Nil(attr)
}

func TestPolicySuite(t *testing.T) {
if testing.Short() {
t.Skip("skipping policy integration tests")
}
suite.Run(t, new(PolicyDBClientSuite))
}
3 changes: 3 additions & 0 deletions service/integration/subject_mappings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,14 +404,17 @@ func (s *SubjectMappingsSuite) Test_ListSubjectMappings_NoPagination_Succeeds()
for _, sm := range listed {
if sm.GetId() == fixture1.ID {
assertEqual(sm, fixture1)
s.Equal("https://example.com/attr/attr1/value/value1", sm.GetAttributeValue().GetFqn())
found1 = true
}
if sm.GetId() == fixture2.ID {
assertEqual(sm, fixture2)
s.Equal("https://example.com/attr/attr1/value/value2", sm.GetAttributeValue().GetFqn())
found2 = true
}
if sm.GetId() == fixture3.ID {
assertEqual(sm, fixture3)
s.Equal("https://example.com/attr/attr1/value/value1", sm.GetAttributeValue().GetFqn())
found3 = true
}
}
Expand Down
1 change: 1 addition & 0 deletions service/pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func (t Table) Field(field string) string {
// We can rename this but wanted to get mocks working.
type PgxIface interface {
Acquire(ctx context.Context) (*pgxpool.Conn, error)
Begin(ctx context.Context) (pgx.Tx, error)
Exec(context.Context, string, ...any) (pgconn.CommandTag, error)
QueryRow(context.Context, string, ...any) pgx.Row
Query(context.Context, string, ...any) (pgx.Rows, error)
Expand Down
3 changes: 3 additions & 0 deletions service/pkg/db/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ var (
ErrUUIDInvalid = errors.New("ErrUUIDInvalid: value not a valid UUID")
ErrMissingValue = errors.New("ErrMissingValue: value must be included")
ErrListLimitTooLarge = errors.New("ErrListLimitTooLarge: requested limit greater than configured maximum")
ErrTxBeginFailed = errors.New("ErrTxBeginFailed: failed to begin DB transaction")
ErrTxRollbackFailed = errors.New("ErrTxRollbackFailed: failed to rollback DB transaction")
ErrTxCommitFailed = errors.New("ErrTxCommitFailed: failed to commit DB transaction")
)

// Get helpful error message for PostgreSQL violation
Expand Down
Loading

0 comments on commit 7f6d5cf

Please sign in to comment.