create.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package environment_groups
  2. import (
  3. "net/http"
  4. "time"
  5. "connectrpc.com/connect"
  6. porterv1 "github.com/porter-dev/api-contracts/generated/go/porter/v1"
  7. "github.com/porter-dev/porter/api/server/authz"
  8. "github.com/porter-dev/porter/api/server/handlers"
  9. "github.com/porter-dev/porter/api/server/shared"
  10. "github.com/porter-dev/porter/api/server/shared/apierrors"
  11. "github.com/porter-dev/porter/api/server/shared/config"
  12. "github.com/porter-dev/porter/api/types"
  13. "github.com/porter-dev/porter/internal/models"
  14. "github.com/porter-dev/porter/internal/telemetry"
  15. )
  16. type UpdateEnvironmentGroupHandler struct {
  17. handlers.PorterHandlerReadWriter
  18. authz.KubernetesAgentGetter
  19. }
  20. func NewUpdateEnvironmentGroupHandler(
  21. config *config.Config,
  22. decoderValidator shared.RequestDecoderValidator,
  23. writer shared.ResultWriter,
  24. ) *UpdateEnvironmentGroupHandler {
  25. return &UpdateEnvironmentGroupHandler{
  26. PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
  27. KubernetesAgentGetter: authz.NewOutOfClusterAgentGetter(config),
  28. }
  29. }
  30. // EnvVariableDeletions is the set of keys to delete from the environment group
  31. type EnvVariableDeletions struct {
  32. // Variables is a set of variable keys to delete from the environment group
  33. Variables []string `json:"variables"`
  34. // Secrets is a set of secret variable keys to delete from the environment group
  35. Secrets []string `json:"secrets"`
  36. }
  37. type UpdateEnvironmentGroupRequest struct {
  38. // Name of the env group to create or update
  39. Name string `json:"name"`
  40. // Type of the env group to create or update
  41. Type string `json:"type"`
  42. // AuthToken for the env group
  43. AuthToken string `json:"auth_token"`
  44. // Variables are values which are not sensitive. All values must be a string due to a kubernetes limitation.
  45. Variables map[string]string `json:"variables"`
  46. // SecretVariables are sensitive values. All values must be a string due to a kubernetes limitation.
  47. SecretVariables map[string]string `json:"secret_variables"`
  48. // IsEnvOverride is a flag to determine if provided variables should override or merge with existing variables
  49. IsEnvOverride bool `json:"is_env_override"`
  50. // Deletions is a set of keys to delete from the environment group
  51. Deletions EnvVariableDeletions `json:"deletions"`
  52. // SkipAppAutoDeploy is a flag to determine if the app should be auto deployed
  53. SkipAppAutoDeploy bool `json:"skip_app_auto_deploy"`
  54. }
  55. type UpdateEnvironmentGroupResponse struct {
  56. // Name of the env group to create or update
  57. Name string `json:"name"`
  58. // Variables are variables which should are not sensitive. All values must be a string due to a kubernetes limitation.
  59. Variables map[string]string `json:"variables,omitempty"`
  60. // SecretVariables are sensitive variables. All values must be a string due to a kubernetes limitation.
  61. SecretVariables map[string]string `json:"secret_variables,omitempty"`
  62. CreatedAt time.Time `json:"created_at"`
  63. }
  64. func (c *UpdateEnvironmentGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  65. ctx, span := telemetry.NewSpan(r.Context(), "serve-update-env-group")
  66. defer span.End()
  67. request := &UpdateEnvironmentGroupRequest{}
  68. if ok := c.DecodeAndValidate(w, r, request); !ok {
  69. return
  70. }
  71. cluster, _ := ctx.Value(types.ClusterScope).(*models.Cluster)
  72. telemetry.WithAttributes(span,
  73. telemetry.AttributeKV{Key: "environment-group-name", Value: request.Name},
  74. telemetry.AttributeKV{Key: "environment-group-type", Value: request.Type},
  75. )
  76. switch request.Type {
  77. case "doppler":
  78. _, err := c.Config().ClusterControlPlaneClient.CreateOrUpdateEnvGroup(ctx, connect.NewRequest(&porterv1.CreateOrUpdateEnvGroupRequest{
  79. ProjectId: int64(cluster.ProjectID),
  80. ClusterId: int64(cluster.ID),
  81. EnvGroupProviderType: porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_DOPPLER,
  82. EnvGroupName: request.Name,
  83. EnvGroupAuthToken: request.AuthToken,
  84. }))
  85. if err != nil {
  86. err := telemetry.Error(ctx, span, err, "unable to create environment group")
  87. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  88. return
  89. }
  90. default:
  91. _, err := c.Config().ClusterControlPlaneClient.CreateOrUpdateEnvGroup(ctx, connect.NewRequest(&porterv1.CreateOrUpdateEnvGroupRequest{
  92. ProjectId: int64(cluster.ProjectID),
  93. ClusterId: int64(cluster.ID),
  94. EnvGroupProviderType: porterv1.EnumEnvGroupProviderType_ENUM_ENV_GROUP_PROVIDER_TYPE_PORTER,
  95. EnvGroupName: request.Name,
  96. EnvVars: &porterv1.EnvGroupVariables{
  97. Normal: request.Variables,
  98. Secret: request.SecretVariables,
  99. },
  100. EnvVariableDeletions: &porterv1.EnvVariableDeletions{
  101. Variables: request.Deletions.Variables,
  102. Secrets: request.Deletions.Secrets,
  103. },
  104. IsEnvOverride: request.IsEnvOverride,
  105. SkipAppAutoDeploy: request.SkipAppAutoDeploy,
  106. }))
  107. if err != nil {
  108. err := telemetry.Error(ctx, span, err, "unable to create environment group")
  109. c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  110. return
  111. }
  112. }
  113. envGroupResponse := &UpdateEnvironmentGroupResponse{
  114. Name: request.Name,
  115. CreatedAt: time.Now().UTC(),
  116. }
  117. c.WriteResult(w, r, envGroupResponse)
  118. }