Skip to content

Commit 8e66267

Browse files
fanminshihasbro17
authored andcommitted
cmd/add: append role of new apiGroup and Resource to role.yaml
1 parent cc62dbd commit 8e66267

File tree

1 file changed

+61
-1
lines changed
  • commands/operator-sdk/cmd/add

1 file changed

+61
-1
lines changed

commands/operator-sdk/cmd/add/api.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package add
1616

1717
import (
1818
"bytes"
19+
"errors"
1920
"fmt"
2021
"io/ioutil"
2122
"log"
@@ -25,7 +26,10 @@ import (
2526
"github.com/operator-framework/operator-sdk/commands/operator-sdk/cmd/cmdutil"
2627
"github.com/operator-framework/operator-sdk/pkg/scaffold"
2728

29+
"github.com/ghodss/yaml"
2830
"github.com/spf13/cobra"
31+
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
32+
cgoscheme "k8s.io/client-go/kubernetes/scheme"
2933
)
3034

3135
var (
@@ -162,8 +166,64 @@ func apiRun(cmd *cobra.Command, args []string) {
162166
log.Fatalf("failed to create %v: %v", filePath, err)
163167
}
164168

165-
// TODO: append rbac rule to deploy/rbac/role.yaml
169+
// update deploy/role.yaml for the given resource r.
170+
if err := updateRoleForResource(r, fullProjectPath); err != nil {
171+
log.Fatalf("failed to update the RBAC manifest for the resource (%v, %v): %v", r.APIVersion, r.Kind, err)
172+
}
173+
}
166174

175+
func updateRoleForResource(r *scaffold.Resource, fullProjectPath string) error {
176+
// append rbac rule to deploy/role.yaml
177+
roleFilePath := filepath.Join(fullProjectPath, "deploy", "role.yaml")
178+
roleYAML, err := ioutil.ReadFile(roleFilePath)
179+
if err != nil {
180+
return fmt.Errorf("failed to read role manifest %v: %v", roleFilePath, err)
181+
}
182+
obj, _, err := cgoscheme.Codecs.UniversalDeserializer().Decode(roleYAML, nil, nil)
183+
if err != nil {
184+
return fmt.Errorf("failed to decode role manifest %v: %v", roleFilePath, err)
185+
}
186+
switch role := obj.(type) {
187+
// TODO: use rbac/v1.
188+
case *rbacv1beta1.Role:
189+
pr := &rbacv1beta1.PolicyRule{}
190+
apiGroupFound := false
191+
for i := range role.Rules {
192+
if role.Rules[i].APIGroups[0] == r.FullGroup {
193+
apiGroupFound = true
194+
pr = &role.Rules[i]
195+
break
196+
}
197+
}
198+
// check if the resource already exists
199+
for _, resource := range pr.Resources {
200+
if resource == r.Resource {
201+
log.Printf("deploy/role.yaml RBAC rules already up to date for the resource (%v, %v)", r.APIVersion, r.Kind)
202+
return nil
203+
}
204+
}
205+
206+
pr.Resources = append(pr.Resources, r.Resource)
207+
// create a new apiGroup if not found.
208+
if !apiGroupFound {
209+
pr.APIGroups = []string{r.FullGroup}
210+
pr.Resources = []string{r.Resource}
211+
pr.Verbs = []string{"*"}
212+
role.Rules = append(role.Rules, *pr)
213+
}
214+
// update role.yaml
215+
data, err := yaml.Marshal(&role)
216+
if err != nil {
217+
return fmt.Errorf("failed to marshal role(%+v): %v", role, err)
218+
}
219+
if err := ioutil.WriteFile(roleFilePath, data, cmdutil.DefaultFileMode); err != nil {
220+
return fmt.Errorf("failed to update %v: %v", roleFilePath, err)
221+
}
222+
default:
223+
return errors.New("failed to parse role.yaml as a role")
224+
}
225+
// not reachable
226+
return nil
167227
}
168228

169229
// TODO: Make the utils below common in pkg/cmd/util

0 commit comments

Comments
 (0)