Export metadata export api

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/10397
GitOrigin-RevId: 9545145248557371f05d2efe646151667cc20909
This commit is contained in:
Varun Dey 2023-10-25 20:54:37 +00:00 committed by hasura-bot
parent b28d6470e3
commit d6e5005cb5
5 changed files with 172 additions and 3 deletions

View File

@ -4,21 +4,21 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/commands"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/internal/projectmetadata"
"io"
"io/ioutil"
)
type modeHandler interface {
Apply(*ProjectMetadata) (io.Reader, error)
Diff(*ProjectMetadata) (io.Reader, error)
Parse(*ProjectMetadata) (io.Reader, error)
Export(*ProjectMetadata) (io.Reader, error)
}
func getModeHandler(mode cli.MetadataMode) modeHandler {
@ -77,6 +77,16 @@ func (m *metadataModeDirectoryHandler) Diff(p *ProjectMetadata) (io.Reader, erro
return r, nil
}
func (m *metadataModeDirectoryHandler) Export(p *ProjectMetadata) (io.Reader, error) {
var op errors.Op = "metadata.metadataModeDirectoryHandler.Export"
r, err := export(p, p.ec.MetadataMode)
if err != nil {
return nil, errors.E(op, err)
}
return r, nil
}
func diff(p *ProjectMetadata) (io.Reader, error) {
var op errors.Op = "metadata.diff"
w := new(bytes.Buffer)
@ -121,6 +131,15 @@ func (m *metadataModeJSONHandler) Diff(p *ProjectMetadata) (io.Reader, error) {
return r, nil
}
func (m *metadataModeJSONHandler) Export(p *ProjectMetadata) (io.Reader, error) {
var op errors.Op = "metadata.metadataModeDirectoryHandler.Export"
r, err := export(p, p.ec.MetadataMode)
if err != nil {
return nil, errors.E(op, err)
}
return r, nil
}
type metadataModeYAMLHandler struct{}
func (m *metadataModeYAMLHandler) Apply(p *ProjectMetadata) (io.Reader, error) {
@ -154,6 +173,15 @@ func (m *metadataModeYAMLHandler) Diff(p *ProjectMetadata) (io.Reader, error) {
return r, nil
}
func (m *metadataModeYAMLHandler) Export(p *ProjectMetadata) (io.Reader, error) {
var op errors.Op = "metadata.metadataModeYAMLHandler.Export"
r, err := export(p, p.ec.MetadataMode)
if err != nil {
return nil, errors.E(op, err)
}
return r, nil
}
func apply(p *ProjectMetadata, mode cli.MetadataMode) (io.Reader, error) {
var op errors.Op = "metadata.apply"
var localMetadataBytes []byte
@ -194,3 +222,26 @@ func apply(p *ProjectMetadata, mode cli.MetadataMode) (io.Reader, error) {
}
return b, nil
}
func export(p *ProjectMetadata, mode cli.MetadataMode) (io.Reader, error) {
var op errors.Op = "metadata.export"
metadata, err := p.ec.APIClient.V1Metadata.ExportMetadata()
if err != nil {
return nil, errors.E(op, fmt.Errorf("exporting metadata from server: %w", err))
}
var metadataBytes []byte
metadataBytes, err = ioutil.ReadAll(metadata)
if err != nil {
return nil, errors.E(op, fmt.Errorf("reading metadata from response: %w", err))
}
if mode == cli.MetadataModeYAML {
metadataBytes, err = metadatautil.JSONToYAML(metadataBytes)
if err != nil {
return nil, errors.E(op, fmt.Errorf("parsing metadata to yaml: %w", err))
}
}
return bytes.NewReader(metadataBytes), nil
}

View File

@ -68,6 +68,16 @@ func (p *ProjectMetadata) Diff() (io.Reader, error) {
return r, nil
}
// Export will return the server metadata
func (p *ProjectMetadata) Export() (io.Reader, error) {
var op errors.Op = "metadata.ProjectMetadata.Export"
r, err := getModeHandler(p.ec.MetadataMode).Export(p)
if err != nil {
return nil, errors.E(op, err)
}
return r, nil
}
type ProjectMetadataOption func(*ProjectMetadata)
func WithAdminSecret(adminSecret string) ProjectMetadataOption {

View File

@ -475,3 +475,70 @@ func TestProjectMetadata_GetInconsistentMetadata(t *testing.T) {
})
}
}
func TestProjectMetadata_Export(t *testing.T) {
port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage)
hgeEndpoint := fmt.Sprintf("http://localhost:%s", port)
defer teardown()
type fields struct {
projectDirectory string
}
tests := []struct {
name string
fields fields
want string
wantErr bool
assertErr require.ErrorAssertionFunc
}{
{
"can export metadata from config",
fields{
projectDirectory: "testdata/projectv2",
},
"testdata/metadata_export_test/config-v2.json",
false,
require.NoError,
},
{
"can export json metadata from config in filemode (json)",
fields{
projectDirectory: "testdata/projectv2-file-mode-json",
},
"testdata/metadata_export_test/config-v2.json",
false,
require.NoError,
},
{
"can export yaml metadata from config in filemode (yaml)",
fields{
projectDirectory: "testdata/projectv2-file-mode-yaml",
},
"testdata/metadata_export_test/config-v2.yaml",
false,
require.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p, err := NewProjectMetadata(tt.fields.projectDirectory, WithEndpoint(hgeEndpoint), WithAdminSecret(testutil.TestAdminSecret))
require.NoError(t, err)
got, err := p.Export()
tt.assertErr(t, err)
if tt.wantErr {
return
}
gotb, err := ioutil.ReadAll(got)
require.NoError(t, err)
// uncomment to update golden file
//require.NoError(t, ioutil.WriteFile(tt.wantGolden, gotb, os.ModePerm))
wantb, err := ioutil.ReadFile(tt.want)
require.NoError(t, err)
require.Equal(t, string(wantb), string(gotb))
})
}
}

View File

@ -0,0 +1,25 @@
{
"version": 3,
"sources": [
{
"name": "default",
"kind": "postgres",
"tables": [],
"configuration": {
"connection_info": {
"database_url": {
"from_env": "HASURA_GRAPHQL_DATABASE_URL"
},
"isolation_level": "read-committed",
"pool_settings": {
"connection_lifetime": 600,
"idle_timeout": 180,
"max_connections": 50,
"retries": 1
},
"use_prepared_statements": true
}
}
}
]
}

View File

@ -0,0 +1,16 @@
version: 3
sources:
- name: default
kind: postgres
tables: []
configuration:
connection_info:
database_url:
from_env: HASURA_GRAPHQL_DATABASE_URL
isolation_level: read-committed
pool_settings:
connection_lifetime: 600
idle_timeout: 180
max_connections: 50
retries: 1
use_prepared_statements: true