github.com/cilium/cilium@v1.16.2/pkg/api/config_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package api
     5  
     6  import (
     7  	"errors"
     8  	"testing"
     9  
    10  	"github.com/go-openapi/spec"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestParseSpecPaths(t *testing.T) {
    15  	testCases := [...]struct {
    16  		name     string
    17  		paths    *spec.Paths
    18  		expected PathSet
    19  	}{
    20  		{
    21  			name: "Basic GET BGP",
    22  			paths: &spec.Paths{Paths: map[string]spec.PathItem{
    23  				"/bgp": {PathItemProps: spec.PathItemProps{
    24  					Get: &spec.Operation{},
    25  				}}}},
    26  			expected: PathSet{
    27  				"GetBGP": {
    28  					Method: "GET",
    29  					Path:   "/bgp",
    30  				}},
    31  		},
    32  		{
    33  			name: "PUT endpoints by ID",
    34  			paths: &spec.Paths{Paths: map[string]spec.PathItem{
    35  				"/endpoint/{id}": {PathItemProps: spec.PathItemProps{
    36  					Put: &spec.Operation{},
    37  				}}}},
    38  			expected: PathSet{
    39  				"PutEndpointID": {
    40  					Method: "PUT",
    41  					Path:   "/endpoint/{id}",
    42  				}},
    43  		},
    44  		{
    45  			name: "DELETE LRP by ID with suffix",
    46  			paths: &spec.Paths{Paths: map[string]spec.PathItem{
    47  				"/lrp/{id}/foo": {PathItemProps: spec.PathItemProps{
    48  					Delete: &spec.Operation{},
    49  				}}}},
    50  			expected: PathSet{
    51  				"DeleteLRPIDFoo": {
    52  					Method: "DELETE",
    53  					Path:   "/lrp/{id}/foo",
    54  				}},
    55  		},
    56  		{
    57  			name: "POST kebab-case",
    58  			paths: &spec.Paths{Paths: map[string]spec.PathItem{
    59  				"/cgroup-metadata-dump": {PathItemProps: spec.PathItemProps{
    60  					Post: &spec.Operation{},
    61  				}}}},
    62  			expected: PathSet{
    63  				"PostCgroupMetadataDump": {
    64  					Method: "POST",
    65  					Path:   "/cgroup-metadata-dump",
    66  				}},
    67  		},
    68  		{
    69  			name: "Multiple endpoints PATCH and PUT",
    70  			paths: &spec.Paths{Paths: map[string]spec.PathItem{
    71  				"/endpoint/{id}": {PathItemProps: spec.PathItemProps{
    72  					Put: &spec.Operation{},
    73  				}},
    74  				"/endpoint/{id}/config": {PathItemProps: spec.PathItemProps{
    75  					Patch: &spec.Operation{},
    76  				}},
    77  			}},
    78  			expected: PathSet{
    79  				"PatchEndpointIDConfig": {
    80  					Method: "PATCH",
    81  					Path:   "/endpoint/{id}/config",
    82  				},
    83  				"PutEndpointID": {
    84  					Method: "PUT",
    85  					Path:   "/endpoint/{id}",
    86  				},
    87  			},
    88  		},
    89  		{
    90  			name: "Multiple methods PATCH and PUT ipam",
    91  			paths: &spec.Paths{Paths: map[string]spec.PathItem{
    92  				"/ipam/{ip}": {PathItemProps: spec.PathItemProps{
    93  					Put:   &spec.Operation{},
    94  					Patch: &spec.Operation{},
    95  				}},
    96  			}},
    97  			expected: PathSet{
    98  				"PatchIPAMIP": {
    99  					Method: "PATCH",
   100  					Path:   "/ipam/{ip}",
   101  				},
   102  				"PutIPAMIP": {
   103  					Method: "PUT",
   104  					Path:   "/ipam/{ip}",
   105  				},
   106  			},
   107  		},
   108  	}
   109  	for _, tc := range testCases {
   110  		t.Run(tc.name, func(t *testing.T) {
   111  			got := parseSpecPaths(tc.paths)
   112  			require.Equalf(t, tc.expected, got, "case %q failed", tc.name)
   113  		})
   114  	}
   115  }
   116  
   117  func TestAllowedFlagsToDeniedPaths(t *testing.T) {
   118  	sampleFlags := PathSet{
   119  		"GetEndpoint":           {Method: "GET", Path: "/endpoint"},
   120  		"PutEndpointID":         {Method: "PUT", Path: "/endpoint/{id}"},
   121  		"PatchEndpointIDConfig": {Method: "PATCH", Path: "/endpoint/{id}/config"},
   122  	}
   123  	testCases := [...]struct {
   124  		name        string
   125  		allowed     []string
   126  		expected    PathSet
   127  		expectedErr error
   128  	}{
   129  		{
   130  			name:    "deny all",
   131  			allowed: []string{},
   132  			expected: PathSet{
   133  				"GetEndpoint":           {Method: "GET", Path: "/endpoint"},
   134  				"PutEndpointID":         {Method: "PUT", Path: "/endpoint/{id}"},
   135  				"PatchEndpointIDConfig": {Method: "PATCH", Path: "/endpoint/{id}/config"},
   136  			},
   137  		},
   138  		{
   139  			name:     "wildcard: allow all",
   140  			allowed:  []string{"*"},
   141  			expected: PathSet{},
   142  		},
   143  		{
   144  			name:    "wildcard: allow gets",
   145  			allowed: []string{"Get*"},
   146  			expected: PathSet{
   147  				"PutEndpointID":         {Method: "PUT", Path: "/endpoint/{id}"},
   148  				"PatchEndpointIDConfig": {Method: "PATCH", Path: "/endpoint/{id}/config"},
   149  			},
   150  		},
   151  		{
   152  			name:        "allow invalid option",
   153  			allowed:     []string{"NoSuchOption"},
   154  			expected:    PathSet(nil),
   155  			expectedErr: ErrUnknownFlag,
   156  		},
   157  		{
   158  			name:        "deny all empty string",
   159  			allowed:     []string{""},
   160  			expected:    PathSet(nil),
   161  			expectedErr: ErrUnknownFlag,
   162  		},
   163  		{
   164  			name:        "wildcard: invalid prefix",
   165  			allowed:     []string{"*foo"},
   166  			expected:    PathSet(nil),
   167  			expectedErr: ErrUnknownWildcard,
   168  		},
   169  		{
   170  			name:        "wildcard: invalid multiple wildcard",
   171  			allowed:     []string{"foo*bar*"},
   172  			expected:    PathSet(nil),
   173  			expectedErr: ErrUnknownWildcard,
   174  		},
   175  	}
   176  	for _, tc := range testCases {
   177  		t.Run(tc.name, func(t *testing.T) {
   178  			got, err := generateDeniedAPIEndpoints(sampleFlags, tc.allowed)
   179  			require.Equalf(t, tc.expected, got, "case %q failed", tc.name)
   180  			require.Equalf(t, tc.expectedErr, errors.Unwrap(err), "case %q failed", tc.name)
   181  		})
   182  	}
   183  
   184  }