...

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

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

     1  package services
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"fmt"
     7  	"strconv"
     8  	"testing"
     9  
    10  	"github.com/DATA-DOG/go-sqlmock"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"edge-infra.dev/pkg/edge/api/graph/mapper"
    14  	"edge-infra.dev/pkg/edge/api/graph/model"
    15  	sqlquery "edge-infra.dev/pkg/edge/api/sql"
    16  	"edge-infra.dev/pkg/edge/constants"
    17  	linkerd "edge-infra.dev/pkg/edge/linkerd"
    18  	"edge-infra.dev/pkg/lib/uuid"
    19  	"edge-infra.dev/pkg/sds/ien/topology"
    20  )
    21  
    22  const (
    23  	// test cluster edge id
    24  	clusterConfigClusterEdgeID = "1c52b9fa-1396-4ebf-a67a-23d06021774c"
    25  )
    26  
    27  var (
    28  	namespaceLogLevelsPayloadInsert = "[]"
    29  	clusterConfigRows               = sqlmock.NewRows([]string{"cluster_config_edge_id", "cluster_edge_id", "config_key", "config_value"})
    30  )
    31  
    32  var (
    33  	// valid values
    34  	validNamespace        = "fluent-operator"
    35  	validLevel            = "ALERT"
    36  	validMaximumLanOutage = int(linkerd.DefaultThickPosIdentityIssuerCertificateDurationHours)
    37  	// invalid values
    38  	invalidLogLevel         = "NONSENSE"
    39  	invalidMaximumLanOutage = 23
    40  )
    41  
    42  // Deprecated: Marked as DEPRECATED. Do not use
    43  var (
    44  	invalidL5dCertRenewal  = -1
    45  	invalidL5dCertDuration = 0
    46  	validL5dCertDuration   = int(linkerd.DefaultThinPosIdentityIssuerCertificateDurationHours)
    47  	validL5dCertRenewal    = int(linkerd.DefaultThinPosIdentityIssuerCertificateRenewBeforeHours)
    48  )
    49  
    50  type clusterConfigTests struct {
    51  	description    string
    52  	currentConfig  *model.ClusterConfig
    53  	inputConfig    *model.UpdateClusterConfig
    54  	expectedConfig *model.ClusterConfig
    55  	expectedErr    error
    56  }
    57  
    58  var (
    59  	trueValue        = true
    60  	falseValue       = false
    61  	rateLimitValid   = "4mbit"
    62  	rateLimitInvalid = "4"
    63  )
    64  
    65  var clusterCfgTestCases = []clusterConfigTests{
    66  	{
    67  		description:    "create valid default configuration",
    68  		currentConfig:  nil,
    69  		inputConfig:    &model.UpdateClusterConfig{},
    70  		expectedConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
    71  		expectedErr:    nil,
    72  	},
    73  	{
    74  		description:   "change all default cluster configuration values",
    75  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
    76  		inputConfig: &model.UpdateClusterConfig{
    77  			AcRelay:                    &falseValue,
    78  			PxeEnabled:                 &falseValue,
    79  			BootstrapAck:               &trueValue,
    80  			GatewayRateLimitingEnabled: &trueValue,
    81  			EgressGatewayEnabled:       &trueValue,
    82  			UplinkRateLimit:            &rateLimitValid,
    83  			DownlinkRateLimit:          &rateLimitValid,
    84  			ThickPos:                   &trueValue,
    85  			VpnEnabled:                 &trueValue,
    86  			ClusterLogLevel:            &validLevel,
    87  			NamespaceLogLevels: []*model.NamespaceLogLevelPayload{
    88  				{
    89  					Namespace: &validNamespace,
    90  					Level:     &validLevel,
    91  				},
    92  			},
    93  			MaximumLanOutageHours: &validMaximumLanOutage,
    94  			// TODO: Marked as DEPRECATED. Remove
    95  			LinkerdIdentityIssuerCertDuration:    &validL5dCertDuration,
    96  			LinkerdIdentityIssuerCertRenewBefore: &validL5dCertRenewal,
    97  			VncReadWriteAuthRequired:             &trueValue,
    98  			VncReadAuthRequired:                  &falseValue,
    99  		},
   100  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   101  			AcRelay:                    &falseValue,
   102  			PxeEnabled:                 &falseValue,
   103  			BootstrapAck:               &trueValue,
   104  			GatewayRateLimitingEnabled: &trueValue,
   105  			EgressGatewayEnabled:       &trueValue,
   106  			UplinkRateLimit:            &rateLimitValid,
   107  			DownlinkRateLimit:          &rateLimitValid,
   108  			ThickPos:                   &trueValue,
   109  			VpnEnabled:                 &trueValue,
   110  			ClusterLogLevel:            &validLevel,
   111  			NamespaceLogLevels: []*model.NamespaceLogLevelPayload{
   112  				{
   113  					Namespace: &validNamespace,
   114  					Level:     &validLevel,
   115  				},
   116  			},
   117  			MaximumLanOutageHours: &validMaximumLanOutage,
   118  			// TODO: Marked as DEPRECATED. Remove
   119  			LinkerdIdentityIssuerCertDuration:    &validL5dCertDuration,
   120  			LinkerdIdentityIssuerCertRenewBefore: &validL5dCertRenewal,
   121  			VncReadWriteAuthRequired:             &trueValue,
   122  			VncReadAuthRequired:                  &falseValue,
   123  		}),
   124  		expectedErr: nil,
   125  	},
   126  	{
   127  		description: "update boot options with valid configuration",
   128  		currentConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   129  			AcRelay:      &trueValue,
   130  			PxeEnabled:   &trueValue,
   131  			BootstrapAck: &falseValue,
   132  		}),
   133  		inputConfig: &model.UpdateClusterConfig{
   134  			AcRelay:      &falseValue,
   135  			PxeEnabled:   &falseValue,
   136  			BootstrapAck: &trueValue,
   137  		},
   138  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   139  			AcRelay:      &falseValue,
   140  			PxeEnabled:   &falseValue,
   141  			BootstrapAck: &trueValue,
   142  		}),
   143  		expectedErr: nil,
   144  	},
   145  	{
   146  		description:   "update egress gateway options with valid configuration",
   147  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   148  		inputConfig: &model.UpdateClusterConfig{
   149  			GatewayRateLimitingEnabled: &trueValue,
   150  			EgressGatewayEnabled:       &trueValue,
   151  			UplinkRateLimit:            &rateLimitValid,
   152  			DownlinkRateLimit:          &rateLimitValid,
   153  		},
   154  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   155  			GatewayRateLimitingEnabled: &trueValue,
   156  			EgressGatewayEnabled:       &trueValue,
   157  			UplinkRateLimit:            &rateLimitValid,
   158  			DownlinkRateLimit:          &rateLimitValid,
   159  		}),
   160  		expectedErr: nil,
   161  	},
   162  	{
   163  		description:   "invalid egress gateway bandwidth limits",
   164  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   165  		inputConfig: &model.UpdateClusterConfig{
   166  			GatewayRateLimitingEnabled: &trueValue,
   167  			EgressGatewayEnabled:       &trueValue,
   168  			UplinkRateLimit:            &rateLimitInvalid,
   169  			DownlinkRateLimit:          &rateLimitInvalid,
   170  		},
   171  		expectedConfig: nil,
   172  		expectedErr:    ErrInvalidRateLimit,
   173  	},
   174  	{
   175  		description:   "thick pos topology setting",
   176  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   177  		inputConfig: &model.UpdateClusterConfig{
   178  			ThickPos: &trueValue,
   179  		},
   180  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   181  			ThickPos: &trueValue,
   182  		}),
   183  		expectedErr: nil,
   184  	},
   185  	{
   186  		description:   "vpn enablement cluster setting",
   187  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   188  		inputConfig: &model.UpdateClusterConfig{
   189  			VpnEnabled: &trueValue,
   190  		},
   191  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   192  			VpnEnabled: &trueValue,
   193  		}),
   194  		expectedErr: nil,
   195  	},
   196  	{
   197  		description:   "valid cluster log levels",
   198  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   199  		inputConfig: &model.UpdateClusterConfig{
   200  			ClusterLogLevel: &validLevel,
   201  		},
   202  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   203  			ClusterLogLevel: &validLevel,
   204  		}),
   205  		expectedErr: nil,
   206  	},
   207  	{
   208  		description:   "invalid cluster log levels",
   209  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   210  		inputConfig: &model.UpdateClusterConfig{
   211  			ClusterLogLevel: &invalidLogLevel,
   212  		},
   213  		expectedConfig: nil,
   214  		expectedErr: &ErrInvalidLogLevel{
   215  			LogLevel: invalidLogLevel,
   216  		},
   217  	},
   218  	{
   219  		description:   "valid namespace log levels",
   220  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   221  		inputConfig: &model.UpdateClusterConfig{
   222  			NamespaceLogLevels: []*model.NamespaceLogLevelPayload{
   223  				{
   224  					Namespace: &validNamespace,
   225  					Level:     &validLevel,
   226  				},
   227  			},
   228  		},
   229  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   230  			NamespaceLogLevels: []*model.NamespaceLogLevelPayload{
   231  				{
   232  					Namespace: &validNamespace,
   233  					Level:     &validLevel,
   234  				},
   235  			},
   236  		}),
   237  		expectedErr: nil,
   238  	},
   239  	{
   240  		description:   "invalid namespace log levels",
   241  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   242  		inputConfig: &model.UpdateClusterConfig{
   243  			NamespaceLogLevels: []*model.NamespaceLogLevelPayload{
   244  				{
   245  					Namespace: &validNamespace,
   246  					Level:     &invalidLogLevel,
   247  				},
   248  			},
   249  		},
   250  		expectedConfig: nil,
   251  		expectedErr: &ErrInvalidLogLevel{
   252  			LogLevel: invalidLogLevel,
   253  		},
   254  	},
   255  	{
   256  		description:   "valid maximum lan outage duration in hours",
   257  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   258  		inputConfig: &model.UpdateClusterConfig{
   259  			MaximumLanOutageHours: &validMaximumLanOutage,
   260  		},
   261  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   262  			MaximumLanOutageHours: &validMaximumLanOutage,
   263  		}),
   264  		expectedErr: nil,
   265  	},
   266  	{
   267  		description:   "invalid maximum lan outage duration in hours",
   268  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   269  		inputConfig: &model.UpdateClusterConfig{
   270  			MaximumLanOutageHours: &invalidMaximumLanOutage,
   271  		},
   272  		expectedConfig: nil,
   273  		expectedErr:    ErrInvalidMaximumLanOutageHours,
   274  	},
   275  	// TODO: DEPRECATED test cases for linkerd identity cert. Remove
   276  	{
   277  		description:   "valid linkerd cert duration and renew",
   278  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   279  		inputConfig: &model.UpdateClusterConfig{
   280  			LinkerdIdentityIssuerCertDuration:    &validL5dCertDuration,
   281  			LinkerdIdentityIssuerCertRenewBefore: &validL5dCertRenewal,
   282  		},
   283  		expectedConfig: generateExpectedClusterConfig(&model.UpdateClusterConfig{
   284  			LinkerdIdentityIssuerCertDuration:    &validL5dCertDuration,
   285  			LinkerdIdentityIssuerCertRenewBefore: &validL5dCertRenewal,
   286  		}),
   287  		expectedErr: nil,
   288  	},
   289  	{
   290  		description:   "invalid linkerd cert duration and renewal",
   291  		currentConfig: defaultClusterConfig(clusterConfigClusterEdgeID),
   292  		inputConfig: &model.UpdateClusterConfig{
   293  			LinkerdIdentityIssuerCertDuration:    &invalidL5dCertDuration,
   294  			LinkerdIdentityIssuerCertRenewBefore: &invalidL5dCertRenewal,
   295  		},
   296  		expectedConfig: nil,
   297  		expectedErr:    topology.ErrInvalidCertificateDurationOrRenewBefore, //nolint:staticcheck // Allow existing usage of deprecated fields
   298  	},
   299  }
   300  
   301  func TestUpdateClusterConfig(t *testing.T) {
   302  	for _, test := range clusterCfgTestCases {
   303  		ctx := context.Background()
   304  		passMsg := fmt.Sprintf("PASS: %s", test.description)
   305  		failMsg := fmt.Sprintf("FAIL: %s", test.description)
   306  
   307  		db, mock, err := generateMockDB(test.currentConfig, test.expectedConfig, test.inputConfig)
   308  		require.NoError(t, err, failMsg)
   309  
   310  		service := NewClusterConfigService(db)
   311  		actualClusterCfg, err := service.UpdateClusterConfig(ctx, clusterConfigClusterEdgeID, test.inputConfig)
   312  		if test.expectedErr != nil {
   313  			require.Equal(t, test.expectedErr.Error(), err.Error(), failMsg)
   314  			t.Log(passMsg)
   315  			continue
   316  		}
   317  		require.NoError(t, err, failMsg)
   318  		require.NotNil(t, test.expectedConfig, failMsg)
   319  		require.NotNil(t, actualClusterCfg, failMsg)
   320  		require.Equal(t, *test.expectedConfig, *actualClusterCfg, failMsg)
   321  		require.NoError(t, mock.ExpectationsWereMet(), failMsg)
   322  		t.Log(passMsg)
   323  	}
   324  }
   325  
   326  // verfies that the default configuration is returned if
   327  // a new cluster configuration key is added to the api.
   328  // This ensures that older clusters that do not have the key registered
   329  // in the database yet, get the correct default values.
   330  func TestGetNewAddedKeyClusterConfig(t *testing.T) {
   331  	ctx := context.Background()
   332  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   333  	require.NoError(t, err)
   334  	defer db.Close()
   335  
   336  	mock.ExpectQuery(sqlquery.GetClusterConfig).
   337  		WithArgs(clusterConfigClusterEdgeID).
   338  		WillReturnRows(clusterConfigRows)
   339  
   340  	service := NewClusterConfigService(db)
   341  	clusterCfg, err := service.GetClusterConfig(ctx, clusterConfigClusterEdgeID)
   342  	require.NoError(t, err)
   343  	require.Equal(t, defaultClusterConfig(clusterConfigClusterEdgeID), clusterCfg)
   344  }
   345  
   346  // This is key mapper function so it needs a test case
   347  func TestNLLPToNLL(t *testing.T) {
   348  	testLogLevels := make([]*model.NamespaceLogLevelPayload, 3)
   349  
   350  	validNamespace2 := "kube-system"
   351  	validNamespace3 := "prometheus"
   352  
   353  	validLevel2 := "EMERGENCY"
   354  
   355  	testLogLevels[0] = &model.NamespaceLogLevelPayload{
   356  		Namespace: &validNamespace,
   357  		Level:     &validLevel,
   358  	}
   359  	testLogLevels[1] = &model.NamespaceLogLevelPayload{
   360  		Namespace: &validNamespace2,
   361  		Level:     &validLevel,
   362  	}
   363  	testLogLevels[2] = &model.NamespaceLogLevelPayload{
   364  		Namespace: &validNamespace3,
   365  		Level:     &validLevel2,
   366  	}
   367  
   368  	NLL := mapper.NLLPToNLL(testLogLevels)
   369  
   370  	require.Len(t, NLL, 3)
   371  }
   372  
   373  // helper to generate a mock db and assertions for ClusterConfig
   374  func generateMockDB(currentCfg, expectedCfg *model.ClusterConfig, inputCfg *model.UpdateClusterConfig) (*sql.DB, sqlmock.Sqlmock, error) {
   375  	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
   376  	if err != nil {
   377  		return nil, nil, err
   378  	}
   379  
   380  	mock.MatchExpectationsInOrder(false)
   381  	if currentCfg != nil {
   382  		mock.ExpectQuery(sqlquery.GetClusterConfig).WithArgs(clusterConfigClusterEdgeID).
   383  			WillReturnRows(clusterConfigRows.
   384  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, AcRelayKey, strconv.FormatBool(currentCfg.AcRelay)).
   385  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, PxeEnabledKey, strconv.FormatBool(currentCfg.PxeEnabled)).
   386  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, BootstrapAckKey, strconv.FormatBool(currentCfg.BootstrapAck)).
   387  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, VpnEnabledKey, strconv.FormatBool(currentCfg.VpnEnabled)).
   388  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, ThickPosKey, strconv.FormatBool(currentCfg.ThickPos)).
   389  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, GatewayRateLimitingEnabledKey, strconv.FormatBool(currentCfg.GatewayRateLimitingEnabled)).
   390  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, UplinkRateLimitKey, currentCfg.UplinkRateLimit).
   391  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, DownlinkRateLimitKey, currentCfg.DownlinkRateLimit).
   392  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, ClusterLogLevelKey, currentCfg.ClusterLogLevel).
   393  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, NamespaceLogLevelsKey, namespaceLogLevelsPayloadInsert).
   394  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, MaximumLanOutageHoursKey, strconv.FormatInt(int64(currentCfg.MaximumLanOutageHours), 10)).
   395  				//TODO: Marked as DEPRECATED. Remove
   396  				//nolint:staticcheck // Allow existing usage of deprecated fields
   397  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, constants.LinkerdIdentityIssuerCertDuration, strconv.FormatInt(int64(currentCfg.LinkerdIdentityIssuerCertDuration), 10)).
   398  				//TODO: Marked as DEPRECATED. Remove
   399  				//nolint:staticcheck // Allow existing usage of deprecated fields
   400  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, constants.LinkerdIdentityIssuerCertRenewBefore, strconv.FormatInt(int64(currentCfg.LinkerdIdentityIssuerCertRenewBefore), 10)).
   401  				AddRow(uuid.New().UUID, clusterConfigClusterEdgeID, EgressGatewayEnabledKey, strconv.FormatBool(currentCfg.EgressGatewayEnabled)))
   402  	} else {
   403  		mock.ExpectQuery(sqlquery.GetClusterConfig).WithArgs(clusterConfigClusterEdgeID).WillReturnRows(clusterConfigRows)
   404  	}
   405  
   406  	if expectedCfg == nil {
   407  		mock.ExpectBegin()
   408  		mock.ExpectCommit()
   409  		return db, mock, nil
   410  	}
   411  
   412  	mock.ExpectBegin()
   413  	if inputCfg.AcRelay != nil {
   414  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   415  			WithArgs(clusterConfigClusterEdgeID, AcRelayKey, strconv.FormatBool(expectedCfg.AcRelay), sqlmock.AnyArg()).
   416  			WillReturnResult(sqlmock.NewResult(1, 1))
   417  	}
   418  	if inputCfg.PxeEnabled != nil {
   419  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   420  			WithArgs(clusterConfigClusterEdgeID, PxeEnabledKey, strconv.FormatBool(expectedCfg.PxeEnabled), sqlmock.AnyArg()).
   421  			WillReturnResult(sqlmock.NewResult(1, 1))
   422  	}
   423  	if inputCfg.BootstrapAck != nil {
   424  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   425  			WithArgs(clusterConfigClusterEdgeID, BootstrapAckKey, strconv.FormatBool(expectedCfg.BootstrapAck), sqlmock.AnyArg()).
   426  			WillReturnResult(sqlmock.NewResult(1, 1))
   427  	}
   428  	if inputCfg.VpnEnabled != nil {
   429  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   430  			WithArgs(clusterConfigClusterEdgeID, VpnEnabledKey, strconv.FormatBool(expectedCfg.VpnEnabled), sqlmock.AnyArg()).
   431  			WillReturnResult(sqlmock.NewResult(1, 1))
   432  	}
   433  	if inputCfg.ThickPos != nil {
   434  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   435  			WithArgs(clusterConfigClusterEdgeID, ThickPosKey, strconv.FormatBool(expectedCfg.ThickPos), sqlmock.AnyArg()).
   436  			WillReturnResult(sqlmock.NewResult(1, 1))
   437  	}
   438  	if inputCfg.EgressGatewayEnabled != nil {
   439  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   440  			WithArgs(clusterConfigClusterEdgeID, EgressGatewayEnabledKey, strconv.FormatBool(expectedCfg.EgressGatewayEnabled), sqlmock.AnyArg()).
   441  			WillReturnResult(sqlmock.NewResult(1, 1))
   442  	}
   443  	if inputCfg.GatewayRateLimitingEnabled != nil {
   444  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   445  			WithArgs(clusterConfigClusterEdgeID, GatewayRateLimitingEnabledKey, strconv.FormatBool(expectedCfg.GatewayRateLimitingEnabled), sqlmock.AnyArg()).
   446  			WillReturnResult(sqlmock.NewResult(1, 1))
   447  	}
   448  	if inputCfg.UplinkRateLimit != nil {
   449  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   450  			WithArgs(clusterConfigClusterEdgeID, UplinkRateLimitKey, expectedCfg.UplinkRateLimit, sqlmock.AnyArg()).
   451  			WillReturnResult(sqlmock.NewResult(1, 1))
   452  	}
   453  	if inputCfg.DownlinkRateLimit != nil {
   454  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   455  			WithArgs(clusterConfigClusterEdgeID, DownlinkRateLimitKey, expectedCfg.DownlinkRateLimit, sqlmock.AnyArg()).
   456  			WillReturnResult(sqlmock.NewResult(1, 1))
   457  	}
   458  	if inputCfg.ClusterLogLevel != nil {
   459  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   460  			WithArgs(clusterConfigClusterEdgeID, ClusterLogLevelKey, expectedCfg.ClusterLogLevel, sqlmock.AnyArg()).
   461  			WillReturnResult(sqlmock.NewResult(1, 1))
   462  	}
   463  	if inputCfg.NamespaceLogLevels != nil {
   464  		namespaces, _ := mapper.NLLPToJSON(inputCfg.NamespaceLogLevels)
   465  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   466  			WithArgs(clusterConfigClusterEdgeID, NamespaceLogLevelsKey, namespaces, sqlmock.AnyArg()).
   467  			WillReturnResult(sqlmock.NewResult(1, 1))
   468  	}
   469  	if inputCfg.MaximumLanOutageHours != nil {
   470  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   471  			WithArgs(clusterConfigClusterEdgeID, MaximumLanOutageHoursKey, strconv.FormatInt(int64(expectedCfg.MaximumLanOutageHours), 10), sqlmock.AnyArg()).
   472  			WillReturnResult(sqlmock.NewResult(1, 1))
   473  	}
   474  	//nolint:staticcheck // Allow existing usage of deprecated fields
   475  	if inputCfg.LinkerdIdentityIssuerCertDuration != nil {
   476  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   477  			WithArgs(clusterConfigClusterEdgeID, constants.LinkerdIdentityIssuerCertDuration, strconv.FormatInt(int64(expectedCfg.LinkerdIdentityIssuerCertDuration), 10), sqlmock.AnyArg()).
   478  			WillReturnResult(sqlmock.NewResult(1, 1))
   479  	}
   480  	//nolint:staticcheck // Allow existing usage of deprecated fields
   481  	if inputCfg.LinkerdIdentityIssuerCertRenewBefore != nil {
   482  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   483  			WithArgs(clusterConfigClusterEdgeID, constants.LinkerdIdentityIssuerCertRenewBefore, strconv.FormatInt(int64(expectedCfg.LinkerdIdentityIssuerCertRenewBefore), 10), sqlmock.AnyArg()).
   484  			WillReturnResult(sqlmock.NewResult(1, 1))
   485  	}
   486  	if inputCfg.VncReadWriteAuthRequired != nil {
   487  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   488  			WithArgs(clusterConfigClusterEdgeID, VncReadWriteAuthRequired, strconv.FormatBool(*expectedCfg.VncReadWriteAuthRequired), sqlmock.AnyArg()).
   489  			WillReturnResult(sqlmock.NewResult(1, 1))
   490  	}
   491  	if inputCfg.VncReadAuthRequired != nil {
   492  		mock.ExpectExec(sqlquery.UpdateClusterConfig).
   493  			WithArgs(clusterConfigClusterEdgeID, VncReadAuthRequired, strconv.FormatBool(*expectedCfg.VncReadAuthRequired), sqlmock.AnyArg()).
   494  			WillReturnResult(sqlmock.NewResult(1, 1))
   495  	}
   496  
   497  	mock.ExpectCommit()
   498  	return db, mock, nil
   499  }
   500  
   501  // overrides the default config with expected config changes
   502  func generateExpectedClusterConfig(expectedClusterCfg *model.UpdateClusterConfig) *model.ClusterConfig {
   503  	clusterCfg := defaultClusterConfig(clusterConfigClusterEdgeID)
   504  	mapUpdateClusterConfig(clusterCfg, expectedClusterCfg)
   505  	return clusterCfg
   506  }
   507  

View as plain text