1package api
2
3import (
4	"testing"
5
6	"github.com/stretchr/testify/require"
7)
8
9func TestAPI_ConfigEntries_ServiceIntentions(t *testing.T) {
10	t.Parallel()
11	c, s := makeClient(t)
12	defer s.Stop()
13
14	s.WaitForServiceIntentions(t)
15
16	config_entries := c.ConfigEntries()
17
18	// Allow L7 for all services.
19	_, _, err := config_entries.Set(&ProxyConfigEntry{
20		Kind: ProxyDefaults,
21		Name: ProxyConfigGlobal,
22		Config: map[string]interface{}{
23			"protocol": "http",
24		},
25	}, nil)
26	require.NoError(t, err)
27
28	entries := []*ServiceIntentionsConfigEntry{
29		{
30			Kind: ServiceIntentions,
31			Name: "foo",
32			Sources: []*SourceIntention{
33				{
34					Name:   "one",
35					Action: IntentionActionAllow,
36				},
37				{
38					Name:   "two",
39					Action: IntentionActionDeny,
40				},
41			},
42		},
43		{
44			Kind: ServiceIntentions,
45			Name: "bar",
46			Sources: []*SourceIntention{
47				{
48					Name:   "three",
49					Action: IntentionActionAllow,
50				},
51			},
52		},
53	}
54
55	// set them
56	for _, entry := range entries {
57		_, wm, err := config_entries.Set(entry, nil)
58		require.NoError(t, err)
59		require.NotNil(t, wm)
60		require.NotEqual(t, 0, wm.RequestTime)
61	}
62
63	// get one
64	entry, qm, err := config_entries.Get(ServiceIntentions, "foo", nil)
65	require.NoError(t, err)
66	require.NotNil(t, qm)
67	require.NotEqual(t, 0, qm.RequestTime)
68
69	// verify it
70	readIxn, ok := entry.(*ServiceIntentionsConfigEntry)
71	require.True(t, ok)
72	require.Equal(t, "service-intentions", readIxn.Kind)
73	require.Equal(t, "foo", readIxn.Name)
74	require.Len(t, readIxn.Sources, 2)
75
76	// update it
77	entries[0].Meta = map[string]string{"a": "b"}
78
79	// CAS fail
80	written, _, err := config_entries.CAS(entries[0], 0, nil)
81	require.NoError(t, err)
82	require.False(t, written)
83
84	// CAS success
85	written, wm, err := config_entries.CAS(entries[0], readIxn.ModifyIndex, nil)
86	require.NoError(t, err)
87	require.NotNil(t, wm)
88	require.NotEqual(t, 0, wm.RequestTime)
89	require.True(t, written)
90
91	// update no cas
92	entries[0].Meta = map[string]string{"x": "y"}
93
94	_, wm, err = config_entries.Set(entries[0], nil)
95	require.NoError(t, err)
96	require.NotNil(t, wm)
97	require.NotEqual(t, 0, wm.RequestTime)
98
99	// list them
100	gotEntries, qm, err := config_entries.List(ServiceIntentions, nil)
101	require.NoError(t, err)
102	require.NotNil(t, qm)
103	require.NotEqual(t, 0, qm.RequestTime)
104	require.Len(t, gotEntries, 2)
105
106	for _, entry = range gotEntries {
107		switch entry.GetName() {
108		case "foo":
109			// this also verifies that the update value was persisted and
110			// the updated values are seen
111			readIxn, ok = entry.(*ServiceIntentionsConfigEntry)
112			require.True(t, ok)
113			require.Equal(t, "service-intentions", readIxn.Kind)
114			require.Equal(t, "foo", readIxn.Name)
115			require.Len(t, readIxn.Sources, 2)
116			require.Equal(t, map[string]string{"x": "y"}, readIxn.Meta)
117		case "bar":
118			readIxn, ok = entry.(*ServiceIntentionsConfigEntry)
119			require.True(t, ok)
120			require.Equal(t, "service-intentions", readIxn.Kind)
121			require.Equal(t, "bar", readIxn.Name)
122			require.Len(t, readIxn.Sources, 1)
123			require.Empty(t, readIxn.Meta)
124		}
125	}
126
127	// delete one
128	wm, err = config_entries.Delete(ServiceIntentions, "foo", nil)
129	require.NoError(t, err)
130	require.NotNil(t, wm)
131	require.NotEqual(t, 0, wm.RequestTime)
132
133	// verify deletion
134	_, _, err = config_entries.Get(ServiceIntentions, "foo", nil)
135	require.Error(t, err)
136}
137