Skip to content

Commit 6611a20

Browse files
authored
feat: add support for logs permissions (#362)
1 parent a456f1a commit 6611a20

File tree

34 files changed

+1922
-139
lines changed

34 files changed

+1922
-139
lines changed

_run/common-commands.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ get-manifest:
9494

9595
.PHONY: deployment-create
9696
deployment-create:
97-
$(AKASH) tx deployment create "$(SDL_PATH)" \
97+
$(PROVIDER_SERVICES) tx deployment create "$(SDL_PATH)" \
9898
--dseq "$(DSEQ)" \
9999
--from "$(KEY_NAME)"
100100

cluster/kube/apply.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
appsv1 "k8s.io/api/apps/v1"
1111
corev1 "k8s.io/api/core/v1"
1212
netv1 "k8s.io/api/networking/v1"
13+
rbacv1 "k8s.io/api/rbac/v1"
1314
"k8s.io/apimachinery/pkg/api/errors"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
k8stypes "k8s.io/apimachinery/pkg/types"
@@ -265,3 +266,82 @@ func applyService(ctx context.Context, kc kubernetes.Interface, b builder.Servic
265266

266267
return nobj, uobj, oobj, err
267268
}
269+
270+
func applyServiceAccount(ctx context.Context, kc kubernetes.Interface, b builder.ServiceAccount) (*corev1.ServiceAccount, *corev1.ServiceAccount, *corev1.ServiceAccount, error) {
271+
oobj, err := kc.CoreV1().ServiceAccounts(b.NS()).Get(ctx, b.Name(), metav1.GetOptions{})
272+
metricsutils.IncCounterVecWithLabelValuesFiltered(kubeCallsCounter, "serviceaccounts-get", err, errors.IsNotFound)
273+
274+
var nobj *corev1.ServiceAccount
275+
var uobj *corev1.ServiceAccount
276+
277+
switch {
278+
case err == nil:
279+
uobj, err = b.Update(oobj)
280+
if err == nil && (!b.IsObjectRevisionLatest(uobj.Labels) ||
281+
!reflect.DeepEqual(uobj.Labels, oobj.Labels)) {
282+
uobj, err = kc.CoreV1().ServiceAccounts(b.NS()).Update(ctx, uobj, metav1.UpdateOptions{})
283+
metricsutils.IncCounterVecWithLabelValues(kubeCallsCounter, "serviceaccounts-update", err)
284+
}
285+
case errors.IsNotFound(err):
286+
nobj, err = b.Create()
287+
if err == nil {
288+
nobj, err = kc.CoreV1().ServiceAccounts(b.NS()).Create(ctx, nobj, metav1.CreateOptions{})
289+
metricsutils.IncCounterVecWithLabelValues(kubeCallsCounter, "serviceaccounts-create", err)
290+
}
291+
}
292+
293+
return nobj, uobj, oobj, err
294+
}
295+
296+
func applyRole(ctx context.Context, kc kubernetes.Interface, b builder.Role) (*rbacv1.Role, *rbacv1.Role, *rbacv1.Role, error) {
297+
oobj, err := kc.RbacV1().Roles(b.NS()).Get(ctx, b.Name(), metav1.GetOptions{})
298+
metricsutils.IncCounterVecWithLabelValuesFiltered(kubeCallsCounter, "roles-get", err, errors.IsNotFound)
299+
300+
var nobj *rbacv1.Role
301+
var uobj *rbacv1.Role
302+
303+
switch {
304+
case err == nil:
305+
uobj, err = b.Update(oobj)
306+
if err == nil && (!b.IsObjectRevisionLatest(uobj.Labels) ||
307+
!reflect.DeepEqual(&uobj.Rules, &oobj.Rules) ||
308+
!reflect.DeepEqual(uobj.Labels, oobj.Labels)) {
309+
uobj, err = kc.RbacV1().Roles(b.NS()).Update(ctx, uobj, metav1.UpdateOptions{})
310+
metricsutils.IncCounterVecWithLabelValues(kubeCallsCounter, "roles-update", err)
311+
}
312+
case errors.IsNotFound(err):
313+
nobj, err = b.Create()
314+
if err == nil {
315+
nobj, err = kc.RbacV1().Roles(b.NS()).Create(ctx, nobj, metav1.CreateOptions{})
316+
metricsutils.IncCounterVecWithLabelValues(kubeCallsCounter, "roles-create", err)
317+
}
318+
}
319+
320+
return nobj, uobj, oobj, err
321+
}
322+
323+
func applyRoleBinding(ctx context.Context, kc kubernetes.Interface, b builder.RoleBinding) (*rbacv1.RoleBinding, *rbacv1.RoleBinding, *rbacv1.RoleBinding, error) {
324+
oobj, err := kc.RbacV1().RoleBindings(b.NS()).Get(ctx, b.Name(), metav1.GetOptions{})
325+
metricsutils.IncCounterVecWithLabelValuesFiltered(kubeCallsCounter, "rolebindings-get", err, errors.IsNotFound)
326+
327+
var nobj *rbacv1.RoleBinding
328+
var uobj *rbacv1.RoleBinding
329+
330+
switch {
331+
case err == nil:
332+
uobj, err = b.Update(oobj)
333+
if err == nil && (!b.IsObjectRevisionLatest(uobj.Labels) ||
334+
!reflect.DeepEqual(uobj.Labels, oobj.Labels)) {
335+
uobj, err = kc.RbacV1().RoleBindings(b.NS()).Update(ctx, uobj, metav1.UpdateOptions{})
336+
metricsutils.IncCounterVecWithLabelValues(kubeCallsCounter, "rolebindings-update", err)
337+
}
338+
case errors.IsNotFound(err):
339+
nobj, err = b.Create()
340+
if err == nil {
341+
nobj, err = kc.RbacV1().RoleBindings(b.NS()).Create(ctx, nobj, metav1.CreateOptions{})
342+
metricsutils.IncCounterVecWithLabelValues(kubeCallsCounter, "rolebindings-create", err)
343+
}
344+
}
345+
346+
return nobj, uobj, oobj, err
347+
}

cluster/kube/builder/builder.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ const (
5151
)
5252

5353
const (
54-
envVarAkashGroupSequence = "AKASH_GROUP_SEQUENCE"
55-
envVarAkashDeploymentSequence = "AKASH_DEPLOYMENT_SEQUENCE"
56-
envVarAkashOrderSequence = "AKASH_ORDER_SEQUENCE"
57-
envVarAkashOwner = "AKASH_OWNER"
58-
envVarAkashProvider = "AKASH_PROVIDER"
59-
envVarAkashClusterPublicHostname = "AKASH_CLUSTER_PUBLIC_HOSTNAME"
54+
envVarAkashGroupSequence = "AKASH_GROUP_SEQUENCE"
55+
envVarAkashDeploymentSequence = "AKASH_DEPLOYMENT_SEQUENCE"
56+
envVarAkashOrderSequence = "AKASH_ORDER_SEQUENCE"
57+
envVarAkashOwner = "AKASH_OWNER"
58+
envVarAkashProvider = "AKASH_PROVIDER"
59+
envVarAkashClusterPublicHostname = "AKASH_CLUSTER_PUBLIC_HOSTNAME"
60+
envVarKubernetesNamespaceOverride = "KUBERNETES_NAMESPACE_OVERRIDE"
61+
envVarKubernetesServiceHost = "KUBERNETES_SERVICE_HOST"
62+
envVarKubernetesServicePort = "KUBERNETES_SERVICE_PORT"
6063
)
6164

6265
var (

cluster/kube/builder/deployment.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ func (b *deployment) Create() (*appsv1.Deployment, error) { // nolint:unparam
6565
SecurityContext: &corev1.PodSecurityContext{
6666
RunAsNonRoot: &falseValue,
6767
},
68-
AutomountServiceAccountToken: &falseValue,
68+
AutomountServiceAccountToken: b.automountServiceAccountToken(),
69+
ServiceAccountName: b.serviceAccountName(),
6970
Containers: []corev1.Container{b.container()},
7071
ImagePullSecrets: b.secretsRefs,
7172
Volumes: b.volumesObjs,
@@ -86,6 +87,8 @@ func (b *deployment) Update(obj *appsv1.Deployment) (*appsv1.Deployment, error)
8687
uobj.Spec.Template.Labels = b.labels()
8788
uobj.Spec.Template.Spec.Affinity = b.affinity()
8889
uobj.Spec.Template.Spec.RuntimeClassName = b.runtimeClass()
90+
uobj.Spec.Template.Spec.AutomountServiceAccountToken = b.automountServiceAccountToken()
91+
uobj.Spec.Template.Spec.ServiceAccountName = b.serviceAccountName()
8992
uobj.Spec.Template.Spec.Containers = []corev1.Container{b.container()}
9093
uobj.Spec.Template.Spec.ImagePullSecrets = b.secretsRefs
9194
uobj.Spec.Template.Spec.Volumes = b.volumesObjs

cluster/kube/builder/deployment_test.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,23 @@ import (
1010
"pkg.akt.dev/go/testutil"
1111

1212
crd "github.com/akash-network/provider/pkg/apis/akash.network/v2beta2"
13+
mtypes "pkg.akt.dev/go/node/market/v1"
1314
)
1415

15-
func TestDeploySetsEnvironmentVariables(t *testing.T) {
16+
const fakeHostname = "ahostname.dev"
17+
18+
func testSetup(t *testing.T, sdlFile string, serviceIdx int, lid mtypes.LeaseID) (*crd.Manifest, *Workload) {
19+
t.Helper()
20+
1621
log := testutil.Logger(t)
17-
const fakeHostname = "ahostname.dev"
1822
settings := Settings{
1923
ClusterPublicHostname: fakeHostname,
2024
}
21-
lid := testutil.LeaseID(t)
22-
sdl, err := sdl.ReadFile("../../../testdata/deployment/deployment.yaml")
25+
26+
sdlData, err := sdl.ReadFile(sdlFile)
2327
require.NoError(t, err)
2428

25-
mani, err := sdl.Manifest()
29+
mani, err := sdlData.Manifest()
2630
require.NoError(t, err)
2731

2832
sparams := make([]*crd.SchedulerParams, len(mani.GetGroups()[0].Services))
@@ -39,9 +43,16 @@ func TestDeploySetsEnvironmentVariables(t *testing.T) {
3943
Sparams: crd.ClusterSettings{SchedulerParams: sparams},
4044
}
4145

42-
workload, err := NewWorkloadBuilder(log, settings, cdep, cmani, 0)
46+
workload, err := NewWorkloadBuilder(log, settings, cdep, cmani, serviceIdx)
4347
require.NoError(t, err)
4448

49+
return cmani, workload
50+
}
51+
52+
func TestDeploySetsEnvironmentVariables(t *testing.T) {
53+
lid := testutil.LeaseID(t)
54+
_, workload := testSetup(t, "../../../testdata/deployment/deployment.yaml", 0, lid)
55+
4556
deploymentBuilder := NewDeployment(workload)
4657

4758
require.NotNil(t, deploymentBuilder)
@@ -80,3 +91,46 @@ func TestDeploySetsEnvironmentVariables(t *testing.T) {
8091
require.True(t, ok)
8192
require.Equal(t, lid.Provider, value)
8293
}
94+
95+
func TestDeploymentPermissions(t *testing.T) {
96+
tests := []struct {
97+
name string
98+
sdlFile string
99+
serviceIdx int
100+
expectedToken bool
101+
}{
102+
{
103+
name: "defaults to false when no permissions specified",
104+
sdlFile: "../../../testdata/deployment/deployment.yaml",
105+
serviceIdx: 0,
106+
expectedToken: false,
107+
},
108+
{
109+
name: "enables automount when permissions are defined",
110+
sdlFile: "../../../testdata/sdl/permissions.yaml",
111+
serviceIdx: 0,
112+
expectedToken: true,
113+
},
114+
{
115+
name: "disables automount when no permissions defined",
116+
sdlFile: "../../../testdata/sdl/permissions.yaml",
117+
serviceIdx: 1,
118+
expectedToken: false,
119+
},
120+
}
121+
122+
for _, tt := range tests {
123+
t.Run(tt.name, func(t *testing.T) {
124+
lid := testutil.LeaseID(t)
125+
_, workload := testSetup(t, tt.sdlFile, tt.serviceIdx, lid)
126+
127+
deploymentBuilder := NewDeployment(workload)
128+
deployment, err := deploymentBuilder.Create()
129+
require.NoError(t, err)
130+
require.NotNil(t, deployment)
131+
132+
require.NotNil(t, deployment.Spec.Template.Spec.AutomountServiceAccountToken)
133+
require.Equal(t, tt.expectedToken, *deployment.Spec.Template.Spec.AutomountServiceAccountToken)
134+
})
135+
}
136+
}

0 commit comments

Comments
 (0)