Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
57 changes: 57 additions & 0 deletions migrations/artifact/artifact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package artifact

import (
"errors"
"fmt"
"io"

"github.com/Masterminds/semver/v3"
metadata "github.com/opentdf/otdfctl/migrations/artifact/metadata"
artifactv1 "github.com/opentdf/otdfctl/migrations/artifact/v1"
)

const CurrentSchemaVersion = artifactv1.SchemaVersion

var (
currentSchemaVersion = semver.MustParse(CurrentSchemaVersion)

ErrInvalidSchemaVersion = errors.New("invalid artifact schema version")
ErrUnsupportedSchemaVersion = errors.New("unsupported artifact schema version")
ErrNotImplemented = errors.New("not implemented")
)

type ArtifactOpts struct {
Version *semver.Version
Writer io.Writer
}

type Artifact interface {
Build() error
Commit() error
Metadata() metadata.ArtifactMetadata
Summary() ([]byte, error)
Write() error
}

func New(opts ArtifactOpts) (Artifact, error) {
version := opts.Version
if version == nil {
version = currentSchemaVersion
}

doc, err := newDocumentForVersion(version, opts.Writer)
if err != nil {
return nil, err
}

return doc, nil
}

func newDocumentForVersion(version *semver.Version, writer io.Writer) (Artifact, error) {
switch version.Major() {
case 1:
return artifactv1.New(writer)
default:
return nil, fmt.Errorf("%w: %s", ErrUnsupportedSchemaVersion, version.Original())
}
}
76 changes: 76 additions & 0 deletions migrations/artifact/artifact_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package artifact

import (
"bytes"
"testing"

"github.com/Masterminds/semver/v3"
artifactmetadata "github.com/opentdf/otdfctl/migrations/artifact/metadata"
artifactv1 "github.com/opentdf/otdfctl/migrations/artifact/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNewRejectsUnsupportedSchemaVersion(t *testing.T) {
t.Parallel()

_, err := New(ArtifactOpts{
Version: semver.MustParse("v2.0.0"),
})
require.ErrorIs(t, err, ErrUnsupportedSchemaVersion)
}

func TestNewRejectsNilWriter(t *testing.T) {
t.Parallel()

_, err := New(ArtifactOpts{})
require.ErrorIs(t, err, artifactv1.ErrNilWriter)
}

func TestNewDefaultsCurrentVersion(t *testing.T) {
t.Parallel()

var buf bytes.Buffer
doc, err := New(ArtifactOpts{Writer: &buf})
require.NoError(t, err)

require.NoError(t, doc.Write())
assert.Contains(t, buf.String(), `"schema": "v1.0.0"`)
assert.Contains(t, buf.String(), `"name": "`+artifactmetadata.ArtifactName+`"`)
}

func TestArtifactSummaryReturnsEncodedJSON(t *testing.T) {
t.Parallel()

var buf bytes.Buffer
doc, err := New(ArtifactOpts{Writer: &buf})
require.NoError(t, err)

summary, err := doc.Summary()
require.NoError(t, err)
assert.JSONEq(t, `{
"counts": {
"namespaces": 0,
"actions": 0,
"subject_condition_sets": 0,
"subject_mappings": 0,
"registered_resources": 0,
"obligation_triggers": 0,
"skipped": 0
}
}`, string(summary))
}

func TestArtifactBuildAndCommitAreNotImplemented(t *testing.T) {
t.Parallel()

var buf bytes.Buffer
doc, err := New(ArtifactOpts{Writer: &buf})
require.NoError(t, err)

buildErr := doc.Build()
require.ErrorIs(t, buildErr, artifactv1.ErrNotImplemented)

commitErr := doc.Commit()
require.ErrorIs(t, commitErr, artifactv1.ErrNotImplemented)
}
50 changes: 50 additions & 0 deletions migrations/artifact/metadata/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package metadata

import (
"time"

"github.com/Masterminds/semver/v3"
)

const ArtifactName = "policy-migration"

type ArtifactMetadata struct {
SchemaValue string `json:"schema"`
NameValue string `json:"name"`
RunIDValue string `json:"run_id"`
CreatedAtValue time.Time `json:"created_at"`
}

func New(schema, runID string, createdAt time.Time) ArtifactMetadata {
return ArtifactMetadata{
SchemaValue: schema,
NameValue: ArtifactName,
RunIDValue: runID,
CreatedAtValue: createdAt,
}
}

func (m ArtifactMetadata) Schema() *semver.Version {
if m.SchemaValue == "" {
return nil
}

version, err := semver.NewVersion(m.SchemaValue)
if err != nil {
return nil
}

return version
}

func (m ArtifactMetadata) Name() string {
return m.NameValue
}

func (m ArtifactMetadata) RunID() string {
return m.RunIDValue
}

func (m ArtifactMetadata) CreatedAt() time.Time {
return m.CreatedAtValue
}
Loading
Loading