github.com/Axway/agent-sdk@v1.1.101/pkg/agent/credendtialvalidator.go (about) 1 package agent 2 3 import ( 4 "sync" 5 "time" 6 7 v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1" 8 management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" 9 "github.com/Axway/agent-sdk/pkg/apic/provisioning" 10 "github.com/Axway/agent-sdk/pkg/config" 11 "github.com/Axway/agent-sdk/pkg/jobs" 12 "github.com/Axway/agent-sdk/pkg/util/log" 13 ) 14 15 const ( 16 status = "status" 17 state = "state" 18 ) 19 20 type cacheManager interface { 21 GetWatchResourceCacheKeys(group, kind string) []string 22 GetWatchResourceByKey(key string) *v1.ResourceInstance 23 } 24 25 type apicClient interface { 26 UpdateResourceInstance(ri v1.Interface) (*v1.ResourceInstance, error) 27 CreateSubResource(rm v1.ResourceMeta, subs map[string]interface{}) error 28 } 29 30 type credentialValidator struct { 31 jobs.Job 32 id string 33 logger log.FieldLogger 34 cacheManager cacheManager 35 client apicClient 36 } 37 38 func newCredentialChecker(cacheManager cacheManager, client apicClient) *credentialValidator { 39 return &credentialValidator{ 40 logger: log.NewFieldLogger().WithComponent("credentialValidator"), 41 cacheManager: cacheManager, 42 client: client, 43 } 44 } 45 46 // Ready - 47 func (j *credentialValidator) Ready() bool { 48 return true 49 } 50 51 // Status - 52 func (j *credentialValidator) Status() error { 53 return nil 54 } 55 56 // Execute - 57 func (j *credentialValidator) Execute() error { 58 j.logger.Debug("validating credentials for expiration") 59 60 if agent.cfg.GetCredentialConfig() == nil || 61 !agent.cfg.GetCredentialConfig().ShouldDeprovisionExpired() { 62 return nil 63 } 64 65 // Get all of the credentials from the cache 66 credKeys := j.cacheManager.GetWatchResourceCacheKeys(management.CredentialGVK().Group, management.CredentialGVK().Kind) 67 68 // loop all the keys in the cache and check if any have expired 69 now := time.Now() 70 wg := &sync.WaitGroup{} 71 for _, k := range credKeys { 72 wg.Add(1) 73 func(credKey string) { 74 j.validateCredential(credKey, now) 75 }(k) 76 } 77 78 return nil 79 } 80 81 func (j *credentialValidator) validateCredential(credKey string, now time.Time) { 82 logger := j.logger.WithField("cacheKey", credKey) 83 res := j.cacheManager.GetWatchResourceByKey(credKey) 84 if res == nil { 85 logger.Error("could not get resource by key") 86 return 87 } 88 89 cred := &management.Credential{} 90 err := cred.FromInstance(res) 91 if err != nil { 92 logger.WithError(err).Error("could not convert resource instance to credential") 93 return 94 } 95 96 if cred.Policies.Expiry == nil { 97 return 98 } 99 100 expTime := time.Time(cred.Policies.Expiry.Timestamp) 101 if expTime.IsZero() { 102 // cred does not expire 103 return 104 } 105 106 logger = logger.WithField("credName", cred.Name).WithField("expiration", expTime.Format(v1.APIServerTimeFormat)) 107 logger.Trace("validating credential") 108 109 if expTime.Before(now) { 110 logger.Info("Credential has expired, updating Central") 111 cred.Status.Level = provisioning.Pending.String() 112 113 // update state so the inactivated credential will come back for removal 114 cred.Spec.State = management.CredentialSpecState{ 115 Name: v1.Inactive, 116 Reason: provisioning.CredExpDetail, 117 } 118 119 // only update a subset of the sub resources 120 subResources := map[string]interface{}{ 121 status: cred.Status, 122 state: cred.State, 123 } 124 125 _, err = j.client.UpdateResourceInstance(cred) 126 if err != nil { 127 logger.WithError(err).Error("error update credential resources") 128 } 129 130 err = j.client.CreateSubResource(cred.ResourceMeta, subResources) 131 if err != nil { 132 logger.WithError(err).Error("error creating subresources") 133 } 134 } 135 } 136 137 func registerCredentialChecker() *credentialValidator { 138 c := newCredentialChecker(agent.cacheManager, agent.apicClient) 139 140 err := agent.cfg.SetWatchResourceFilters([]config.ResourceFilter{ 141 { 142 Group: management.CredentialGVK().Group, 143 Kind: management.CredentialGVK().Kind, 144 Name: "*", 145 IsCachedResource: true, 146 }, 147 }) 148 if err != nil { 149 c.logger.WithError(err).Error("could not watch for the credential resource in the credential validator job") 150 return nil 151 } 152 153 id, err := jobs.RegisterScheduledJobWithName(c, "@hourly", "CredentialValidator") 154 if err != nil { 155 c.logger.WithError(err).Error("could not start the credential validator job") 156 return nil 157 } 158 c.logger.Debug("registered the credential validator") 159 c.id = id 160 161 return c 162 }