Skip to content

Commit

Permalink
infisical ui updates (#4570)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianedwards authored Apr 23, 2024
1 parent f91cb09 commit b765d7e
Show file tree
Hide file tree
Showing 20 changed files with 703 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,20 @@ func NewAreExternalProvidersEnabledHandler(
}
}

// AreExternalProvidersEnabledResponse is the response object for the /environment-group/are-external-providers-enabled endpoint
type AreExternalProvidersEnabledResponse struct {
// ExternalEnvGroupOperator is the type of external env group operator, which syncs secrets from external sources
type ExternalEnvGroupOperator string

const (
// ExternalEnvGroupOperator_ExternalSecrets is the external secrets operator
ExternalEnvGroupOperator_ExternalSecrets ExternalEnvGroupOperator = "external-secrets"
// ExternalEnvGroupOperator_Infisical is the infisical secrets operator
ExternalEnvGroupOperator_Infisical ExternalEnvGroupOperator = "infisical"
)

// ExternalEnvGroupOperatorEnabledStatus is the status of an external env group operator
type ExternalEnvGroupOperatorEnabledStatus struct {
// Type is the type of external provider
Type ExternalEnvGroupOperator `json:"type"`
// Enabled is true if external providers are enabled
Enabled bool `json:"enabled"`
// ReprovisionRequired is true if the cluster needs to be reprovisioned to enable external providers
Expand All @@ -44,6 +56,11 @@ type AreExternalProvidersEnabledResponse struct {
K8SUpgradeRequired bool `json:"k8s_upgrade_required"`
}

// AreExternalProvidersEnabledResponse is the response object for the /environment-group/are-external-providers-enabled endpoint
type AreExternalProvidersEnabledResponse struct {
Operators []ExternalEnvGroupOperatorEnabledStatus `json:"operators"`
}

// ServeHTTP checks if external providers are enabled
func (c *AreExternalProvidersEnabledHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx, span := telemetry.NewSpan(r.Context(), "serve-are-external-providers-enabled")
Expand All @@ -62,9 +79,27 @@ func (c *AreExternalProvidersEnabledHandler) ServeHTTP(w http.ResponseWriter, r
return
}

var operators []ExternalEnvGroupOperatorEnabledStatus
for _, operator := range resp.Msg.Operators {
var operatorType ExternalEnvGroupOperator
switch operator.Operator {
case porterv1.EnumExternalEnvGroupOperatorType_ENUM_EXTERNAL_ENV_GROUP_OPERATOR_TYPE_EXTERNAL_SECRETS:
operatorType = ExternalEnvGroupOperator_ExternalSecrets
case porterv1.EnumExternalEnvGroupOperatorType_ENUM_EXTERNAL_ENV_GROUP_OPERATOR_TYPE_INFISICAL:
operatorType = ExternalEnvGroupOperator_Infisical
default:
continue
}

operators = append(operators, ExternalEnvGroupOperatorEnabledStatus{
Type: operatorType,
Enabled: operator.Enabled,
ReprovisionRequired: operator.ReprovisionRequired,
K8SUpgradeRequired: operator.K8SUpgradeRequired,
})
}

c.WriteResult(w, r, &AreExternalProvidersEnabledResponse{
Enabled: resp.Msg.Enabled,
ReprovisionRequired: resp.Msg.ReprovisionRequired,
K8SUpgradeRequired: resp.Msg.K8SUpgradeRequired,
Operators: operators,
})
}
14 changes: 12 additions & 2 deletions api/server/handlers/environment_groups/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,19 @@ func (c *DeleteEnvironmentGroupHandler) ServeHTTP(w http.ResponseWriter, r *http
)

switch request.Type {
case "doppler":
case "doppler", "infisical":
var provider porterv1.EnumEnvGroupProviderType
switch request.Type {
case "doppler":
provider = porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER
case "infisical":
provider = porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_INFISICAL
}

_, err := c.Config().ClusterControlPlaneClient.DeleteEnvGroup(ctx, connect.NewRequest(&porterv1.DeleteEnvGroupRequest{
ProjectId: int64(cluster.ProjectID),
ClusterId: int64(cluster.ID),
EnvGroupProviderType: porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER,
EnvGroupProviderType: provider,
EnvGroupName: request.Name,
}))
if err != nil {
Expand All @@ -88,4 +96,6 @@ func (c *DeleteEnvironmentGroupHandler) ServeHTTP(w http.ResponseWriter, r *http
return
}
}

c.WriteResult(w, r, nil)
}
1 change: 1 addition & 0 deletions api/server/handlers/environment_groups/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,5 +218,6 @@ func (c *ListEnvironmentGroupsHandler) ServeHTTP(w http.ResponseWriter, r *http.
var translateProtoTypeToEnvGroupType = map[porterv1.EnumEnvGroupProviderType]string{
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DATASTORE: "datastore",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER: "doppler",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_INFISICAL: "infisical",
porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_PORTER: "porter",
}
58 changes: 55 additions & 3 deletions api/server/handlers/environment_groups/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,22 @@ func NewUpdateEnvironmentGroupHandler(
}
}

// EnvironmentGroupType is the env_groups-level environment group type
type EnvironmentGroupType string

const (
// EnvironmentGroupType_Unspecified is the nil environment group type
EnvironmentGroupType_Unspecified EnvironmentGroupType = ""
// EnvironmentGroupType_Doppler is the doppler environment group type
EnvironmentGroupType_Doppler EnvironmentGroupType = "doppler"
// EnvironmentGroupType_Porter is the porter environment group type
EnvironmentGroupType_Porter EnvironmentGroupType = "porter"
// EnvironmentGroupType_Datastore is the datastore environment group type
EnvironmentGroupType_Datastore EnvironmentGroupType = "datastore"
// EnvironmentGroupType_Infisical is the infisical environment group type
EnvironmentGroupType_Infisical EnvironmentGroupType = "infisical"
)

// EnvVariableDeletions is the set of keys to delete from the environment group
type EnvVariableDeletions struct {
// Variables is a set of variable keys to delete from the environment group
Expand All @@ -42,12 +58,20 @@ type EnvVariableDeletions struct {
Secrets []string `json:"secrets"`
}

// InfisicalEnv is the Infisical environment to pull secret values from, only required for the Infisical external provider type
type InfisicalEnv struct {
// Slug is the slug referring to the Infisical environment to pull secret values from
Slug string `json:"slug"`
// Path is the relative path in the Infisical environment to pull secret values from
Path string `json:"path"`
}

type UpdateEnvironmentGroupRequest struct {
// Name of the env group to create or update
Name string `json:"name"`

// Type of the env group to create or update
Type string `json:"type"`
Type EnvironmentGroupType `json:"type"`

// AuthToken for the env group
AuthToken string `json:"auth_token"`
Expand All @@ -69,6 +93,9 @@ type UpdateEnvironmentGroupRequest struct {

// SkipAppAutoDeploy is a flag to determine if the app should be auto deployed
SkipAppAutoDeploy bool `json:"skip_app_auto_deploy"`

// InfisicalEnv is the Infisical environment to pull secret values from, only required for the Infisical external provider type
InfisicalEnv InfisicalEnv `json:"infisical_env"`
}
type UpdateEnvironmentGroupResponse struct {
// Name of the env group to create or update
Expand Down Expand Up @@ -99,13 +126,38 @@ func (c *UpdateEnvironmentGroupHandler) ServeHTTP(w http.ResponseWriter, r *http
)

switch request.Type {
case "doppler":
case EnvironmentGroupType_Doppler, EnvironmentGroupType_Infisical:
var provider porterv1.EnumEnvGroupProviderType
var infisicalEnv *porterv1.InfisicalEnv
if request.Type == EnvironmentGroupType_Doppler {
provider = porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER
}
if request.Type == EnvironmentGroupType_Infisical {
if request.InfisicalEnv.Slug == "" {
err := telemetry.Error(ctx, span, nil, "infisical env slug is required")
c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
return
}
if request.InfisicalEnv.Path == "" {
err := telemetry.Error(ctx, span, nil, "infisical env path is required")
c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
return
}

provider = porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_INFISICAL
infisicalEnv = &porterv1.InfisicalEnv{
EnvironmentSlug: request.InfisicalEnv.Slug,
EnvironmentPath: request.InfisicalEnv.Path,
}
}

_, err := c.Config().ClusterControlPlaneClient.CreateOrUpdateEnvGroup(ctx, connect.NewRequest(&porterv1.CreateOrUpdateEnvGroupRequest{
ProjectId: int64(cluster.ProjectID),
ClusterId: int64(cluster.ID),
EnvGroupProviderType: porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER,
EnvGroupProviderType: provider,
EnvGroupName: request.Name,
EnvGroupAuthToken: request.AuthToken,
InfisicalEnv: infisicalEnv,
}))
if err != nil {
err := telemetry.Error(ctx, span, err, "unable to create environment group")
Expand Down
65 changes: 65 additions & 0 deletions dashboard/src/assets/infisical.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion dashboard/src/lib/env-groups/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ export const envGroupValidator = z.object({
variables: z.record(z.string()).optional().default({}),
secret_variables: z.record(z.string()).optional().default({}),
created_at: z.string(),
linked_applications: z.array(z.string()).optional().default([]),
type: z
.string()
.pipe(
z.enum(["UNKNOWN", "datastore", "doppler", "porter"]).catch("UNKNOWN")
z
.enum(["UNKNOWN", "datastore", "doppler", "porter", "infisical"])
.catch("UNKNOWN")
),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Context } from "shared/Context";
import { envGroupPath } from "shared/util";
import database from "assets/database.svg";
import doppler from "assets/doppler.png";
import infisical from "assets/infisical.svg";
import key from "assets/key.svg";

type Props = {
Expand Down Expand Up @@ -65,22 +66,26 @@ const EnvGroupRow: React.FC<Props> = ({
return [...normalVariables, ...secretVariables];
}, [envGroup]);

const envGroupIcon = useMemo(() => {
if (envGroup.type === "doppler") {
return doppler;
}
if (envGroup.type === "datastore") {
return database;
}
if (envGroup.type === "infisical") {
return infisical;
}
return key;
}, [envGroup.type]);

return (
<Expandable
maxHeight={maxHeight}
header={
<Container row spaced>
<Container row>
<Image
size={20}
src={
envGroup.type === "doppler"
? doppler
: envGroup.type === "datastore"
? database
: key
}
/>
<Image size={20} src={envGroupIcon} />
<Spacer inline x={1} />
<Text size={14}>{envGroup.name}</Text>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ export const ExpandedEnvGroupFC = ({

const linkedApp: string[] = currentEnvGroup?.linked_applications;
// doppler env groups update themselves, and we don't want to increment the version
if (currentEnvGroup?.type !== "doppler") {
if (currentEnvGroup?.type !== "doppler" && currentEnvGroup.type !== "infisical") {
await api.createEnvironmentGroups(
"<token>",
{
Expand Down
Loading

0 comments on commit b765d7e

Please sign in to comment.