Skip to content

Commit

Permalink
unswallow host extracting errors
Browse files Browse the repository at this point in the history
  • Loading branch information
cam-garrison committed Jul 30, 2024
1 parent 9946592 commit ee26b50
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 20 deletions.
33 changes: 27 additions & 6 deletions controllers/authorization/authorization_reconcile_authconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,16 @@ import (
)

func (r *PlatformAuthorizationReconciler) reconcileAuthConfig(ctx context.Context, target *unstructured.Unstructured) error {
authType, err := r.typeDetector.Detect(ctx, target)
templ, err := r.detectAndLoadTemplate(ctx, target)
if err != nil {
return fmt.Errorf("could not detect authtype: %w", err)
return err
}

templ, err := r.templateLoader.Load(ctx, authType, types.NamespacedName{Namespace: target.GetNamespace(), Name: target.GetName()})
hosts, err := r.extractHosts(target)
if err != nil {
return fmt.Errorf("could not load template %s: %w", authType, err)
return err
}

hosts := r.hostExtractor.Extract(target)

desired, err := createAuthConfig(templ, hosts, target)
if err != nil {
return fmt.Errorf("could not create destired AuthConfig: %w", err)
Expand Down Expand Up @@ -117,3 +115,26 @@ func CompareAuthConfigs(m1, m2 *authorinov1beta2.AuthConfig) bool {
return reflect.DeepEqual(m1.ObjectMeta.Labels, m2.ObjectMeta.Labels) &&
reflect.DeepEqual(m1.Spec, m2.Spec)
}

func (r *PlatformAuthorizationReconciler) detectAndLoadTemplate(ctx context.Context, target *unstructured.Unstructured) (authorinov1beta2.AuthConfig, error) {
authType, err := r.typeDetector.Detect(ctx, target)
if err != nil {
return authorinov1beta2.AuthConfig{}, fmt.Errorf("could not detect authtype: %w", err)
}

templ, err := r.templateLoader.Load(ctx, authType, types.NamespacedName{Namespace: target.GetNamespace(), Name: target.GetName()})
if err != nil {
return authorinov1beta2.AuthConfig{}, fmt.Errorf("could not load template %s: %w", authType, err)
}

return templ, nil
}

func (r *PlatformAuthorizationReconciler) extractHosts(target *unstructured.Unstructured) ([]string, error) {
hosts, err := r.hostExtractor.Extract(target)
if err != nil {
return nil, fmt.Errorf("could not extract host: %w", err)
}

return hosts, nil
}
43 changes: 32 additions & 11 deletions pkg/resource/authorization/authconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,27 +141,46 @@ func NewExpressionHostExtractor(paths []string) spi.HostExtractor {
return &expressionHostExtractor{paths: paths}
}

func (k *expressionHostExtractor) Extract(target *unstructured.Unstructured) []string {
func (k *expressionHostExtractor) Extract(target *unstructured.Unstructured) ([]string, error) {
hosts := []string{}

for _, path := range k.paths {
splitPath := strings.Split(path, ".")
extractedHosts, err := extractHosts(target, splitPath)

if foundHost, foundStr, errNestedStr := unstructured.NestedString(target.Object, splitPath...); errNestedStr == nil && foundStr {
hosts = appendHosts(hosts, foundHost)
if err != nil {
return nil, fmt.Errorf("failed to extract hosts at path %s: %w", path, err)
}

if foundHosts, foundSlice, errNestedSlice := unstructured.NestedStringSlice(target.Object, splitPath...); errNestedSlice == nil && foundSlice {
hosts = appendHosts(hosts, foundHosts...)
parsedHosts, errAppend := appendHosts(hosts, extractedHosts...)

if errAppend != nil {
return nil, fmt.Errorf("failed to append hosts %v: %w", extractedHosts, errAppend)
}

hosts = parsedHosts
}

u := unique(hosts)
if len(u) == 0 {
return []string{"unknown.host.com"}
return []string{"unknown.host.com"}, nil
}

return u
return u, nil
}

func extractHosts(target *unstructured.Unstructured, splitPath []string) ([]string, error) {
// extracting as string
if foundHost, found, err := unstructured.NestedString(target.Object, splitPath...); err == nil && found {
return []string{foundHost}, nil
}

// extracting as slice of strings
if foundHosts, found, err := unstructured.NestedStringSlice(target.Object, splitPath...); err == nil && found {
return foundHosts, nil
}

return nil, fmt.Errorf("neither string nor slice of strings found at path %v", splitPath)
}

func unique(in []string) []string {
Expand All @@ -183,19 +202,21 @@ func unique(in []string) []string {
return keys
}

func appendHosts(hosts []string, foundHosts ...string) []string {
func appendHosts(hosts []string, foundHosts ...string) ([]string, error) {
for _, foundHost := range foundHosts {
if isURI(foundHost) {
parsedURL, errParse := url.Parse(foundHost)
if errParse == nil {
hosts = append(hosts, parsedURL.Host)
if errParse != nil {
return nil, fmt.Errorf("failed to parse URL %s: %w", foundHost, errParse)
}

hosts = append(hosts, parsedURL.Host)
} else {
hosts = append(hosts, foundHost)
}
}

return hosts
return hosts, nil
}

func isURI(host string) bool {
Expand Down
6 changes: 4 additions & 2 deletions pkg/resource/authorization/authconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ var _ = Describe("AuthConfig functions", Label(labels.Unit), func() {
}

// when
hosts := extractor.Extract(&target)
hosts, err := extractor.Extract(&target)

// then
Expect(err).To(Not(HaveOccurred()))
Expect(hosts).To(HaveExactElements("test.com"))
})

Expand All @@ -39,9 +40,10 @@ var _ = Describe("AuthConfig functions", Label(labels.Unit), func() {
unstructured.SetNestedStringSlice(target.Object, []string{"test.com", "test2.com"}, "status", "url")

// when
hosts := extractor.Extract(&target)
hosts, err := extractor.Extract(&target)

// then
Expect(err).To(Not(HaveOccurred()))
Expect(hosts).To(ContainElements("test.com", "test2.com"))
})

Expand Down
2 changes: 1 addition & 1 deletion pkg/spi/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (a AuthorizationComponent) Load(configPath string) ([]AuthorizationComponen

// HostExtractor attempts to extract Hosts from the given resource.
type HostExtractor interface {
Extract(res *unstructured.Unstructured) []string
Extract(res *unstructured.Unstructured) ([]string, error)
}

// AuthTypeDetector attempts to determine the AuthType for the given resource
Expand Down

0 comments on commit ee26b50

Please sign in to comment.