Skip to content

Commit

Permalink
feat: add ability to distribute artifacts through archivista (#188)
Browse files Browse the repository at this point in the history
* feat: add ability to distribute artifacts through archivista

Support use case of private archivista deployments where getting witness
may be difficult. Also support use case of folks having custom builds of
witness to distribute. Extended to be a more generic artifact store for
additional tools.

---------

Signed-off-by: Mikhail Swift <mikhail@testifysec.com>
  • Loading branch information
mikhailswift authored Feb 7, 2024
1 parent c7fbca6 commit bada510
Show file tree
Hide file tree
Showing 10 changed files with 1,276 additions and 17 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Archivista is configured through environment variables currently.
| ARCHIVISTA_SQL_STORE_CONNECTION_STRING | root:example@tcp(db)/testify | SQL store connection string |
| ARCHIVISTA_STORAGE_BACKEND | | Backend to use for attestation storage. Options are FILE, BLOB, or empty string for disabled. |
| ARCHIVISTA_FILE_SERVE_ON | | What address to serve files on. Only valid when using FILE storage backend. |
| ARCHIVISTA_FILE_DIR | /tmp/archivista/ | Directory to store and serve files. Only valid when using FILE storage backend. |
| ARCHIVISTA_FILE_DIR | /tmp/archivista/ | Directory to store and serve files. Only valid when using FILE storage backend. |
| ARCHIVISTA_BLOB_STORE_ENDPOINT | 127.0.0.1:9000 | URL endpoint for blob storage. Only valid when using BLOB storage backend. |
| ARCHIVISTA_BLOB_STORE_CREDENTIAL_TYPE | | Blob store credential type. Options are IAM or ACCESS_KEY. |
| ARCHIVISTA_BLOB_STORE_ACCESS_KEY_ID | | Blob store access key id. Only valid when using BLOB storage backend. |
Expand All @@ -89,6 +89,8 @@ Archivista is configured through environment variables currently.
| ARCHIVISTA_BLOB_STORE_BUCKET_NAME | | Bucket to use for storage. Only valid when using BLOB storage backend. |
| ARCHIVISTA_ENABLE_GRAPHQL | TRUE | Enable GraphQL Endpoint |
| ARCHIVISTA_GRAPHQL_WEB_CLIENT_ENABLE | TRUE | Enable GraphiQL, the GraphQL web client |
| ARCHIVISTA_ENABLE_ARTIFACT_STORE | FALSE | Enable Artifact Store Endpoints |
| ARCHIVISTA_ARTIFACT_STORE_CONFIG | /tmp/artifacts/config.yaml | Location of the config describing available artifacts |


## Using Archivista
Expand Down
20 changes: 19 additions & 1 deletion cmd/archivista/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

nested "github.com/antonfisher/nested-logrus-formatter"
"github.com/gorilla/handlers"
"github.com/in-toto/archivista/internal/artifactstore"
"github.com/in-toto/archivista/internal/config"
"github.com/in-toto/archivista/internal/metadatastorage/sqlstore"
"github.com/in-toto/archivista/internal/objectstorage/blobstore"
Expand All @@ -56,6 +57,7 @@ func main() {
defer cancel()

startTime := time.Now()
serverOpts := make([]server.Option, 0)

logrus.Infof("executing phase 1: get config from environment (time since start: %s)", time.Since(startTime))
now := time.Now()
Expand All @@ -81,6 +83,7 @@ func main() {
if err != nil {
logrus.Fatalf("error initializing storage clients: %+v", err)
}
serverOpts = append(serverOpts, server.WithObjectStore(fileStore))

entClient, err := sqlstore.NewEntClient(
cfg.SQLStoreBackend,
Expand All @@ -96,6 +99,7 @@ func main() {
if err != nil {
logrus.Fatalf("error initializing mysql client: %+v", err)
}
serverOpts = append(serverOpts, server.WithMetadataStore(sqlStore))

logrus.WithField("duration", time.Since(now)).Infof("completed phase 3: initializing storage clients")

Expand All @@ -104,9 +108,23 @@ func main() {
// ********************************************************************************
now = time.Now()

// initialize the artifact store
if cfg.EnableArtifactStore {
wds, err := artifactstore.New(artifactstore.WithConfigFile(cfg.ArtifactStoreConfig))
if err != nil {
logrus.Fatalf("could not create the artifact store: %+v", err)
}

serverOpts = append(serverOpts, server.WithArtifactStore(wds))
}

// initialize the server
sqlClient := sqlStore.GetClient()
server := server.New(sqlStore, fileStore, cfg, sqlClient)
serverOpts = append(serverOpts, server.WithEntSqlClient(sqlClient))
server, err := server.New(cfg, serverOpts...)
if err != nil {
logrus.Fatalf("could not create archivista server: %+v", err)
}

listenAddress := cfg.ListenOn
listenAddress = strings.ToLower(strings.TrimSpace(listenAddress))
Expand Down
221 changes: 221 additions & 0 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,194 @@ const docTemplate = `{
}
}
},
"/v1/artifacts": {
"get": {
"description": "retrieves details about all available Artifacts",
"produces": [
"application/json"
],
"tags": [
"Artifacts"
],
"summary": "List all Artifacts",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/artifactstore.Artifact"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "string"
}
}
}
}
},
"/v1/artifacts/{name}": {
"get": {
"description": "retrieves details about all available versions of a specified artifact",
"produces": [
"application/json"
],
"tags": [
"Artifacts"
],
"summary": "List Artifact Versions",
"parameters": [
{
"type": "string",
"description": "artifact name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/artifactstore.Version"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "string"
}
}
}
}
},
"/v1/artifacts/{name}/{version}": {
"get": {
"description": "retrieves details about a specified version of an artifact",
"produces": [
"application/json"
],
"tags": [
"Artifacts"
],
"summary": "Artifact Version Details",
"parameters": [
{
"type": "string",
"description": "artifact name",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "version of artifact",
"name": "version",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/artifactstore.Version"
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "objecpec"
}
}
}
}
},
"/v1/download/artifact/{name}/{version}/{distribution}": {
"get": {
"description": "downloads a specified distribution of an artifact",
"produces": [
"application/octet-stream"
],
"tags": [
"Artifacts"
],
"summary": "Download Artifact",
"parameters": [
{
"type": "string",
"description": "name of artifact",
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "version of artifact to download",
"name": "version",
"in": "path",
"required": true
},
{
"type": "string",
"description": "distribution of artifact to download",
"name": "distribution",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "string"
}
}
}
}
},
"/v1/download/{gitoid}": {
"get": {
"description": "download an attestation",
Expand Down Expand Up @@ -178,6 +366,39 @@ const docTemplate = `{
"archivista.Resolver": {
"type": "object"
},
"artifactstore.Artifact": {
"type": "object",
"properties": {
"versions": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/artifactstore.Version"
}
}
}
},
"artifactstore.Distribution": {
"type": "object",
"properties": {
"sha256digest": {
"type": "string"
}
}
},
"artifactstore.Version": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"distributions": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/artifactstore.Distribution"
}
}
}
},
"dsse.Envelope": {
"type": "object",
"properties": {
Expand Down
Loading

0 comments on commit bada510

Please sign in to comment.