github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/acl/policy_test.go (about)

     1  package acl
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func TestParse(t *testing.T) {
    12  	type tcase struct {
    13  		Raw    string
    14  		ErrStr string
    15  		Expect *Policy
    16  	}
    17  	tcases := []tcase{
    18  		{
    19  			`
    20  			namespace "default" {
    21  				policy = "read"
    22  			}
    23  			`,
    24  			"",
    25  			&Policy{
    26  				Namespaces: []*NamespacePolicy{
    27  					{
    28  						Name:   "default",
    29  						Policy: PolicyRead,
    30  						Capabilities: []string{
    31  							NamespaceCapabilityListJobs,
    32  							NamespaceCapabilityReadJob,
    33  							NamespaceCapabilityCSIListVolume,
    34  							NamespaceCapabilityCSIReadVolume,
    35  							NamespaceCapabilityReadJobScaling,
    36  							NamespaceCapabilityListScalingPolicies,
    37  							NamespaceCapabilityReadScalingPolicy,
    38  						},
    39  					},
    40  				},
    41  			},
    42  		},
    43  		{
    44  			`
    45  			namespace "default" {
    46  				policy = "read"
    47  			}
    48  			namespace "other" {
    49  				policy = "write"
    50  			}
    51  			namespace "secret" {
    52  				capabilities = ["deny", "read-logs"]
    53  			}
    54  			namespace "autoscaler" {
    55  				policy = "scale"
    56  			}
    57  			agent {
    58  				policy = "read"
    59  			}
    60  			node {
    61  				policy = "write"
    62  			}
    63  			operator {
    64  				policy = "deny"
    65  			}
    66  			quota {
    67  				policy = "read"
    68  			}
    69  			plugin {
    70  				policy = "read"
    71  			}
    72  			`,
    73  			"",
    74  			&Policy{
    75  				Namespaces: []*NamespacePolicy{
    76  					{
    77  						Name:   "default",
    78  						Policy: PolicyRead,
    79  						Capabilities: []string{
    80  							NamespaceCapabilityListJobs,
    81  							NamespaceCapabilityReadJob,
    82  							NamespaceCapabilityCSIListVolume,
    83  							NamespaceCapabilityCSIReadVolume,
    84  							NamespaceCapabilityReadJobScaling,
    85  							NamespaceCapabilityListScalingPolicies,
    86  							NamespaceCapabilityReadScalingPolicy,
    87  						},
    88  					},
    89  					{
    90  						Name:   "other",
    91  						Policy: PolicyWrite,
    92  						Capabilities: []string{
    93  							NamespaceCapabilityListJobs,
    94  							NamespaceCapabilityReadJob,
    95  							NamespaceCapabilityCSIListVolume,
    96  							NamespaceCapabilityCSIReadVolume,
    97  							NamespaceCapabilityReadJobScaling,
    98  							NamespaceCapabilityListScalingPolicies,
    99  							NamespaceCapabilityReadScalingPolicy,
   100  							NamespaceCapabilityScaleJob,
   101  							NamespaceCapabilitySubmitJob,
   102  							NamespaceCapabilityDispatchJob,
   103  							NamespaceCapabilityReadLogs,
   104  							NamespaceCapabilityReadFS,
   105  							NamespaceCapabilityAllocExec,
   106  							NamespaceCapabilityAllocLifecycle,
   107  							NamespaceCapabilityCSIMountVolume,
   108  							NamespaceCapabilityCSIWriteVolume,
   109  							NamespaceCapabilitySubmitRecommendation,
   110  						},
   111  					},
   112  					{
   113  						Name: "secret",
   114  						Capabilities: []string{
   115  							NamespaceCapabilityDeny,
   116  							NamespaceCapabilityReadLogs,
   117  						},
   118  					},
   119  					{
   120  						Name:   "autoscaler",
   121  						Policy: PolicyScale,
   122  						Capabilities: []string{
   123  							NamespaceCapabilityListScalingPolicies,
   124  							NamespaceCapabilityReadScalingPolicy,
   125  							NamespaceCapabilityReadJobScaling,
   126  							NamespaceCapabilityScaleJob,
   127  						},
   128  					},
   129  				},
   130  				Agent: &AgentPolicy{
   131  					Policy: PolicyRead,
   132  				},
   133  				Node: &NodePolicy{
   134  					Policy: PolicyWrite,
   135  				},
   136  				Operator: &OperatorPolicy{
   137  					Policy: PolicyDeny,
   138  				},
   139  				Quota: &QuotaPolicy{
   140  					Policy: PolicyRead,
   141  				},
   142  				Plugin: &PluginPolicy{
   143  					Policy: PolicyRead,
   144  				},
   145  			},
   146  		},
   147  		{
   148  			`
   149  			namespace "default" {
   150  				policy = "foo"
   151  			}
   152  			`,
   153  			"Invalid namespace policy",
   154  			nil,
   155  		},
   156  		{
   157  			`
   158  			namespace "default" {
   159  				capabilities = ["deny", "foo"]
   160  			}
   161  			`,
   162  			"Invalid namespace capability",
   163  			nil,
   164  		},
   165  		{
   166  			`
   167  			agent {
   168  				policy = "foo"
   169  			}
   170  			`,
   171  			"Invalid agent policy",
   172  			nil,
   173  		},
   174  		{
   175  			`
   176  			node {
   177  				policy = "foo"
   178  			}
   179  			`,
   180  			"Invalid node policy",
   181  			nil,
   182  		},
   183  		{
   184  			`
   185  			operator {
   186  				policy = "foo"
   187  			}
   188  			`,
   189  			"Invalid operator policy",
   190  			nil,
   191  		},
   192  		{
   193  			`
   194  			quota {
   195  				policy = "foo"
   196  			}
   197  			`,
   198  			"Invalid quota policy",
   199  			nil,
   200  		},
   201  		{
   202  			`
   203  			{
   204  				"Name": "my-policy",
   205  				"Description": "This is a great policy",
   206  				"Rules": "anything"
   207  			}
   208  			`,
   209  			"Invalid policy",
   210  			nil,
   211  		},
   212  		{
   213  			`
   214  			namespace "has a space"{
   215  				policy = "read"
   216  			}
   217  			`,
   218  			"Invalid namespace name",
   219  			nil,
   220  		},
   221  		{
   222  			`
   223  			namespace "default" {
   224  				capabilities = ["sentinel-override"]
   225  			}
   226  			`,
   227  			"",
   228  			&Policy{
   229  				Namespaces: []*NamespacePolicy{
   230  					{
   231  						Name:   "default",
   232  						Policy: "",
   233  						Capabilities: []string{
   234  							NamespaceCapabilitySentinelOverride,
   235  						},
   236  					},
   237  				},
   238  			},
   239  		},
   240  		{
   241  			`
   242  			host_volume "production-tls-*" {
   243  				capabilities = ["mount-readonly"]
   244  			}
   245  			`,
   246  			"",
   247  			&Policy{
   248  				HostVolumes: []*HostVolumePolicy{
   249  					{
   250  						Name:   "production-tls-*",
   251  						Policy: "",
   252  						Capabilities: []string{
   253  							HostVolumeCapabilityMountReadOnly,
   254  						},
   255  					},
   256  				},
   257  			},
   258  		},
   259  		{
   260  			`
   261  			host_volume "production-tls-*" {
   262  				capabilities = ["mount-readwrite"]
   263  			}
   264  			`,
   265  			"",
   266  			&Policy{
   267  				HostVolumes: []*HostVolumePolicy{
   268  					{
   269  						Name:   "production-tls-*",
   270  						Policy: "",
   271  						Capabilities: []string{
   272  							HostVolumeCapabilityMountReadWrite,
   273  						},
   274  					},
   275  				},
   276  			},
   277  		},
   278  		{
   279  			`
   280  			host_volume "volume has a space" {
   281  				capabilities = ["mount-readwrite"]
   282  			}
   283  			`,
   284  			"Invalid host volume name",
   285  			nil,
   286  		},
   287  		{
   288  			`
   289  			plugin {
   290  				policy = "list"
   291  			}
   292  			`,
   293  			"",
   294  			&Policy{
   295  				Plugin: &PluginPolicy{
   296  					Policy: PolicyList,
   297  				},
   298  			},
   299  		},
   300  		{
   301  			`
   302  			plugin {
   303  				policy = "reader"
   304  			}
   305  			`,
   306  			"Invalid plugin policy",
   307  			nil,
   308  		},
   309  	}
   310  
   311  	for idx, tc := range tcases {
   312  		t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) {
   313  			p, err := Parse(tc.Raw)
   314  			if err != nil {
   315  				if tc.ErrStr == "" {
   316  					t.Fatalf("Unexpected err: %v", err)
   317  				}
   318  				if !strings.Contains(err.Error(), tc.ErrStr) {
   319  					t.Fatalf("Unexpected err: %v", err)
   320  				}
   321  				return
   322  			}
   323  			if err == nil && tc.ErrStr != "" {
   324  				t.Fatalf("Missing expected err")
   325  			}
   326  			tc.Expect.Raw = tc.Raw
   327  			assert.EqualValues(t, tc.Expect, p)
   328  		})
   329  	}
   330  }
   331  
   332  func TestParse_BadInput(t *testing.T) {
   333  	inputs := []string{
   334  		`namespace "\500" {}`,
   335  	}
   336  
   337  	for i, c := range inputs {
   338  		t.Run(fmt.Sprintf("%d: %v", i, c), func(t *testing.T) {
   339  			_, err := Parse(c)
   340  			assert.Error(t, err)
   341  		})
   342  	}
   343  }