github.com/Axway/agent-sdk@v1.1.101/pkg/agent/aclupdatejob.go (about) 1 package agent 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1" 9 management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" 10 "github.com/Axway/agent-sdk/pkg/jobs" 11 "github.com/Axway/agent-sdk/pkg/util" 12 hc "github.com/Axway/agent-sdk/pkg/util/healthcheck" 13 "github.com/Axway/agent-sdk/pkg/util/log" 14 ) 15 16 const envACLFormat = "%s-agent-acl" 17 18 // aclUpdateHandler - job that handles updates to the ACL in the environment 19 type aclUpdateJob struct { 20 jobs.Job 21 logger log.FieldLogger 22 } 23 24 func newACLUpdateJob() *aclUpdateJob { 25 logger := log.NewFieldLogger(). 26 WithPackage("sdk.agent"). 27 WithComponent("aclUpdateJob") 28 job := &aclUpdateJob{ 29 logger: logger, 30 } 31 return job 32 } 33 34 func (j *aclUpdateJob) Ready() bool { 35 status, _ := hc.GetGlobalStatus() 36 return status == string(hc.OK) 37 } 38 39 func (j *aclUpdateJob) Status() error { 40 if status, _ := hc.GetGlobalStatus(); status != string(hc.OK) { 41 err := fmt.Errorf("agent is marked as not running") 42 j.logger.WithError(err).Trace("status failed") 43 return err 44 } 45 return nil 46 } 47 48 func (j *aclUpdateJob) getACLTeamIDs(ri *v1.ResourceInstance) []string { 49 teamIDs := make([]string, 0) 50 acl, _ := management.NewAccessControlList("", management.EnvironmentGVK().Kind, agent.cfg.GetEnvironmentName()) 51 err := acl.FromInstance(ri) 52 if err != nil { 53 return teamIDs 54 } 55 for _, subject := range acl.Spec.Subjects { 56 if subject.Type == v1.TeamOwner { 57 teamIDs = append(teamIDs, subject.ID) 58 } 59 } 60 teamIDs = util.RemoveDuplicateValuesFromStringSlice(teamIDs) 61 sort.Strings(teamIDs) 62 return teamIDs 63 } 64 65 func (j *aclUpdateJob) Execute() error { 66 currentACL := agent.cacheManager.GetAccessControlList() 67 if currentACL == nil { 68 currentACL = j.getACLsFromServer() 69 } 70 71 currentTeamIDs := j.getACLTeamIDs(currentACL) 72 newTeamIDs := agent.cacheManager.GetTeamsIDsInAPIServices() 73 if len(newTeamIDs) == 0 { 74 return nil 75 } 76 77 sort.Strings(newTeamIDs) 78 if currentTeamIDs != nil && strings.Join(newTeamIDs, "") == strings.Join(currentTeamIDs, "") { 79 return nil 80 } 81 if err := j.updateACL(newTeamIDs); err != nil { 82 return fmt.Errorf("acl update job failed: %s", err) 83 } 84 return nil 85 } 86 87 func (j aclUpdateJob) getACLsFromServer() *v1.ResourceInstance { 88 emptyACL, _ := management.NewAccessControlList("", management.EnvironmentGVK().Kind, agent.cfg.GetEnvironmentName()) 89 acls, err := agent.apicClient.GetResources(emptyACL) 90 if err != nil { 91 return nil 92 } 93 94 for _, acl := range acls { 95 ri, _ := acl.AsInstance() 96 if ri.Name == j.getACLName() { 97 agent.cacheManager.SetAccessControlList(ri) 98 return ri 99 } 100 } 101 return nil 102 } 103 104 func (j *aclUpdateJob) getACLName() string { 105 return fmt.Sprintf(envACLFormat, GetCentralConfig().GetEnvironmentName()) 106 } 107 108 func (j *aclUpdateJob) initializeACLJob() { 109 if acl := agent.cacheManager.GetAccessControlList(); acl != nil { 110 return 111 } 112 113 acl, err := agent.apicClient.GetAccessControlList(j.getACLName()) 114 if err != nil { 115 return 116 } 117 118 if aclInstance, err := acl.AsInstance(); err == nil { 119 agent.cacheManager.SetAccessControlList(aclInstance) 120 } 121 } 122 123 func (j *aclUpdateJob) createACLResource(teamIDs []string) *management.AccessControlList { 124 acl, _ := management.NewAccessControlList( 125 j.getACLName(), 126 management.EnvironmentGVK().Kind, 127 agent.cfg.GetEnvironmentName(), 128 ) 129 acl.Spec = management.AccessControlListSpec{ 130 Rules: []management.AccessRules{ 131 { 132 Access: []management.AccessLevelScope{ 133 { 134 Level: "scope", 135 }, 136 }, 137 }, 138 }, 139 } 140 141 // Add all the teams 142 acl.Spec.Subjects = make([]v1.Owner, 0) 143 for _, id := range teamIDs { 144 acl.Spec.Subjects = append(acl.Spec.Subjects, v1.Owner{ 145 Type: v1.TeamOwner, 146 ID: id, 147 }) 148 } 149 150 return acl 151 } 152 153 func (j *aclUpdateJob) updateACL(teamIDs []string) error { 154 // do not add an acl if there are no teamIDs and an ACL currently does not exist 155 currentACL := agent.cacheManager.GetAccessControlList() 156 if len(teamIDs) == 0 && currentACL == nil { 157 return nil 158 } 159 160 var err error 161 j.logger.Trace("acl about to be updated") 162 acl := j.createACLResource(teamIDs) 163 if currentACL != nil { 164 acl, err = agent.apicClient.UpdateAccessControlList(acl) 165 } else { 166 acl, err = agent.apicClient.CreateAccessControlList(acl) 167 } 168 169 if err == nil { 170 aclInstance, err := acl.AsInstance() 171 if err == nil { 172 agent.cacheManager.SetAccessControlList(aclInstance) 173 } 174 } 175 176 return err 177 } 178 179 // registerAccessControlListHandler - 180 func registerAccessControlListHandler() { 181 job := newACLUpdateJob() 182 183 jobs.RegisterIntervalJobWithName(job, agent.cfg.GetPollInterval(), "Access Control List") 184 }