Skip to content

Commit

Permalink
App page secrets error (#4021)
Browse files Browse the repository at this point in the history
* Do not check for secrets when retrieving hr inventory if spec kubeconfig is set up

* Refactor getHelmReleaseInventory to use getHelmReleaseObjects

* Add test for spec kubeconfig scenario

* Add test for spec kubeconfig scenario - updated

* Add test for spec kubeconfig scenario - updated2

* Show user info alert when spec kubeconfig is set

* Solve linting warnings
  • Loading branch information
AlinaGoaga authored Sep 21, 2023
1 parent 388acf4 commit 565e1d4
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 67 deletions.
64 changes: 4 additions & 60 deletions core/server/helm_release.go
Original file line number Diff line number Diff line change
@@ -1,81 +1,25 @@
package server

import (
"bytes"
"compress/gzip"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"strings"

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
"github.com/fluxcd/pkg/ssa"
"github.com/weaveworks/weave-gitops/core/clustersmngr"
"github.com/weaveworks/weave-gitops/core/server/types"
pb "github.com/weaveworks/weave-gitops/pkg/api/core"
v1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func getHelmReleaseInventory(ctx context.Context, helmRelease helmv2.HelmRelease, c clustersmngr.Client, cluster string) ([]*pb.GroupVersionKind, error) {
storageNamespace := helmRelease.GetStorageNamespace()

storageName := helmRelease.GetReleaseName()

storageVersion := helmRelease.Status.LastReleaseRevision
if storageVersion < 1 {
// skip release if it failed to install
return nil, nil
}

storageSecret := &v1.Secret{}
secretName := fmt.Sprintf("sh.helm.release.v1.%s.v%v", storageName, storageVersion)
key := client.ObjectKey{
Name: secretName,
Namespace: storageNamespace,
}

if err := c.Get(ctx, cluster, key, storageSecret); err != nil {
return nil, err
}

releaseData, releaseFound := storageSecret.Data["release"]
if !releaseFound {
return nil, fmt.Errorf("failed to decode the Helm storage object for HelmRelease '%s'", helmRelease.Name)
}

byteData, err := base64.StdEncoding.DecodeString(string(releaseData))
k8sClient, err := c.Scoped(cluster)
if err != nil {
return nil, err
}

var magicGzip = []byte{0x1f, 0x8b, 0x08}
if bytes.Equal(byteData[0:3], magicGzip) {
r, err := gzip.NewReader(bytes.NewReader(byteData))
if err != nil {
return nil, err
}

defer r.Close()

uncompressedByteData, err := io.ReadAll(r)
if err != nil {
return nil, err
}

byteData = uncompressedByteData
return nil, fmt.Errorf("error getting scoped client for cluster=%s: %w", cluster, err)
}

storage := types.HelmReleaseStorage{}
if err := json.Unmarshal(byteData, &storage); err != nil {
return nil, fmt.Errorf("failed to decode the Helm storage object for HelmRelease '%s': %w", helmRelease.Name, err)
}
objects, err := getHelmReleaseObjects(ctx, k8sClient, &helmRelease)

objects, err := ssa.ReadObjects(strings.NewReader(storage.Manifest))
if err != nil {
return nil, fmt.Errorf("failed to read the Helm storage object for HelmRelease '%s': %w", helmRelease.Name, err)
return nil, err
}

var gvk []*pb.GroupVersionKind
Expand Down
5 changes: 5 additions & 0 deletions core/server/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ func getHelmReleaseObjects(ctx context.Context, k8sClient client.Client, helmRel
Namespace: storageNamespace,
}

if helmRelease.Spec.KubeConfig != nil {
// helmrelease secret is on another cluster so we cannot inspect it to figure out the inventory and version and other things
return nil, nil
}

if err := k8sClient.Get(ctx, key, storageSecret); err != nil {
return nil, err
}
Expand Down
47 changes: 47 additions & 0 deletions core/server/inventory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
. "github.com/onsi/gomega"
"github.com/weaveworks/weave-gitops/core/clustersmngr/cluster"
Expand Down Expand Up @@ -270,3 +271,49 @@ func TestGetInventoryHelmRelease(t *testing.T) {
g.Expect(err).NotTo(HaveOccurred())
g.Expect(res.Entries).To(HaveLen(1))
}

func TestGetInventoryHelmReleaseWithKubeconfig(t *testing.T) {
g := NewGomegaWithT(t)

scheme, err := kube.CreateScheme()
g.Expect(err).NotTo(HaveOccurred())

ctx := context.Background()

ns := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
},
}
helm1 := &helmv2.HelmRelease{
ObjectMeta: metav1.ObjectMeta{
Name: "first-helm-name",
Namespace: ns.Name,
},
Spec: helmv2.HelmReleaseSpec{
KubeConfig: &meta.KubeConfigReference{
SecretRef: meta.SecretKeyReference{
Name: "kubeconfig",
},
},
},
Status: helmv2.HelmReleaseStatus{
LastReleaseRevision: 1,
},
}

client := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(ns, helm1).Build()
cfg := makeServerConfig(client, t, "")
c := makeServer(cfg, t)

res, err := c.GetInventory(ctx, &pb.GetInventoryRequest{
Namespace: ns.Name,
ClusterName: cluster.DefaultCluster,
Kind: "HelmRelease",
Name: helm1.Name,
WithChildren: true,
})

g.Expect(err).NotTo(HaveOccurred())
g.Expect(res.Entries).To(HaveLen(0))
}
17 changes: 14 additions & 3 deletions ui/components/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Alert as MaterialAlert, AlertTitle } from "@material-ui/lab";
import * as React from "react";
import styled from "styled-components";
import { ThemeTypes } from "../contexts/AppContext";
import Flex from "./Flex";
import Icon, { IconType } from "./Icon";
import Text from "./Text";
Expand All @@ -23,9 +24,7 @@ function UnstyledAlert({ center, title, message, severity, className }: Props) {
return (
<Flex wide start={!center} className={className}>
<MaterialAlert
icon={
<Icon type={IconType.ErrorIcon} size="medium" color="alertDark" />
}
icon={<Icon type={IconType.ErrorIcon} size="medium" />}
severity={severity}
>
<AlertTitle>{title}</AlertTitle>
Expand All @@ -37,11 +36,23 @@ function UnstyledAlert({ center, title, message, severity, className }: Props) {

const Alert = styled(UnstyledAlert)`
.MuiAlert-standardError {
svg {
color: ${(props) => props.theme.colors.alertDark};
}
background-color: ${(props) => props.theme.colors.alertLight};
}
.MuiAlertTitle-root {
color: ${(props) => props.theme.colors.black};
}
.MuiAlert-standardInfo {
svg {
color: ${(props) => props.theme.colors.primary10};
}
background-color: ${(props) =>
props.theme.mode === ThemeTypes.Dark
? props.theme.colors.primary20
: null};
}
`;

export default Alert;
17 changes: 13 additions & 4 deletions ui/components/AutomationDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createCanaryCondition, useGetInventory } from "../hooks/inventory";
import { Condition, Kind, ObjectRef } from "../lib/api/core/types.pb";
import { Automation, HelmRelease } from "../lib/objects";
import { automationLastUpdated } from "../lib/utils";
import Alert from "./Alert";
import Collapsible from "./Collapsible";
import DependenciesView from "./DependenciesView";
import EventsTable from "./EventsTable";
Expand All @@ -25,6 +26,9 @@ import Text from "./Text";
import Timestamp from "./Timestamp";
import YamlView from "./YamlView";

const hrInfoMessage =
"spec.Kubeconfig is set on this HelmRelease. Details about reconciled objects are not available.";

type Props = {
automation: Automation;
className?: string;
Expand Down Expand Up @@ -87,10 +91,15 @@ function AutomationDetail({
component: () => {
return (
<RequestStateHandler loading={isLoading} error={error}>
<ReconciledObjectsTable
className={className}
objects={data?.objects}
/>
{automation.type === "HelmRelease" &&
(automation as HelmRelease).kubeConfig === "" ? (
<ReconciledObjectsTable
className={className}
objects={data?.objects}
/>
) : (
<Alert severity="info" title="Note" message={hrInfoMessage} />
)}
</RequestStateHandler>
);
},
Expand Down
4 changes: 4 additions & 0 deletions ui/lib/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ export class HelmRelease extends FluxObject {
get lastAttemptedRevision(): string {
return this.obj.status?.lastAttemptedRevision || "";
}

get kubeConfig(): string {
return this.obj.spec?.kubeConfig?.secretRef?.name || "";
}
}

export class Provider extends FluxObject {
Expand Down

0 comments on commit 565e1d4

Please sign in to comment.