...

Source file src/edge-infra.dev/pkg/edge/api/services/clustersecrets/secret_test.go

Documentation: edge-infra.dev/pkg/edge/api/services/clustersecrets

     1  package clustersecrets
     2  
     3  import (
     4  	"context"
     5  	"database/sql/driver"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/DATA-DOG/go-sqlmock"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"edge-infra.dev/pkg/edge/api/bsl/types"
    13  	"edge-infra.dev/pkg/edge/api/graph/model"
    14  	"edge-infra.dev/pkg/edge/api/middleware"
    15  	configType "edge-infra.dev/pkg/edge/api/types"
    16  	"edge-infra.dev/pkg/sds/clustersecrets/common"
    17  )
    18  
    19  var (
    20  	mockClusterSecretEdgeID     = "4c235de1-6984-4c96-bae9-0fc35f94a020"
    21  	mockTerminalEdgeID          = "78de6c9a-5d30-4860-bd01-be751c849d7e"
    22  	clusterSecretColumns        = []string{"cluster_secret_edge_id", "cluster_secret_lease_edge_id", "secert_name", "secret_version", "secret_expire_at"}
    23  	fetchSecretVersionQueryType = []string{"expire_at", "secret_version"}
    24  	config                      = &configType.Config{
    25  		EdgeOptInSecurityCompliance: true,
    26  		EdgeMaxLeaseValidityPeriod:  "48h",
    27  	}
    28  )
    29  
    30  func TestAddClusterSecretValidityInDays(t *testing.T) {
    31  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
    32  	require.NoError(t, err)
    33  	defer db.Close()
    34  
    35  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
    36  		Username: testuser,
    37  	})
    38  	config.EdgeMaxSecretValidityPeriod = "60d"
    39  	expirationTime := time.Now().UTC().AddDate(0, 0, 60).Format(time.RFC3339)
    40  
    41  	clusterSecret := common.ClusterSecret{
    42  		SecretEdgeID: mockClusterSecretEdgeID,
    43  		LeaseEdgeID:  mockLeaseID,
    44  		Name:         "breakglass",
    45  		Version:      "1",
    46  		Type:         model.ClusterSecretTypeBreakglass,
    47  	}
    48  	mockAddClusterSecretQuery(mock, expirationTime, sqlmock.NewResult(1, 1))
    49  	clusterSecretService := NewClusterSecretService(db, nil, config)
    50  	require.NoError(t, clusterSecretService.AddClusterSecret(ctx, clusterSecret))
    51  	require.NoError(t, mock.ExpectationsWereMet())
    52  }
    53  
    54  func TestAddClusterSecretValidityInHours(t *testing.T) { //nolint
    55  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
    56  	require.NoError(t, err)
    57  	defer db.Close()
    58  
    59  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
    60  		Username: testuser,
    61  	})
    62  	config.EdgeMaxSecretValidityPeriod = "60h"
    63  	expirationTime := time.Now().UTC().Add(time.Hour * 60).Format(time.RFC3339)
    64  
    65  	clusterSecret := common.ClusterSecret{
    66  		SecretEdgeID: mockClusterSecretEdgeID,
    67  		LeaseEdgeID:  mockLeaseID,
    68  		Name:         "breakglass",
    69  		Version:      "1",
    70  		Type:         model.ClusterSecretTypeBreakglass,
    71  	}
    72  	mockAddClusterSecretQuery(mock, expirationTime, sqlmock.NewResult(1, 1))
    73  
    74  	clusterSecretService := NewClusterSecretService(db, nil, config)
    75  	require.NoError(t, clusterSecretService.AddClusterSecret(ctx, clusterSecret))
    76  	require.NoError(t, mock.ExpectationsWereMet())
    77  }
    78  
    79  func TestAddClusterSecretValidityInMins(t *testing.T) { //nolint
    80  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
    81  	require.NoError(t, err)
    82  	defer db.Close()
    83  
    84  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
    85  		Username: testuser,
    86  	})
    87  	config.EdgeMaxSecretValidityPeriod = "60m"
    88  	expirationTime := time.Now().UTC().Add(time.Minute * 60).Format(time.RFC3339)
    89  
    90  	clusterSecret := common.ClusterSecret{
    91  		SecretEdgeID: mockClusterSecretEdgeID,
    92  		LeaseEdgeID:  mockLeaseID,
    93  		Name:         "breakglass",
    94  		Version:      "1",
    95  		Type:         model.ClusterSecretTypeBreakglass,
    96  	}
    97  	mockAddClusterSecretQuery(mock, expirationTime, sqlmock.NewResult(1, 1))
    98  
    99  	clusterSecretService := NewClusterSecretService(db, nil, config)
   100  	require.NoError(t, clusterSecretService.AddClusterSecret(ctx, clusterSecret))
   101  	require.NoError(t, mock.ExpectationsWereMet())
   102  }
   103  
   104  func mockAddClusterSecretQuery(mock sqlmock.Sqlmock, expirationTime string, result driver.Result) {
   105  	mock.ExpectExec(AddClusterSecretQuery).WithArgs(mockClusterSecretEdgeID, mockLeaseID, model.ClusterSecretTypeBreakglass.String(), "1", expirationTime, time.Now().UTC().Format(time.RFC3339), time.Now().UTC().Format(time.RFC3339), model.ClusterSecretTypeBreakglass.String()).
   106  		WillReturnResult(result)
   107  }
   108  
   109  func TestFetchClusterSecret(t *testing.T) {
   110  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   111  	require.NoError(t, err)
   112  	defer db.Close()
   113  
   114  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
   115  		Username: testuser,
   116  	})
   117  	expirationTime := time.Now().UTC().AddDate(0, 0, 60).Format(time.RFC3339)
   118  	mockFetchClusterSecret(mock, expirationTime)
   119  
   120  	clusterSecretService := NewClusterSecretService(db, nil, config)
   121  	clusterSecret, err := clusterSecretService.FetchClusterSecret(ctx, mockClusterEdgeID, model.ClusterSecretTypeBreakglass)
   122  	require.NoError(t, err)
   123  	require.Equal(t, mockClusterSecretEdgeID, clusterSecret.SecretEdgeID)
   124  	require.Equal(t, mockLeaseID, clusterSecret.LeaseEdgeID)
   125  	require.Equal(t, "os-user-store", clusterSecret.Name)
   126  	require.Equal(t, expirationTime, clusterSecret.ExpirationTime)
   127  	require.Equal(t, model.ClusterSecretTypeBreakglass, clusterSecret.Type)
   128  	require.Equal(t, "1", clusterSecret.Version)
   129  	require.NoError(t, mock.ExpectationsWereMet())
   130  }
   131  
   132  func mockFetchClusterSecret(mock sqlmock.Sqlmock, expirationTime string) {
   133  	rows := mock.NewRows(clusterSecretColumns).AddRow(mockClusterSecretEdgeID, mockLeaseID, "os-user-store", "1", expirationTime)
   134  	mock.ExpectQuery(FetchClusterSecretQuery).WithArgs(mockClusterEdgeID, model.ClusterSecretTypeBreakglass).WillReturnRows(rows)
   135  }
   136  
   137  func TestUpdateClusterSecret(t *testing.T) {
   138  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   139  	require.NoError(t, err)
   140  	defer db.Close()
   141  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
   142  		Username: testuser,
   143  	})
   144  	config.EdgeMaxSecretValidityPeriod = "60d"
   145  	expirationTime := time.Now().UTC().AddDate(0, 0, 60).Format(time.RFC3339)
   146  	mockUpdateClusterSecret(mock, "1", expirationTime, sqlmock.NewResult(1, 1))
   147  
   148  	clusterSecretService := NewClusterSecretService(db, nil, config)
   149  	require.NoError(t, clusterSecretService.UpdateClusterSecret(ctx, mockClusterSecretEdgeID, model.ClusterSecretTypeBreakglass, "1"))
   150  	require.NoError(t, mock.ExpectationsWereMet())
   151  }
   152  
   153  func mockUpdateClusterSecret(mock sqlmock.Sqlmock, version string, expirationTime string, result driver.Result) {
   154  	mock.ExpectExec(UpdateClusterSecretQuery).WithArgs(expirationTime, version, mockClusterSecretEdgeID, model.ClusterSecretTypeBreakglass).
   155  		WillReturnResult(result)
   156  }
   157  
   158  func TestFetchClusterSecretVersions(t *testing.T) {
   159  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   160  	require.NoError(t, err)
   161  	defer db.Close()
   162  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
   163  		Username: testuser,
   164  	})
   165  	expirationTime := time.Now().UTC().AddDate(0, 0, 30).Format(time.RFC3339)
   166  	mockFetchClusterSecretVersions(mock, expirationTime, "5")
   167  
   168  	clusterSecretService := NewClusterSecretService(db, nil, config)
   169  	versionInfo, err := clusterSecretService.FetchClusterSecretVersions(ctx, mockClusterEdgeID, model.ClusterSecretTypeBreakglass)
   170  	require.NoError(t, err)
   171  	require.Equal(t, versionInfo[0].Version, "5")
   172  	require.Equal(t, versionInfo[0].ExpiresAt, expirationTime)
   173  	require.Equal(t, versionInfo[1].Version, "2")
   174  	require.Equal(t, versionInfo[1].ExpiresAt, "expires once latest version syncs to terminal(s) 78de6c9a-5d30-4860-bd01-be751c849d7e")
   175  	require.NoError(t, mock.ExpectationsWereMet())
   176  }
   177  
   178  func mockFetchClusterSecretVersions(mock sqlmock.Sqlmock, expirationTime string, version string) {
   179  	rows := mock.NewRows(fetchSecretVersionQueryType).AddRow(expirationTime, version)
   180  	mock.ExpectQuery(FetchSecretVersionInfoQuery).WithArgs(model.ClusterSecretTypeBreakglass, mockClusterEdgeID).WillReturnRows(rows)
   181  	rows = mock.NewRows([]string{"value"}).AddRow(`["os-user-store","2","78de6c9a-5d30-4860-bd01-be751c849d7e", "grub2store","1","78de6c9a-5d30-4860-bd01-be751c849d7e"]`)
   182  	mock.ExpectQuery(FetchLatestTerminalClusterSecretsQuery).WithArgs(mockClusterEdgeID).WillReturnRows(rows)
   183  }
   184  
   185  func TestFetchLatestTerminalClusterSecrets(t *testing.T) {
   186  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   187  	require.NoError(t, err)
   188  	defer db.Close()
   189  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
   190  		Username: testuser,
   191  	})
   192  	mockFetchLatestTerminalClusterSecrets(mock)
   193  
   194  	clusterSecretService := NewClusterSecretService(db, nil, config)
   195  	terminalClusterSecrets, err := clusterSecretService.FetchLatestTerminalClusterSecrets(ctx, mockClusterEdgeID)
   196  	require.NoError(t, err)
   197  	require.Equal(t, 2, len(terminalClusterSecrets))
   198  	require.Equal(t, mockTerminalEdgeID, terminalClusterSecrets[0].TerminalEdgeID)
   199  	require.Equal(t, "os-user-store", terminalClusterSecrets[0].SecretType)
   200  	require.Equal(t, "2", terminalClusterSecrets[0].Version)
   201  	require.NoError(t, mock.ExpectationsWereMet())
   202  }
   203  
   204  func mockFetchLatestTerminalClusterSecrets(mock sqlmock.Sqlmock) {
   205  	rows := mock.NewRows([]string{"value"}).AddRow(`["os-user-store","2","78de6c9a-5d30-4860-bd01-be751c849d7e", "grub2store","2","78de6c9a-5d30-4860-bd01-be751c849d7e"]`)
   206  	mock.ExpectQuery(FetchLatestTerminalClusterSecretsQuery).WithArgs(mockClusterEdgeID).WillReturnRows(rows)
   207  }
   208  
   209  func TestExpireClusterSecret(t *testing.T) {
   210  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   211  	require.NoError(t, err)
   212  	defer db.Close()
   213  	ctx := middleware.NewContext(context.Background(), &types.AuthUser{
   214  		Username: testuser,
   215  	})
   216  	expirationTime := time.Now().Format(time.RFC3339)
   217  	mockExpireClusterSecret(mock, expirationTime, sqlmock.NewResult(2, 2))
   218  
   219  	clusterSecretService := NewClusterSecretService(db, nil, config)
   220  	require.NoError(t, clusterSecretService.ExpireClusterSecrets(ctx, mockLeaseID))
   221  	require.NoError(t, mock.ExpectationsWereMet())
   222  }
   223  
   224  func mockExpireClusterSecret(mock sqlmock.Sqlmock, expirationTime string, result driver.Result) {
   225  	mock.ExpectExec(ExpireClusterSecretsQuery).WithArgs(expirationTime, mockLeaseID).
   226  		WillReturnResult(result)
   227  }
   228  

View as plain text