github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/kinesis/kinesis_integration_test.go (about)

     1  package kinesis_test
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"io"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/fastly/go-fastly/v9/fastly"
    11  
    12  	"github.com/fastly/cli/pkg/app"
    13  	"github.com/fastly/cli/pkg/global"
    14  	"github.com/fastly/cli/pkg/mock"
    15  	"github.com/fastly/cli/pkg/testutil"
    16  )
    17  
    18  func TestKinesisCreate(t *testing.T) {
    19  	args := testutil.Args
    20  	scenarios := []struct {
    21  		args       []string
    22  		api        mock.API
    23  		wantError  string
    24  		wantOutput string
    25  	}{
    26  		{
    27  			args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --region us-east-1 --secret-key bar --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"),
    28  			api: mock.API{
    29  				ListVersionsFn: testutil.ListVersions,
    30  				CloneVersionFn: testutil.CloneVersionResult(4),
    31  			},
    32  			wantError: "error parsing arguments: the --access-key and --secret-key flags are mutually exclusive with the --iam-role flag",
    33  		},
    34  		{
    35  			args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --region us-east-1 --access-key foo --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"),
    36  			api: mock.API{
    37  				ListVersionsFn: testutil.ListVersions,
    38  				CloneVersionFn: testutil.CloneVersionResult(4),
    39  			},
    40  			wantError: "error parsing arguments: the --access-key and --secret-key flags are mutually exclusive with the --iam-role flag",
    41  		},
    42  		{
    43  			args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --region us-east-1 --access-key foo --secret-key bar --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"),
    44  			api: mock.API{
    45  				ListVersionsFn: testutil.ListVersions,
    46  				CloneVersionFn: testutil.CloneVersionResult(4),
    47  			},
    48  			wantError: "error parsing arguments: the --access-key and --secret-key flags are mutually exclusive with the --iam-role flag",
    49  		},
    50  		{
    51  			args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --access-key foo --secret-key bar --region us-east-1 --autoclone"),
    52  			api: mock.API{
    53  				ListVersionsFn:  testutil.ListVersions,
    54  				CloneVersionFn:  testutil.CloneVersionResult(4),
    55  				CreateKinesisFn: createKinesisOK,
    56  			},
    57  			wantOutput: "Created Kinesis logging endpoint log (service 123 version 4)",
    58  		},
    59  		{
    60  			args: args("logging kinesis create --service-id 123 --version 1 --name log --stream-name log --access-key foo --secret-key bar --region us-east-1 --autoclone"),
    61  			api: mock.API{
    62  				ListVersionsFn:  testutil.ListVersions,
    63  				CloneVersionFn:  testutil.CloneVersionResult(4),
    64  				CreateKinesisFn: createKinesisError,
    65  			},
    66  			wantError: errTest.Error(),
    67  		},
    68  		{
    69  			args: args("logging kinesis create --service-id 123 --version 1 --name log2 --stream-name log --region us-east-1 --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"),
    70  			api: mock.API{
    71  				ListVersionsFn:  testutil.ListVersions,
    72  				CloneVersionFn:  testutil.CloneVersionResult(4),
    73  				CreateKinesisFn: createKinesisOK,
    74  			},
    75  			wantOutput: "Created Kinesis logging endpoint log2 (service 123 version 4)",
    76  		},
    77  		{
    78  			args: args("logging kinesis create --service-id 123 --version 1 --name log2 --stream-name log --region us-east-1 --iam-role arn:aws:iam::123456789012:role/KinesisAccess --autoclone"),
    79  			api: mock.API{
    80  				ListVersionsFn:  testutil.ListVersions,
    81  				CloneVersionFn:  testutil.CloneVersionResult(4),
    82  				CreateKinesisFn: createKinesisError,
    83  			},
    84  			wantError: errTest.Error(),
    85  		},
    86  	}
    87  	for testcaseIdx := range scenarios {
    88  		testcase := &scenarios[testcaseIdx]
    89  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
    90  			var stdout bytes.Buffer
    91  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
    92  				opts := testutil.MockGlobalData(testcase.args, &stdout)
    93  				opts.APIClientFactory = mock.APIClient(testcase.api)
    94  				return opts, nil
    95  			}
    96  			err := app.Run(testcase.args, nil)
    97  			testutil.AssertErrorContains(t, err, testcase.wantError)
    98  			testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput)
    99  		})
   100  	}
   101  }
   102  
   103  func TestKinesisList(t *testing.T) {
   104  	args := testutil.Args
   105  	scenarios := []struct {
   106  		args       []string
   107  		api        mock.API
   108  		wantError  string
   109  		wantOutput string
   110  	}{
   111  		{
   112  			args: args("logging kinesis list --service-id 123 --version 1"),
   113  			api: mock.API{
   114  				ListVersionsFn: testutil.ListVersions,
   115  				ListKinesisFn:  listKinesesOK,
   116  			},
   117  			wantOutput: listKinesesShortOutput,
   118  		},
   119  		{
   120  			args: args("logging kinesis list --service-id 123 --version 1 --verbose"),
   121  			api: mock.API{
   122  				ListVersionsFn: testutil.ListVersions,
   123  				ListKinesisFn:  listKinesesOK,
   124  			},
   125  			wantOutput: listKinesesVerboseOutput,
   126  		},
   127  		{
   128  			args: args("logging kinesis list --service-id 123 --version 1 -v"),
   129  			api: mock.API{
   130  				ListVersionsFn: testutil.ListVersions,
   131  				ListKinesisFn:  listKinesesOK,
   132  			},
   133  			wantOutput: listKinesesVerboseOutput,
   134  		},
   135  		{
   136  			args: args("logging kinesis --verbose list --service-id 123 --version 1"),
   137  			api: mock.API{
   138  				ListVersionsFn: testutil.ListVersions,
   139  				ListKinesisFn:  listKinesesOK,
   140  			},
   141  			wantOutput: listKinesesVerboseOutput,
   142  		},
   143  		{
   144  			args: args("logging -v kinesis list --service-id 123 --version 1"),
   145  			api: mock.API{
   146  				ListVersionsFn: testutil.ListVersions,
   147  				ListKinesisFn:  listKinesesOK,
   148  			},
   149  			wantOutput: listKinesesVerboseOutput,
   150  		},
   151  		{
   152  			args: args("logging kinesis list --service-id 123 --version 1"),
   153  			api: mock.API{
   154  				ListVersionsFn: testutil.ListVersions,
   155  				ListKinesisFn:  listKinesesError,
   156  			},
   157  			wantError: errTest.Error(),
   158  		},
   159  	}
   160  	for testcaseIdx := range scenarios {
   161  		testcase := &scenarios[testcaseIdx]
   162  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   163  			var stdout bytes.Buffer
   164  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   165  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   166  				opts.APIClientFactory = mock.APIClient(testcase.api)
   167  				return opts, nil
   168  			}
   169  			err := app.Run(testcase.args, nil)
   170  			testutil.AssertErrorContains(t, err, testcase.wantError)
   171  			testutil.AssertString(t, testcase.wantOutput, stdout.String())
   172  		})
   173  	}
   174  }
   175  
   176  func TestKinesisDescribe(t *testing.T) {
   177  	args := testutil.Args
   178  	scenarios := []struct {
   179  		args       []string
   180  		api        mock.API
   181  		wantError  string
   182  		wantOutput string
   183  	}{
   184  		{
   185  			args:      args("logging kinesis describe --service-id 123 --version 1"),
   186  			wantError: "error parsing arguments: required flag --name not provided",
   187  		},
   188  		{
   189  			args: args("logging kinesis describe --service-id 123 --version 1 --name logs"),
   190  			api: mock.API{
   191  				ListVersionsFn: testutil.ListVersions,
   192  				GetKinesisFn:   getKinesisError,
   193  			},
   194  			wantError: errTest.Error(),
   195  		},
   196  		{
   197  			args: args("logging kinesis describe --service-id 123 --version 1 --name logs"),
   198  			api: mock.API{
   199  				ListVersionsFn: testutil.ListVersions,
   200  				GetKinesisFn:   getKinesisOK,
   201  			},
   202  			wantOutput: describeKinesisOutput,
   203  		},
   204  	}
   205  	for testcaseIdx := range scenarios {
   206  		testcase := &scenarios[testcaseIdx]
   207  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   208  			var stdout bytes.Buffer
   209  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   210  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   211  				opts.APIClientFactory = mock.APIClient(testcase.api)
   212  				return opts, nil
   213  			}
   214  			err := app.Run(testcase.args, nil)
   215  			testutil.AssertErrorContains(t, err, testcase.wantError)
   216  			testutil.AssertString(t, testcase.wantOutput, stdout.String())
   217  		})
   218  	}
   219  }
   220  
   221  func TestKinesisUpdate(t *testing.T) {
   222  	args := testutil.Args
   223  	scenarios := []struct {
   224  		args       []string
   225  		api        mock.API
   226  		wantError  string
   227  		wantOutput string
   228  	}{
   229  		{
   230  			args:      args("logging kinesis update --service-id 123 --version 1 --new-name log"),
   231  			wantError: "error parsing arguments: required flag --name not provided",
   232  		},
   233  		{
   234  			args: args("logging kinesis update --service-id 123 --version 1 --name logs --new-name log --autoclone"),
   235  			api: mock.API{
   236  				ListVersionsFn:  testutil.ListVersions,
   237  				CloneVersionFn:  testutil.CloneVersionResult(4),
   238  				UpdateKinesisFn: updateKinesisError,
   239  			},
   240  			wantError: errTest.Error(),
   241  		},
   242  		{
   243  			args: args("logging kinesis update --service-id 123 --version 1 --name logs --new-name log --region us-west-1 --autoclone"),
   244  			api: mock.API{
   245  				ListVersionsFn:  testutil.ListVersions,
   246  				CloneVersionFn:  testutil.CloneVersionResult(4),
   247  				UpdateKinesisFn: updateKinesisOK,
   248  			},
   249  			wantOutput: "Updated Kinesis logging endpoint log (service 123 version 4)",
   250  		},
   251  	}
   252  	for testcaseIdx := range scenarios {
   253  		testcase := &scenarios[testcaseIdx]
   254  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   255  			var stdout bytes.Buffer
   256  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   257  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   258  				opts.APIClientFactory = mock.APIClient(testcase.api)
   259  				return opts, nil
   260  			}
   261  			err := app.Run(testcase.args, nil)
   262  			testutil.AssertErrorContains(t, err, testcase.wantError)
   263  			testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput)
   264  		})
   265  	}
   266  }
   267  
   268  func TestKinesisDelete(t *testing.T) {
   269  	args := testutil.Args
   270  	scenarios := []struct {
   271  		args       []string
   272  		api        mock.API
   273  		wantError  string
   274  		wantOutput string
   275  	}{
   276  		{
   277  			args:      args("logging kinesis delete --service-id 123 --version 1"),
   278  			wantError: "error parsing arguments: required flag --name not provided",
   279  		},
   280  		{
   281  			args: args("logging kinesis delete --service-id 123 --version 1 --name logs --autoclone"),
   282  			api: mock.API{
   283  				ListVersionsFn:  testutil.ListVersions,
   284  				CloneVersionFn:  testutil.CloneVersionResult(4),
   285  				DeleteKinesisFn: deleteKinesisError,
   286  			},
   287  			wantError: errTest.Error(),
   288  		},
   289  		{
   290  			args: args("logging kinesis delete --service-id 123 --version 1 --name logs --autoclone"),
   291  			api: mock.API{
   292  				ListVersionsFn:  testutil.ListVersions,
   293  				CloneVersionFn:  testutil.CloneVersionResult(4),
   294  				DeleteKinesisFn: deleteKinesisOK,
   295  			},
   296  			wantOutput: "Deleted Kinesis logging endpoint logs (service 123 version 4)",
   297  		},
   298  	}
   299  	for testcaseIdx := range scenarios {
   300  		testcase := &scenarios[testcaseIdx]
   301  		t.Run(strings.Join(testcase.args, " "), func(t *testing.T) {
   302  			var stdout bytes.Buffer
   303  			app.Init = func(_ []string, _ io.Reader) (*global.Data, error) {
   304  				opts := testutil.MockGlobalData(testcase.args, &stdout)
   305  				opts.APIClientFactory = mock.APIClient(testcase.api)
   306  				return opts, nil
   307  			}
   308  			err := app.Run(testcase.args, nil)
   309  			testutil.AssertErrorContains(t, err, testcase.wantError)
   310  			testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput)
   311  		})
   312  	}
   313  }
   314  
   315  var errTest = errors.New("fixture error")
   316  
   317  func createKinesisOK(i *fastly.CreateKinesisInput) (*fastly.Kinesis, error) {
   318  	return &fastly.Kinesis{
   319  		ServiceID:      fastly.ToPointer(i.ServiceID),
   320  		ServiceVersion: fastly.ToPointer(i.ServiceVersion),
   321  		Name:           i.Name,
   322  	}, nil
   323  }
   324  
   325  func createKinesisError(_ *fastly.CreateKinesisInput) (*fastly.Kinesis, error) {
   326  	return nil, errTest
   327  }
   328  
   329  func listKinesesOK(i *fastly.ListKinesisInput) ([]*fastly.Kinesis, error) {
   330  	return []*fastly.Kinesis{
   331  		{
   332  			ServiceID:         fastly.ToPointer(i.ServiceID),
   333  			ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   334  			Name:              fastly.ToPointer("logs"),
   335  			StreamName:        fastly.ToPointer("my-logs"),
   336  			AccessKey:         fastly.ToPointer("1234"),
   337  			SecretKey:         fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"),
   338  			Region:            fastly.ToPointer("us-east-1"),
   339  			Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   340  			FormatVersion:     fastly.ToPointer(2),
   341  			ResponseCondition: fastly.ToPointer("Prevent default logging"),
   342  			Placement:         fastly.ToPointer("none"),
   343  		},
   344  		{
   345  			ServiceID:         fastly.ToPointer(i.ServiceID),
   346  			ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   347  			Name:              fastly.ToPointer("analytics"),
   348  			StreamName:        fastly.ToPointer("analytics"),
   349  			AccessKey:         fastly.ToPointer("1234"),
   350  			SecretKey:         fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"),
   351  			Region:            fastly.ToPointer("us-east-1"),
   352  			Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   353  			FormatVersion:     fastly.ToPointer(2),
   354  			ResponseCondition: fastly.ToPointer("Prevent default logging"),
   355  			Placement:         fastly.ToPointer("none"),
   356  		},
   357  	}, nil
   358  }
   359  
   360  func listKinesesError(_ *fastly.ListKinesisInput) ([]*fastly.Kinesis, error) {
   361  	return nil, errTest
   362  }
   363  
   364  var listKinesesShortOutput = strings.TrimSpace(`
   365  SERVICE  VERSION  NAME
   366  123      1        logs
   367  123      1        analytics
   368  `) + "\n"
   369  
   370  var listKinesesVerboseOutput = strings.TrimSpace(`
   371  Fastly API endpoint: https://api.fastly.com
   372  Fastly API token provided via config file (profile: user)
   373  
   374  Service ID (via --service-id): 123
   375  
   376  Version: 1
   377  	Kinesis 1/2
   378  		Service ID: 123
   379  		Version: 1
   380  		Name: logs
   381  		Stream name: my-logs
   382  		Region: us-east-1
   383  		Access key: 1234
   384  		Secret key: -----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA
   385  		Format: %h %l %u %t "%r" %>s %b
   386  		Format version: 2
   387  		Response condition: Prevent default logging
   388  		Placement: none
   389  	Kinesis 2/2
   390  		Service ID: 123
   391  		Version: 1
   392  		Name: analytics
   393  		Stream name: analytics
   394  		Region: us-east-1
   395  		Access key: 1234
   396  		Secret key: -----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA
   397  		Format: %h %l %u %t "%r" %>s %b
   398  		Format version: 2
   399  		Response condition: Prevent default logging
   400  		Placement: none
   401  `) + "\n\n"
   402  
   403  func getKinesisOK(i *fastly.GetKinesisInput) (*fastly.Kinesis, error) {
   404  	return &fastly.Kinesis{
   405  		ServiceID:         fastly.ToPointer(i.ServiceID),
   406  		ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   407  		Name:              fastly.ToPointer("logs"),
   408  		StreamName:        fastly.ToPointer("my-logs"),
   409  		AccessKey:         fastly.ToPointer("1234"),
   410  		SecretKey:         fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"),
   411  		Region:            fastly.ToPointer("us-east-1"),
   412  		Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   413  		FormatVersion:     fastly.ToPointer(2),
   414  		ResponseCondition: fastly.ToPointer("Prevent default logging"),
   415  		Placement:         fastly.ToPointer("none"),
   416  	}, nil
   417  }
   418  
   419  func getKinesisError(_ *fastly.GetKinesisInput) (*fastly.Kinesis, error) {
   420  	return nil, errTest
   421  }
   422  
   423  var describeKinesisOutput = "\n" + strings.TrimSpace(`
   424  Access key: 1234
   425  Format: %h %l %u %t "%r" %>s %b
   426  Format version: 2
   427  Name: logs
   428  Placement: none
   429  Region: us-east-1
   430  Response condition: Prevent default logging
   431  Secret key: -----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA
   432  Service ID: 123
   433  Stream name: my-logs
   434  Version: 1
   435  `) + "\n"
   436  
   437  func updateKinesisOK(i *fastly.UpdateKinesisInput) (*fastly.Kinesis, error) {
   438  	return &fastly.Kinesis{
   439  		ServiceID:         fastly.ToPointer(i.ServiceID),
   440  		ServiceVersion:    fastly.ToPointer(i.ServiceVersion),
   441  		Name:              fastly.ToPointer("log"),
   442  		StreamName:        fastly.ToPointer("my-logs"),
   443  		AccessKey:         fastly.ToPointer("1234"),
   444  		SecretKey:         fastly.ToPointer("-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCA"),
   445  		Region:            fastly.ToPointer("us-west-1"),
   446  		Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
   447  		FormatVersion:     fastly.ToPointer(2),
   448  		ResponseCondition: fastly.ToPointer("Prevent default logging"),
   449  		Placement:         fastly.ToPointer("none"),
   450  	}, nil
   451  }
   452  
   453  func updateKinesisError(_ *fastly.UpdateKinesisInput) (*fastly.Kinesis, error) {
   454  	return nil, errTest
   455  }
   456  
   457  func deleteKinesisOK(_ *fastly.DeleteKinesisInput) error {
   458  	return nil
   459  }
   460  
   461  func deleteKinesisError(_ *fastly.DeleteKinesisInput) error {
   462  	return errTest
   463  }