Skip to content

Commit

Permalink
support endpoint to clear fetch ttl
Browse files Browse the repository at this point in the history
  • Loading branch information
jcvrabo committed Dec 13, 2024
1 parent 084d52b commit c938e51
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 94 deletions.
11 changes: 10 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func Server() {
securityFilter := security.Filter(true).
Path("/health", "/info").Anonymous().
Path("/credentials").Authorize(security.AuthorizationFunc(localhost)).
Path("/secrets", "/secrets/add", "/secrets/delete", "/secrets/list").Authentication(bearerAuthenticationProvider).Authorize(allowedUsers).
Path("/secrets", "/secrets/add", "/secrets/delete", "/secrets/list", "/cache").Authentication(bearerAuthenticationProvider).Authorize(allowedUsers).
Path("/dashboard").Authentication(ssoAuthenticationProvider).Authorize(allowedUsers).
Path("/**").Authentication(bearerAuthenticationProvider).Authorize(security.Scope("config_hub_" + cfg.ServiceInstanceId + ".read")).
Build()
Expand All @@ -64,6 +64,9 @@ func Server() {
engine.HandleMethod("GET", "/secrets/list", credhub_source.ListSecretsCompatible)
engine.HandleMethod("GET", "/secrets", credhub_source.ListSecrets)

// Cache endpoints
engine.HandleMethod("DELETE", "/cache", deleteCache)

// dashboard
engine.HandleMethod("GET", "/dashboard", sources.Dashboard)

Expand All @@ -82,6 +85,12 @@ func localhost(_ *security.User, scope we.RequestScope) bool {
return parts[0] == "127.0.0.1"
}

func deleteCache(w we.ResponseWriter, _ we.RequestScope) error {
l.Debugf("Clearing caches from all supporting sources")
w.WriteHeader(http.StatusNoContent)
return sources.DeleteCache()
}

func findProperties(w we.ResponseWriter, scope we.RequestScope) error {
app := scope.Var("app")
var profiles []string
Expand Down
4 changes: 4 additions & 0 deletions sources/credhub_source/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ type source struct {
client credhub.Client
}

func (s *source) ClearCache() {
// do nothing, credhub secrets are not cached at the source
}

func (s *source) String() string {
return fmt.Sprintf("CredhubSource{prefix:%s}", s.prefix)
}
Expand Down
8 changes: 7 additions & 1 deletion sources/git_source/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,18 @@ func (r *Repository) fetch(label string) error {
return nil
}

func (r *Repository) ClearTTL() {
r.lock.Lock()
defer r.lock.Unlock()
r.lastFetch = 0
}

func (r *Repository) Refresh(label string) error {
r.lock.Lock()
defer r.lock.Unlock()
if r.currentRef == label {
if r.detached {
// current head is the requested label and it's detached (commit reference)
// current head is the requested label, and it's detached (commit reference)
return nil
} else if r.lastFetch+r.fetchTtl > time.Now().Unix() {
// still valid fetch
Expand Down
187 changes: 95 additions & 92 deletions sources/git_source/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import (
"io"
"os"
"path"
"reflect"
"regexp"
"strconv"
"strings"
"sync"

Expand Down Expand Up @@ -119,6 +117,11 @@ func (s *source) DashboardReport() *string {
return &report
}

func (s *source) ClearCache() {
l.Debugf("Clearing cache for git source %s", s.repo)
s.repository.ClearTTL()
}

func (s *source) FindProperties(apps []string, profiles []string, requestedLabel string) ([]*domain.PropertySource, error) {
l.Debugf("Finding properties from git source %s for app(s):%v, profiles:%s and label %s", s.repo, apps, profiles, requestedLabel)

Expand Down Expand Up @@ -418,96 +421,96 @@ func readYamlFile(file *os.File) (map[string]interface{}, error) {
return object, e
}

func flattenProperties(prefix string, object interface{}, properties *map[string]interface{}) error {

errors := err.Errors()

if object == nil {
object = ""
}

t := reflect.ValueOf(object).Kind()
if t == reflect.Pointer {
object = reflect.ValueOf(object).Elem().Interface()
t = reflect.ValueOf(object).Kind()
}

switch t {
case reflect.Map:
// if it's a map we expect it to be a type of map[string]interface{}, although yaml allows for numbers to be keys in which case they are meant to array/map indexes...
if m, isType := object.(map[string]interface{}); isType {
for key, value := range m {
if e := flattenProperties(prefix+"."+key, value, properties); e != nil {
errors.AddError(e)
}
}
} else {
for key, value := range object.(map[any]any) {
if reflect.TypeOf(key).Kind() == reflect.Int {
if e := flattenProperties(fmt.Sprintf("%s[%v]", prefix, key), value, properties); e != nil {
errors.AddError(e)
}
} else {
if e := flattenProperties(fmt.Sprintf("%s.%v", prefix, key), value, properties); e != nil {
errors.AddError(e)
}
}
}
}
case reflect.Slice:
// if it's an array we expect it to be a type of []interface{}
if len(object.([]interface{})) == 0 {
if len(prefix) == 0 || prefix[0] != '.' {
(*properties)[prefix] = object
} else {
(*properties)[prefix[1:]] = object
}
} else {
for i, value := range object.([]interface{}) {
if e := flattenProperties(prefix+"["+strconv.Itoa(i)+"]", value, properties); e != nil {
errors.AddError(e)
}
}
}
case reflect.Array:
// if it's an array we expect it to be a type of []interface{}
if len(object.([]interface{})) == 0 {
if len(prefix) == 0 || prefix[0] != '.' {
(*properties)[prefix] = object
} else {
(*properties)[prefix[1:]] = object
}
} else {
for i, value := range object.([]interface{}) {
if e := flattenProperties(prefix+"["+strconv.Itoa(i)+"]", value, properties); e != nil {
errors.AddError(e)
}
}
}
default:
if t == reflect.String {
// special string-to-boolean cases
switch strings.ToUpper(object.(string)) {
case "OFF":
object = false
case "ON":
object = true
}
}

if len(prefix) == 0 || prefix[0] != '.' {
(*properties)[prefix] = object
} else {
(*properties)[prefix[1:]] = object
}
}

if errors.Count() > 0 {
return errors
}

return nil
}
// func flattenProperties(prefix string, object interface{}, properties *map[string]interface{}) error {
//
// errors := err.Errors()
//
// if object == nil {
// object = ""
// }
//
// t := reflect.ValueOf(object).Kind()
// if t == reflect.Pointer {
// object = reflect.ValueOf(object).Elem().Interface()
// t = reflect.ValueOf(object).Kind()
// }
//
// switch t {
// case reflect.Map:
// // if it's a map we expect it to be a type of map[string]interface{}, although yaml allows for numbers to be keys in which case they are meant to array/map indexes...
// if m, isType := object.(map[string]interface{}); isType {
// for key, value := range m {
// if e := flattenProperties(prefix+"."+key, value, properties); e != nil {
// errors.AddError(e)
// }
// }
// } else {
// for key, value := range object.(map[any]any) {
// if reflect.TypeOf(key).Kind() == reflect.Int {
// if e := flattenProperties(fmt.Sprintf("%s[%v]", prefix, key), value, properties); e != nil {
// errors.AddError(e)
// }
// } else {
// if e := flattenProperties(fmt.Sprintf("%s.%v", prefix, key), value, properties); e != nil {
// errors.AddError(e)
// }
// }
// }
// }
// case reflect.Slice:
// // if it's an array we expect it to be a type of []interface{}
// if len(object.([]interface{})) == 0 {
// if len(prefix) == 0 || prefix[0] != '.' {
// (*properties)[prefix] = object
// } else {
// (*properties)[prefix[1:]] = object
// }
// } else {
// for i, value := range object.([]interface{}) {
// if e := flattenProperties(prefix+"["+strconv.Itoa(i)+"]", value, properties); e != nil {
// errors.AddError(e)
// }
// }
// }
// case reflect.Array:
// // if it's an array we expect it to be a type of []interface{}
// if len(object.([]interface{})) == 0 {
// if len(prefix) == 0 || prefix[0] != '.' {
// (*properties)[prefix] = object
// } else {
// (*properties)[prefix[1:]] = object
// }
// } else {
// for i, value := range object.([]interface{}) {
// if e := flattenProperties(prefix+"["+strconv.Itoa(i)+"]", value, properties); e != nil {
// errors.AddError(e)
// }
// }
// }
// default:
// if t == reflect.String {
// // special string-to-boolean cases
// switch strings.ToUpper(object.(string)) {
// case "OFF":
// object = false
// case "ON":
// object = true
// }
// }
//
// if len(prefix) == 0 || prefix[0] != '.' {
// (*properties)[prefix] = object
// } else {
// (*properties)[prefix[1:]] = object
// }
// }
//
// if errors.Count() > 0 {
// return errors
// }
//
// return nil
// }

func readPropertiesFile(file *os.File) (map[string]interface{}, error) {
scanner := bufio.NewScanner(file)
Expand Down
7 changes: 7 additions & 0 deletions sources/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ func Setup() error {
return nil
}

func DeleteCache() error {
for _, source := range propertySources {
source.ClearCache()
}
return nil // prepare for future error handling
}

func FindProperties(app string, profiles []string, label string) []*domain.PropertySource {
sources := findProperties(app, profiles, label)
for i, properties := range sources {
Expand Down
1 change: 1 addition & 0 deletions sources/spi/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ type Source interface {
FindProperties(apps []string, profiles []string, label string) ([]*domain.PropertySource, error)
Name() string
DashboardReport() *string
ClearCache()
}

0 comments on commit c938e51

Please sign in to comment.