├── .air.provisioner.toml ├── .air.toml ├── .air.worker.toml ├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ ├── bug.md │ ├── change.md │ └── feature.md ├── PULL_REQUEST_TEMPLATE.md ├── actions │ ├── build-go │ │ └── action.yml │ ├── build-npm │ │ └── action.yml │ └── porter-deploy │ │ └── action.yml ├── dependabot.yml ├── golangci-lint.yaml └── workflows │ ├── app_tests_base.yml │ ├── app_tests_internal_tools.yml │ ├── app_tests_production.yml │ ├── app_tests_sandbox.yml │ ├── install_script.yml │ ├── porter_stack_porter-sandbox.yml │ ├── porter_stack_porter-ui.yml │ ├── pr_push_checks_go.yaml │ ├── pr_push_checks_node.yaml │ ├── prerelease.yaml │ ├── production.yml │ ├── release.yaml │ └── tf_provisioner.yml ├── .gitignore ├── .prettierignore ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── Taskfile.yaml ├── Tiltfile ├── api ├── authmanagement │ ├── api_token.go │ └── server.go ├── client │ ├── api.go │ ├── base.go │ ├── datastore.go │ ├── deploy.go │ ├── deployment_target.go │ ├── domain.go │ ├── env_groups.go │ ├── environment.go │ ├── event.go │ ├── git_repo.go │ ├── integration.go │ ├── k8s.go │ ├── porter_app.go │ ├── project.go │ ├── registry.go │ ├── release.go │ ├── template.go │ ├── user.go │ └── v1_stack.go ├── server │ ├── authn │ │ ├── handler.go │ │ ├── handler_test.go │ │ └── session_helpers.go │ ├── authz │ │ ├── api_contract.go │ │ ├── cluster.go │ │ ├── deployment_target.go │ │ ├── git_installation.go │ │ ├── gitlab_integration.go │ │ ├── helm_repo.go │ │ ├── infra.go │ │ ├── invite.go │ │ ├── namespace.go │ │ ├── operation.go │ │ ├── policy.go │ │ ├── policy │ │ │ ├── doc.go │ │ │ ├── loader.go │ │ │ ├── loader_test.go │ │ │ ├── policy.go │ │ │ └── policy_test.go │ │ ├── policy_test.go │ │ ├── preview_environment.go │ │ ├── project.go │ │ ├── project_test.go │ │ ├── registry.go │ │ ├── release.go │ │ └── stack.go │ ├── handlers │ │ ├── addons │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── list.go │ │ │ ├── tailscale_services.go │ │ │ └── update.go │ │ ├── api_contract │ │ │ ├── delete.go │ │ │ ├── list.go │ │ │ ├── preflight.go │ │ │ └── update.go │ │ ├── api_token │ │ │ ├── create.go │ │ │ ├── get.go │ │ │ ├── list.go │ │ │ └── revoke.go │ │ ├── billing │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── ingest.go │ │ │ ├── invoices.go │ │ │ ├── key.go │ │ │ ├── list.go │ │ │ ├── plan.go │ │ │ └── redirect_billing.go │ │ ├── cloud_provider │ │ │ ├── list_aws.go │ │ │ └── machines.go │ │ ├── cluster │ │ │ ├── agent_status.go │ │ │ ├── cluster_status.go │ │ │ ├── compliance_checks.go │ │ │ ├── create.go │ │ │ ├── create_candidate.go │ │ │ ├── create_namespace.go │ │ │ ├── delete.go │ │ │ ├── delete_namespace.go │ │ │ ├── detect_agent_installed.go │ │ │ ├── detect_prometheus_installed.go │ │ │ ├── get.go │ │ │ ├── get_incident.go │ │ │ ├── get_k8s_events.go │ │ │ ├── get_kubeconfig.go │ │ │ ├── get_logs.go │ │ │ ├── get_logs_pod_values.go │ │ │ ├── get_logs_revision_values.go │ │ │ ├── get_namespace.go │ │ │ ├── get_node.go │ │ │ ├── get_pod_metrics.go │ │ │ ├── get_pods.go │ │ │ ├── get_porter_events.go │ │ │ ├── get_porter_job_events.go │ │ │ ├── install_agent.go │ │ │ ├── list.go │ │ │ ├── list_candidates.go │ │ │ ├── list_incident_events.go │ │ │ ├── list_incidents.go │ │ │ ├── list_namespaces.go │ │ │ ├── list_nginx_ingresses.go │ │ │ ├── list_nodes.go │ │ │ ├── notify_new_incident.go │ │ │ ├── notify_resolved_incident.go │ │ │ ├── rename.go │ │ │ ├── resolve_candidate.go │ │ │ ├── stream_helm_release.go │ │ │ ├── stream_status.go │ │ │ ├── update.go │ │ │ └── upgrade_agent.go │ │ ├── cluster_integration │ │ │ └── aws │ │ │ │ └── get_cluster_info.go │ │ ├── credentials │ │ │ ├── get_credentials_ce.go │ │ │ └── get_credentials_ee.go │ │ ├── database │ │ │ ├── list.go │ │ │ └── update.go │ │ ├── datastore │ │ │ ├── create_proxy.go │ │ │ ├── credential.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── list.go │ │ │ └── update.go │ │ ├── deployment_target │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ └── list.go │ │ ├── environment │ │ │ ├── common.go │ │ │ ├── create.go │ │ │ ├── create_deployment.go │ │ │ ├── create_deployment_by_cluster.go │ │ │ ├── delete.go │ │ │ ├── delete_deployment.go │ │ │ ├── enable_pull_request.go │ │ │ ├── finalize_deployment.go │ │ │ ├── finalize_deployment_by_cluster.go │ │ │ ├── finalize_deployment_with_errors.go │ │ │ ├── finalize_deployment_with_errors_by_cluster.go │ │ │ ├── get_deployment.go │ │ │ ├── get_deployment_by_env.go │ │ │ ├── get_environment.go │ │ │ ├── list.go │ │ │ ├── list_deployments.go │ │ │ ├── list_deployments_by_cluster.go │ │ │ ├── reenable_deployment.go │ │ │ ├── toggle_new_comment.go │ │ │ ├── trigger_deployment_workflow.go │ │ │ ├── update_deployment.go │ │ │ ├── update_deployment_by_cluster.go │ │ │ ├── update_deployment_status.go │ │ │ ├── update_deployment_status_by_cluster.go │ │ │ ├── update_environment_settings.go │ │ │ └── validate_porter_yaml.go │ │ ├── environment_groups │ │ │ ├── are_external_providers_enabled.go │ │ │ ├── delete.go │ │ │ ├── enable_external_providers.go │ │ │ ├── latest_variables.go │ │ │ ├── list.go │ │ │ ├── update.go │ │ │ └── update_linked_apps.go │ │ ├── gitinstallation │ │ │ ├── get.go │ │ │ ├── get_accounts.go │ │ │ ├── get_branch_head.go │ │ │ ├── get_buildpack.go │ │ │ ├── get_contents.go │ │ │ ├── get_permissions.go │ │ │ ├── get_porter_yaml.go │ │ │ ├── get_procfile.go │ │ │ ├── get_tarball_url.go │ │ │ ├── helpers.go │ │ │ ├── install.go │ │ │ ├── list.go │ │ │ ├── list_branches.go │ │ │ ├── list_repos.go │ │ │ ├── oauth_callback.go │ │ │ ├── oauth_start.go │ │ │ ├── rerun_workflow.go │ │ │ ├── webhook.go │ │ │ ├── workflow_log_runid.go │ │ │ └── workflow_logs.go │ │ ├── handler.go │ │ ├── healthcheck │ │ │ ├── livez.go │ │ │ └── readyz.go │ │ ├── helmrepo │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── get_chart.go │ │ │ ├── list.go │ │ │ ├── list_charts.go │ │ │ └── update.go │ │ ├── infra │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── forms.go │ │ │ ├── get.go │ │ │ ├── get_operation.go │ │ │ ├── get_operation_logs.go │ │ │ ├── get_state.go │ │ │ ├── get_template.go │ │ │ ├── list.go │ │ │ ├── list_operations.go │ │ │ ├── list_templates.go │ │ │ ├── retry_create.go │ │ │ ├── retry_delete.go │ │ │ ├── stream_logs.go │ │ │ ├── stream_state.go │ │ │ └── update.go │ │ ├── invite │ │ │ ├── invite_ce.go │ │ │ └── invite_ee.go │ │ ├── job │ │ │ ├── delete.go │ │ │ ├── get_pods.go │ │ │ └── stop.go │ │ ├── metadata │ │ │ ├── get.go │ │ │ ├── list_cluster_ints.go │ │ │ ├── list_helm_repo_ints.go │ │ │ └── list_registry_ints.go │ │ ├── namespace │ │ │ ├── add_env_group_app.go │ │ │ ├── clone_env_group.go │ │ │ ├── create_env_group.go │ │ │ ├── create_stacks_env_group.go │ │ │ ├── delete_crd.go │ │ │ ├── delete_env_group.go │ │ │ ├── delete_pod.go │ │ │ ├── get_env_group.go │ │ │ ├── get_env_group_all_versions.go │ │ │ ├── get_ingress.go │ │ │ ├── get_pod.go │ │ │ ├── get_pod_events.go │ │ │ ├── get_previous_logs.go │ │ │ ├── list_env_groups.go │ │ │ ├── list_releases.go │ │ │ ├── remove_env_group_app.go │ │ │ ├── stream_job_runs.go │ │ │ ├── stream_pod_logs.go │ │ │ ├── stream_pod_logs_loki.go │ │ │ └── update_configmap.go │ │ ├── neon_integration │ │ │ └── list.go │ │ ├── notifications │ │ │ ├── get_notification_config.go │ │ │ ├── notification.go │ │ │ └── update_notification_config.go │ │ ├── oauth_callback │ │ │ ├── digitalocean.go │ │ │ ├── gitlab.go │ │ │ ├── neon.go │ │ │ ├── slack.go │ │ │ └── upstash.go │ │ ├── policy │ │ │ ├── create.go │ │ │ ├── get.go │ │ │ └── list.go │ │ ├── porter_app │ │ │ ├── analytics.go │ │ │ ├── app_env_variables.go │ │ │ ├── app_event_webhook_get.go │ │ │ ├── app_event_webhook_update.go │ │ │ ├── app_instances.go │ │ │ ├── app_metrics.go │ │ │ ├── app_notifications.go │ │ │ ├── attach_env_group.go │ │ │ ├── cloudsql.go │ │ │ ├── create.go │ │ │ ├── create_and_update_events.go │ │ │ ├── create_app.go │ │ │ ├── create_app_template.go │ │ │ ├── create_secret_and_open_pr.go │ │ │ ├── create_subdomain.go │ │ │ ├── current_app_revision.go │ │ │ ├── default_deployment_target.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── get_app_env.go │ │ │ ├── get_app_revision.go │ │ │ ├── get_app_revision_status.go │ │ │ ├── get_app_template.go │ │ │ ├── get_build.go │ │ │ ├── get_build_env.go │ │ │ ├── get_event.go │ │ │ ├── get_logs_within_time_range.go │ │ │ ├── helm_release.go │ │ │ ├── helm_release_history.go │ │ │ ├── helm_values_v2.go │ │ │ ├── job_run_cancel.go │ │ │ ├── job_status.go │ │ │ ├── job_status_by_name.go │ │ │ ├── latest_app_revisions.go │ │ │ ├── list.go │ │ │ ├── list_app_revisions.go │ │ │ ├── list_events.go │ │ │ ├── list_events_apply_v2.go │ │ │ ├── logs_apply_v2.go │ │ │ ├── manifests.go │ │ │ ├── parse.go │ │ │ ├── parse_yaml.go │ │ │ ├── pod_status.go │ │ │ ├── pods.go │ │ │ ├── predeploy_status.go │ │ │ ├── report_status.go │ │ │ ├── rollback.go │ │ │ ├── rollback_revision.go │ │ │ ├── run_app_job.go │ │ │ ├── run_app_job_status.go │ │ │ ├── run_command.go │ │ │ ├── service_status.go │ │ │ ├── status.go │ │ │ ├── stream_logs.go │ │ │ ├── templates_list.go │ │ │ ├── update_app.go │ │ │ ├── update_app_revision_status.go │ │ │ ├── update_build_settings.go │ │ │ ├── update_image.go │ │ │ └── yaml_from_revision.go │ │ ├── project │ │ │ ├── connect.go │ │ │ ├── create.go │ │ │ ├── create_tag.go │ │ │ ├── create_test.go │ │ │ ├── delete.go │ │ │ ├── delete_role.go │ │ │ ├── get.go │ │ │ ├── get_billing.go │ │ │ ├── get_onboarding.go │ │ │ ├── get_policy.go │ │ │ ├── get_test.go │ │ │ ├── get_usage.go │ │ │ ├── images.go │ │ │ ├── invite_admin.go │ │ │ ├── list.go │ │ │ ├── list_collaborators.go │ │ │ ├── list_roles.go │ │ │ ├── list_tags.go │ │ │ ├── list_test.go │ │ │ ├── referrals.go │ │ │ ├── rename.go │ │ │ ├── update_onboarding.go │ │ │ ├── update_onboarding_step.go │ │ │ └── update_role.go │ │ ├── project_integration │ │ │ ├── create_aws.go │ │ │ ├── create_azure.go │ │ │ ├── create_basic.go │ │ │ ├── create_gcp.go │ │ │ ├── create_gitlab.go │ │ │ ├── delete_gitlab.go │ │ │ ├── get_cloud_provider_permissions_status.go │ │ │ ├── get_gitlab_porter_yaml.go │ │ │ ├── get_gitlab_repo_buildpack.go │ │ │ ├── get_gitlab_repo_contents.go │ │ │ ├── get_gitlab_repo_procfile.go │ │ │ ├── list_aws.go │ │ │ ├── list_azure.go │ │ │ ├── list_do.go │ │ │ ├── list_gcp.go │ │ │ ├── list_git.go │ │ │ ├── list_gitlab.go │ │ │ ├── list_gitlab_repo_branches.go │ │ │ ├── list_gitlab_repos.go │ │ │ ├── list_oauth.go │ │ │ ├── overwrite_aws.go │ │ │ ├── preflight_check.go │ │ │ └── request_quota_increase.go │ │ ├── project_oauth │ │ │ ├── digitalocean.go │ │ │ ├── gitlab.go │ │ │ ├── neon.go │ │ │ ├── slack.go │ │ │ └── upstash.go │ │ ├── registry │ │ │ ├── create.go │ │ │ ├── create_repository.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── get_token.go │ │ │ ├── list.go │ │ │ ├── list_images.go │ │ │ ├── list_repositories.go │ │ │ └── update.go │ │ ├── release │ │ │ ├── create.go │ │ │ ├── create_addon.go │ │ │ ├── create_subdomain.go │ │ │ ├── create_webhook.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── get_all_pods.go │ │ │ ├── get_components.go │ │ │ ├── get_controllers.go │ │ │ ├── get_gha_template.go │ │ │ ├── get_history.go │ │ │ ├── get_job_status.go │ │ │ ├── get_jobs.go │ │ │ ├── get_latest_job_run.go │ │ │ ├── get_notifications.go │ │ │ ├── get_steps.go │ │ │ ├── get_webhook.go │ │ │ ├── stream_form.go │ │ │ ├── update_build_config.go │ │ │ ├── update_canonical_name.go │ │ │ ├── update_git_action_config.go │ │ │ ├── update_image_batch.go │ │ │ ├── update_notifications.go │ │ │ ├── update_rollback.go │ │ │ ├── update_steps.go │ │ │ ├── update_tags.go │ │ │ ├── upgrade.go │ │ │ └── upgrade_webhook.go │ │ ├── slack_integration │ │ │ ├── delete.go │ │ │ ├── exists.go │ │ │ └── list.go │ │ ├── stack │ │ │ ├── add_application.go │ │ │ ├── add_env_group.go │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── get.go │ │ │ ├── get_revision.go │ │ │ ├── helpers.go │ │ │ ├── list.go │ │ │ ├── list_revisions.go │ │ │ ├── remove_application.go │ │ │ ├── remove_env_group.go │ │ │ ├── rollback.go │ │ │ ├── update_source_put.go │ │ │ └── update_stack.go │ │ ├── status │ │ │ └── github.go │ │ ├── system_status │ │ │ └── history.go │ │ ├── template │ │ │ ├── get.go │ │ │ ├── get_upgrade_notes.go │ │ │ └── list.go │ │ ├── upstash_integration │ │ │ └── list.go │ │ ├── user │ │ │ ├── can_create_project.go │ │ │ ├── cli_login.go │ │ │ ├── create.go │ │ │ ├── create_ory.go │ │ │ ├── create_test.go │ │ │ ├── current.go │ │ │ ├── current_test.go │ │ │ ├── delete.go │ │ │ ├── delete_test.go │ │ │ ├── email_verify.go │ │ │ ├── email_verify_test.go │ │ │ ├── github_callback.go │ │ │ ├── github_start.go │ │ │ ├── google_callback.go │ │ │ ├── google_start.go │ │ │ ├── login.go │ │ │ ├── login_test.go │ │ │ ├── logout.go │ │ │ ├── logout_test.go │ │ │ ├── migrate.go │ │ │ ├── pw_reset.go │ │ │ ├── update_user_info.go │ │ │ ├── welcome_webhook.go │ │ │ └── welcome_webhook_test.go │ │ ├── v1 │ │ │ ├── env_group │ │ │ │ ├── add_release.go │ │ │ │ ├── create.go │ │ │ │ ├── delete.go │ │ │ │ ├── get.go │ │ │ │ ├── get_all_versions.go │ │ │ │ ├── list.go │ │ │ │ └── remove_release.go │ │ │ ├── registry │ │ │ │ └── list_images.go │ │ │ ├── release │ │ │ │ └── upgrade.go │ │ │ └── template │ │ │ │ ├── get.go │ │ │ │ ├── get_upgrade_notes.go │ │ │ │ └── list.go │ │ └── webhook │ │ │ ├── app_v2_github.go │ │ │ ├── github_incoming.go │ │ │ └── prometheus_incoming.go │ ├── router │ │ ├── addons.go │ │ ├── base.go │ │ ├── cloud_provider.go │ │ ├── cluster.go │ │ ├── cluster_integration.go │ │ ├── datastore.go │ │ ├── deployment_target.go │ │ ├── deployment_target_legacy.go │ │ ├── git_installation.go │ │ ├── helm_repo.go │ │ ├── infra.go │ │ ├── invite.go │ │ ├── middleware │ │ │ ├── content_type_json.go │ │ │ ├── hydrate_trace.go │ │ │ ├── panic.go │ │ │ ├── request_logger.go │ │ │ ├── usage.go │ │ │ └── websocket.go │ │ ├── namespace.go │ │ ├── notification.go │ │ ├── oauth_callback.go │ │ ├── porter_app.go │ │ ├── project.go │ │ ├── project_integration.go │ │ ├── project_oauth.go │ │ ├── registry.go │ │ ├── release.go │ │ ├── router.go │ │ ├── slack_integration.go │ │ ├── status.go │ │ ├── user.go │ │ └── v1 │ │ │ ├── cluster.go │ │ │ ├── env_group.go │ │ │ ├── namespace.go │ │ │ ├── project.go │ │ │ ├── registry.go │ │ │ ├── release.go │ │ │ └── stack.go │ ├── server.go │ └── shared │ │ ├── apierrors │ │ ├── alerter │ │ │ ├── alerter.go │ │ │ ├── noop.go │ │ │ └── sentry.go │ │ └── errors.go │ │ ├── apitest │ │ ├── authn.go │ │ ├── authz.go │ │ ├── config.go │ │ ├── notifier.go │ │ ├── request.go │ │ ├── response.go │ │ └── user.go │ │ ├── commonutils │ │ ├── git_utils.go │ │ └── gitlab.go │ │ ├── config │ │ ├── config.go │ │ ├── env │ │ │ └── envconfs.go │ │ ├── envloader │ │ │ └── envloader.go │ │ ├── loader │ │ │ ├── init_ce.go │ │ │ ├── init_ee.go │ │ │ └── loader.go │ │ └── metadata.go │ │ ├── endpoints.go │ │ ├── features │ │ └── features.go │ │ ├── reader.go │ │ ├── requestutils │ │ ├── decoder.go │ │ ├── decoder_test.go │ │ ├── url_param.go │ │ ├── url_param_test.go │ │ ├── validator.go │ │ └── validator_test.go │ │ ├── router │ │ └── router.go │ │ ├── websocket │ │ ├── response_writer.go │ │ └── upgrader.go │ │ └── writer.go ├── types │ ├── agent.go │ ├── api_token.go │ ├── billing_stripe.go │ ├── billing_usage.go │ ├── build_config.go │ ├── cluster.go │ ├── cluster_integration.go │ ├── crd.go │ ├── database.go │ ├── datastore.go │ ├── deployment_target.go │ ├── environment.go │ ├── error.go │ ├── form.go │ ├── git_action_config.go │ ├── git_installation.go │ ├── helm_release.go │ ├── helm_repo.go │ ├── incident.go │ ├── infra.go │ ├── integrations.go │ ├── invite.go │ ├── jobs.go │ ├── kube_events.go │ ├── monitor.go │ ├── namespace.go │ ├── policy.go │ ├── porter_app.go │ ├── project.go │ ├── project_integration.go │ ├── prometheus_alerts.go │ ├── provision.go │ ├── referral.go │ ├── registry.go │ ├── release.go │ ├── request.go │ ├── role.go │ ├── slack_integration.go │ ├── stack.go │ ├── stacks.go │ ├── status.go │ ├── system_service_status.go │ ├── tag.go │ ├── template.go │ ├── usage.go │ └── user.go └── utils │ ├── dns_label.go │ └── porter_app │ └── namespace.go ├── build ├── Dockerfile.osx └── Dockerfile.win ├── cli ├── cmd │ ├── commands │ │ ├── all.go │ │ ├── app.go │ │ ├── apply.go │ │ ├── auth.go │ │ ├── cluster.go │ │ ├── config.go │ │ ├── connect.go │ │ ├── create.go │ │ ├── datastore.go │ │ ├── delete.go │ │ ├── deploy_bluegreen.go │ │ ├── docker.go │ │ ├── env.go │ │ ├── errors.go │ │ ├── flags │ │ │ ├── app_build.go │ │ │ ├── app_config.go │ │ │ └── app_image.go │ │ ├── get.go │ │ ├── helm.go │ │ ├── job.go │ │ ├── kubectl.go │ │ ├── list.go │ │ ├── logs.go │ │ ├── open.go │ │ ├── project.go │ │ ├── registry.go │ │ ├── root.go │ │ ├── run.go │ │ ├── server.go │ │ ├── stack.go │ │ ├── target.go │ │ ├── update.go │ │ └── version.go │ ├── config │ │ ├── config.go │ │ ├── docker.go │ │ └── version.go │ ├── connect │ │ ├── dockerhub.go │ │ ├── docr.go │ │ ├── ecr.go │ │ ├── gar.go │ │ ├── gcr.go │ │ ├── helmrepo.go │ │ ├── kubeconfig.go │ │ └── registry.go │ ├── deploy │ │ ├── build.go │ │ ├── create.go │ │ ├── deploy.go │ │ ├── shared.go │ │ └── wait │ │ │ └── job.go │ ├── docker │ │ ├── agent.go │ │ ├── agent_test.go │ │ ├── auth.go │ │ ├── builder.go │ │ ├── config.go │ │ └── porter.go │ ├── errors │ │ └── error_handler.go │ ├── github │ │ └── release.go │ ├── gitutils │ │ └── git.go │ ├── login │ │ └── server.go │ ├── pack │ │ ├── logger.go │ │ ├── pack.go │ │ └── pack_test.go │ ├── porter_app │ │ ├── apply.go │ │ ├── build.go │ │ ├── env.go │ │ ├── hooks.go │ │ ├── preDeploy.go │ │ ├── types.go │ │ ├── utils.go │ │ └── validate.go │ ├── preview │ │ ├── build_image_driver.go │ │ ├── env_group_driver.go │ │ ├── os_env_driver.go │ │ ├── push_image_driver.go │ │ ├── random_string_driver.go │ │ ├── update_config_driver.go │ │ ├── utils.go │ │ └── v2beta1 │ │ │ ├── addon_resource.go │ │ │ ├── app_resource.go │ │ │ ├── apply.go │ │ │ ├── build.go │ │ │ ├── helm_chart.go │ │ │ ├── types.go │ │ │ └── utils.go │ ├── providers │ │ ├── aws │ │ │ ├── agent.go │ │ │ ├── authconfigmap.go │ │ │ └── local │ │ │ │ └── config.go │ │ └── gcp │ │ │ ├── agent.go │ │ │ └── local │ │ │ └── config.go │ ├── utils │ │ ├── browser.go │ │ ├── close.go │ │ ├── file.go │ │ ├── flags.go │ │ ├── prompt.go │ │ ├── random_string.go │ │ ├── sanitize.go │ │ └── wsl.go │ └── v2 │ │ ├── app_build.go │ │ ├── app_create.go │ │ ├── app_events.go │ │ ├── app_logs.go │ │ ├── app_push.go │ │ ├── app_status.go │ │ ├── apply.go │ │ ├── bluegreen.go │ │ ├── build.go │ │ ├── create.go │ │ ├── delete.go │ │ ├── deploy.go │ │ ├── deployment_target.go │ │ ├── get.go │ │ ├── job.go │ │ ├── list.go │ │ ├── rollback.go │ │ ├── run_app_job.go │ │ ├── stack.go │ │ └── update_image.go └── main.go ├── cmd ├── app │ └── main.go ├── dev │ └── main.go ├── docker-credential-porter │ ├── helper │ │ └── helper.go │ └── main.go ├── migrate │ ├── enable_cluster_preview_envs │ │ ├── enable.go │ │ ├── enable_test.go │ │ └── helpers_test.go │ ├── keyrotate │ │ ├── helpers_test.go │ │ ├── rotate.go │ │ └── rotate_test.go │ ├── main.go │ ├── migrate_ce.go │ ├── migrate_ee.go │ ├── populate_source_config_display_name │ │ ├── helpers_test.go │ │ ├── populate.go │ │ └── populate_test.go │ └── startup_migrations │ │ ├── doc.go │ │ └── global_map.go ├── provisioner │ └── main.go └── ready │ └── main.go ├── dashboard ├── .dockerignore ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .husky │ └── pre-commit ├── .npmrc ├── .prettierignore ├── .prettierrc.json ├── babel.config.json ├── decs.d.ts ├── docker │ └── dev.Dockerfile ├── index.html ├── jest.config.js ├── package-lock.json ├── package.json ├── react-table.d.ts ├── src │ ├── App.tsx │ ├── __mocks__ │ │ └── fileMock.js │ ├── __tests__ │ │ └── CreateProject.test.tsx │ ├── assets │ │ ├── GoogleIcon.tsx │ │ ├── Light Gradient 08.png │ │ ├── add-circle.png │ │ ├── add-on-grad.svg │ │ ├── add-ons-bold.png │ │ ├── add-ons.png │ │ ├── add-ons.svg │ │ ├── alert-red.svg │ │ ├── alert-triangle.svg │ │ ├── alert-warning.svg │ │ ├── alert_square.svg │ │ ├── amazon-rds.png │ │ ├── app_event.png │ │ ├── application-grad.svg │ │ ├── applications.png │ │ ├── applications.svg │ │ ├── arrow-down.svg │ │ ├── arrow-left-square-contained.svg │ │ ├── aws-elasticache.png │ │ ├── aws-normal.png │ │ ├── aws-white.png │ │ ├── aws.png │ │ ├── azure.png │ │ ├── back_arrow.png │ │ ├── bar-group-03.svg │ │ ├── blog.png │ │ ├── bolt.svg │ │ ├── box.png │ │ ├── branch.png │ │ ├── build.png │ │ ├── calendar-02.svg │ │ ├── calendar-number.svg │ │ ├── cancel.svg │ │ ├── canceled.svg │ │ ├── category.svg │ │ ├── chat.svg │ │ ├── check.png │ │ ├── check.svg │ │ ├── close-rounded.png │ │ ├── close.png │ │ ├── close_rounded.png │ │ ├── cloud-formation-stack-complete.png │ │ ├── cluster.svg │ │ ├── collapse-sidebar.svg │ │ ├── community.png │ │ ├── compliance-grad.svg │ │ ├── compliance.png │ │ ├── compliance.svg │ │ ├── computer-chip.svg │ │ ├── connect.svg │ │ ├── copy-left.svg │ │ ├── copy.svg │ │ ├── credit-card.svg │ │ ├── creds.png │ │ ├── danger.svg │ │ ├── database-grad.svg │ │ ├── database.svg │ │ ├── deploy.png │ │ ├── devicons-name-list.ts │ │ ├── discord.svg │ │ ├── do.png │ │ ├── docs.png │ │ ├── document.svg │ │ ├── doppler.png │ │ ├── dot-vertical.svg │ │ ├── down-arrow.svg │ │ ├── drawer-bg.png │ │ ├── edit-button.svg │ │ ├── edit-contained.svg │ │ ├── edit.svg │ │ ├── env-group-grad.svg │ │ ├── env-groups.svg │ │ ├── expand.png │ │ ├── external-link.svg │ │ ├── eye-off.svg │ │ ├── eye.svg │ │ ├── failure.png │ │ ├── failure.svg │ │ ├── fast-backward.svg │ │ ├── file-branch.svg │ │ ├── file-diff.svg │ │ ├── file.svg │ │ ├── file_v2.svg │ │ ├── filter-outline-icon.svg │ │ ├── filter-outline-new.png │ │ ├── filter-outline-white.svg │ │ ├── filter-outline.svg │ │ ├── filter.svg │ │ ├── fire.svg │ │ ├── folder-outline.svg │ │ ├── folder.svg │ │ ├── folder_v2.svg │ │ ├── framework.svg │ │ ├── gcp.png │ │ ├── gear.svg │ │ ├── gift.svg │ │ ├── git-compare.svg │ │ ├── git-scm.svg │ │ ├── github-icon.png │ │ ├── github-white.png │ │ ├── github.png │ │ ├── globe.svg │ │ ├── gradient.jpg │ │ ├── gradient.png │ │ ├── green-check.svg │ │ ├── grid.png │ │ ├── hash-02.svg │ │ ├── history.png │ │ ├── home.svg │ │ ├── infisical.svg │ │ ├── info-circle.svg │ │ ├── info-outlined.svg │ │ ├── info.svg │ │ ├── information-circle-contained.svg │ │ ├── infra-grad.svg │ │ ├── infra.png │ │ ├── integration-grad.svg │ │ ├── integrations-bold.png │ │ ├── integrations.png │ │ ├── integrations.svg │ │ ├── job-bold.png │ │ ├── job.png │ │ ├── key.svg │ │ ├── last-run.svg │ │ ├── launch.svg │ │ ├── left-arrow.svg │ │ ├── lightning-square-contained.png │ │ ├── lightning.png │ │ ├── lightning.svg │ │ ├── link-external.svg │ │ ├── link.svg │ │ ├── list.png │ │ ├── loading-dots.gif │ │ ├── loading.gif │ │ ├── lock.svg │ │ ├── logo.png │ │ ├── monojob.png │ │ ├── monoweb.png │ │ ├── moon.svg │ │ ├── neon.svg │ │ ├── node.png │ │ ├── not-applicable.svg │ │ ├── not-found.png │ │ ├── oneleet.svg │ │ ├── pencil.png │ │ ├── pending.svg │ │ ├── pipelines.svg │ │ ├── placeholder.png │ │ ├── placeholder.svg │ │ ├── plus-square.svg │ │ ├── plus.svg │ │ ├── postgresql.svg │ │ ├── pr-grad.svg │ │ ├── pre_deploy.png │ │ ├── provider.svg │ │ ├── pull_request_icon.svg │ │ ├── quivr.png │ │ ├── redis.svg │ │ ├── refresh.png │ │ ├── rocket.png │ │ ├── role.svg │ │ ├── run_for.png │ │ ├── save-01.svg │ │ ├── search.png │ │ ├── seed.svg │ │ ├── settings-bold.png │ │ ├── settings-centered.svg │ │ ├── settings-grad.svg │ │ ├── settings.png │ │ ├── settings.svg │ │ ├── shield.svg │ │ ├── sidebar-highlight.png │ │ ├── sliders.svg │ │ ├── sort.svg │ │ ├── sparkle.svg │ │ ├── stars-white.svg │ │ ├── stars.svg │ │ ├── status-healthy.png │ │ ├── swap.svg │ │ ├── tag.png │ │ ├── tag.svg │ │ ├── target.svg │ │ ├── time.png │ │ ├── time.svg │ │ ├── trash.png │ │ ├── type.svg │ │ ├── upload.svg │ │ ├── upstash.svg │ │ ├── user-icon.png │ │ ├── vanta.svg │ │ ├── vector.svg │ │ ├── warning.png │ │ ├── warning.svg │ │ ├── web-bold.png │ │ ├── web.png │ │ ├── worker.png │ │ └── world.svg │ ├── components │ │ ├── AWSCostConsent.tsx │ │ ├── AzureCostConsent.tsx │ │ ├── AzureCredentialForm.tsx │ │ ├── AzureProvisionerSettings.tsx │ │ ├── Breadcrumb.tsx │ │ ├── Button.tsx │ │ ├── CheckboxRow.tsx │ │ ├── CloudFormationForm.tsx │ │ ├── ClusterProvisioningPlaceholder.tsx │ │ ├── ConfirmOverlay.tsx │ │ ├── CopyToClipboard.tsx │ │ ├── CreateDeploymentTargetModal.tsx │ │ ├── CredentialsForm.tsx │ │ ├── Description.tsx │ │ ├── DocsHelper.tsx │ │ ├── DynamicLink.tsx │ │ ├── ExpandableResource.tsx │ │ ├── GCPCostConsent.tsx │ │ ├── GCPCredentialsForm.tsx │ │ ├── GCPProvisionerSettings.tsx │ │ ├── GPUCostConsent.tsx │ │ ├── GPUProvisionSettings.tsx │ │ ├── Loading.tsx │ │ ├── LogQueryModeSelectionToggle.tsx │ │ ├── LogSearchBar.tsx │ │ ├── MultiSaveButton.tsx │ │ ├── OldPlaceholder.tsx │ │ ├── OldTable.tsx │ │ ├── PageIllustration.tsx │ │ ├── Placeholder.tsx │ │ ├── PreflightChecks.tsx │ │ ├── ProvisionerFlow.tsx │ │ ├── ProvisionerForm.tsx │ │ ├── ProvisionerSettings.tsx │ │ ├── ProvisionerStatus.tsx │ │ ├── RadioSelector.tsx │ │ ├── ResourceTab.tsx │ │ ├── SaveButton.tsx │ │ ├── SearchBar.tsx │ │ ├── Selector.tsx │ │ ├── TabRegion.tsx │ │ ├── TabSelector.tsx │ │ ├── TitleSection.tsx │ │ ├── UnauthorizedPage.tsx │ │ ├── UnexpectedErrorPage.tsx │ │ ├── YamlEditor.tsx │ │ ├── azureUtils.ts │ │ ├── date-time-picker │ │ │ ├── DateTimePicker.tsx │ │ │ └── react-datepicker.css │ │ ├── form-components │ │ │ ├── CheckboxList.tsx │ │ │ ├── CheckboxRow.tsx │ │ │ ├── Heading.tsx │ │ │ ├── Helper.tsx │ │ │ ├── InputRow.tsx │ │ │ ├── KeyValueArray.tsx │ │ │ ├── SelectRow.tsx │ │ │ ├── TextArea.tsx │ │ │ └── UploadArea.tsx │ │ ├── image-selector │ │ │ ├── ImageList.tsx │ │ │ ├── ImageSelector.tsx │ │ │ └── TagList.tsx │ │ ├── porter-form │ │ │ ├── FormDebugger.tsx │ │ │ ├── PorterForm.tsx │ │ │ ├── PorterFormContextProvider.tsx │ │ │ ├── PorterFormWrapper.tsx │ │ │ ├── field-components │ │ │ │ ├── ArrayInput.tsx │ │ │ │ ├── Checkbox.tsx │ │ │ │ ├── CronInput.tsx │ │ │ │ ├── Dictionary.tsx │ │ │ │ ├── DictionaryArray.tsx │ │ │ │ ├── Input.tsx │ │ │ │ ├── KeyValueArray.tsx │ │ │ │ ├── MultiSelect.tsx │ │ │ │ ├── ResourceList.tsx │ │ │ │ ├── Select.tsx │ │ │ │ ├── ServiceIPList.tsx │ │ │ │ ├── ServiceRow.tsx │ │ │ │ ├── TextAreaInput.tsx │ │ │ │ ├── UrlLink.tsx │ │ │ │ └── VeleroForm.tsx │ │ │ ├── hooks │ │ │ │ └── useFormField.tsx │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── porter │ │ │ ├── Back.tsx │ │ │ ├── Banner.tsx │ │ │ ├── BlockSelect.tsx │ │ │ ├── Button.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── ClickToCopy.tsx │ │ │ ├── Clickable.tsx │ │ │ ├── CollapsibleContainer.tsx │ │ │ ├── Container.tsx │ │ │ ├── ControlledInput.tsx │ │ │ ├── DashboardPlaceholder.tsx │ │ │ ├── DictionaryEditor.tsx │ │ │ ├── Dropdown.tsx │ │ │ ├── Error.tsx │ │ │ ├── Expandable.tsx │ │ │ ├── ExpandableSection.tsx │ │ │ ├── Fieldset.tsx │ │ │ ├── FileArray.tsx │ │ │ ├── Filter.tsx │ │ │ ├── Icon.tsx │ │ │ ├── Image.tsx │ │ │ ├── Input.tsx │ │ │ ├── InputSlider.tsx │ │ │ ├── Link.tsx │ │ │ ├── LoadingBar.tsx │ │ │ ├── Modal.tsx │ │ │ ├── Pagination.tsx │ │ │ ├── PorterOperatorComponent.tsx │ │ │ ├── RequestToEnable.tsx │ │ │ ├── SearchBar.tsx │ │ │ ├── Select.tsx │ │ │ ├── SelectableList.tsx │ │ │ ├── Selector.tsx │ │ │ ├── ShowIntercomButton.tsx │ │ │ ├── Spacer.tsx │ │ │ ├── StatusBar.tsx │ │ │ ├── StatusDot.tsx │ │ │ ├── Step.tsx │ │ │ ├── Tag.tsx │ │ │ ├── Text.tsx │ │ │ ├── Tiles.tsx │ │ │ ├── Toggle.tsx │ │ │ ├── ToggleRow.tsx │ │ │ ├── Tooltip.tsx │ │ │ ├── VerticalSteps.tsx │ │ │ └── collapsible-container.css │ │ └── repo-selector │ │ │ ├── ActionConfEditor.tsx │ │ │ ├── ActionDetails.tsx │ │ │ ├── BranchList.tsx │ │ │ ├── BuildpackSelection.tsx │ │ │ ├── ContentsList.tsx │ │ │ └── RepoList.tsx │ ├── index.tsx │ ├── legacy │ │ ├── __mocks__ │ │ │ └── fileMock.js │ │ ├── __tests__ │ │ │ └── CreateProject.test.tsx │ │ ├── assets │ │ │ ├── GithubIcon.tsx │ │ │ ├── Light Gradient 08.png │ │ │ ├── add-circle.png │ │ │ ├── add-on-grad.svg │ │ │ ├── add-ons-bold.png │ │ │ ├── add-ons.png │ │ │ ├── add-ons.svg │ │ │ ├── alert-red.svg │ │ │ ├── alert-triangle.svg │ │ │ ├── alert-warning.svg │ │ │ ├── alert_square.svg │ │ │ ├── amazon-rds.png │ │ │ ├── app_event.png │ │ │ ├── application-grad.svg │ │ │ ├── applications.png │ │ │ ├── applications.svg │ │ │ ├── arrow-down.svg │ │ │ ├── arrow-left-square-contained.svg │ │ │ ├── aws-elasticache.png │ │ │ ├── aws-normal.png │ │ │ ├── aws-white.png │ │ │ ├── aws.png │ │ │ ├── azure.png │ │ │ ├── back_arrow.png │ │ │ ├── bar-group-03.svg │ │ │ ├── blog.png │ │ │ ├── bolt.svg │ │ │ ├── box.png │ │ │ ├── branch.png │ │ │ ├── build.png │ │ │ ├── calendar-02.svg │ │ │ ├── calendar-number.svg │ │ │ ├── cancel.svg │ │ │ ├── canceled.svg │ │ │ ├── category.svg │ │ │ ├── chat.svg │ │ │ ├── check.png │ │ │ ├── check.svg │ │ │ ├── close-rounded.png │ │ │ ├── close.png │ │ │ ├── close_rounded.png │ │ │ ├── cloud-formation-stack-complete.png │ │ │ ├── cluster.svg │ │ │ ├── collapse-sidebar.svg │ │ │ ├── command-line-icon.tsx │ │ │ ├── community.png │ │ │ ├── compliance-grad.svg │ │ │ ├── compliance.png │ │ │ ├── compliance.svg │ │ │ ├── computer-chip.svg │ │ │ ├── connect.svg │ │ │ ├── copy-left.svg │ │ │ ├── copy.svg │ │ │ ├── credit-card.svg │ │ │ ├── creds.png │ │ │ ├── danger.svg │ │ │ ├── database-grad.svg │ │ │ ├── database.svg │ │ │ ├── deploy.png │ │ │ ├── devicons-name-list.ts │ │ │ ├── discord.svg │ │ │ ├── do.png │ │ │ ├── docs.png │ │ │ ├── document.svg │ │ │ ├── doppler.png │ │ │ ├── dot-vertical.svg │ │ │ ├── down-arrow.svg │ │ │ ├── drawer-bg.png │ │ │ ├── edit-button.svg │ │ │ ├── edit-contained.svg │ │ │ ├── edit.svg │ │ │ ├── env-group-grad.svg │ │ │ ├── env-groups.svg │ │ │ ├── expand.png │ │ │ ├── external-link.svg │ │ │ ├── eye-off.svg │ │ │ ├── eye.svg │ │ │ ├── failure.png │ │ │ ├── failure.svg │ │ │ ├── fast-backward.svg │ │ │ ├── file-branch.svg │ │ │ ├── file-diff.svg │ │ │ ├── file.svg │ │ │ ├── file_v2.svg │ │ │ ├── filter-outline-icon.svg │ │ │ ├── filter-outline-new.png │ │ │ ├── filter-outline-white.svg │ │ │ ├── filter-outline.svg │ │ │ ├── filter.svg │ │ │ ├── fire.svg │ │ │ ├── folder-outline.svg │ │ │ ├── folder.svg │ │ │ ├── folder_v2.svg │ │ │ ├── framework.svg │ │ │ ├── gcp.png │ │ │ ├── gear.svg │ │ │ ├── gift.svg │ │ │ ├── git-compare.svg │ │ │ ├── git-scm.svg │ │ │ ├── github-icon.png │ │ │ ├── github-white.png │ │ │ ├── github.png │ │ │ ├── globe.svg │ │ │ ├── gradient.jpg │ │ │ ├── gradient.png │ │ │ ├── green-check.svg │ │ │ ├── grid.png │ │ │ ├── hash-02.svg │ │ │ ├── history.png │ │ │ ├── home.svg │ │ │ ├── infisical.svg │ │ │ ├── info-circle.svg │ │ │ ├── info-outlined.svg │ │ │ ├── info.svg │ │ │ ├── information-circle-contained.svg │ │ │ ├── infra-grad.svg │ │ │ ├── infra.png │ │ │ ├── integration-grad.svg │ │ │ ├── integrations-bold.png │ │ │ ├── integrations.png │ │ │ ├── integrations.svg │ │ │ ├── job-bold.png │ │ │ ├── job.png │ │ │ ├── key.svg │ │ │ ├── last-run.svg │ │ │ ├── launch.svg │ │ │ ├── left-arrow.svg │ │ │ ├── lightning-square-contained.png │ │ │ ├── lightning.png │ │ │ ├── lightning.svg │ │ │ ├── link-external.svg │ │ │ ├── link.svg │ │ │ ├── list.png │ │ │ ├── loading-dots.gif │ │ │ ├── loading.gif │ │ │ ├── lock.svg │ │ │ ├── logo.png │ │ │ ├── monojob.png │ │ │ ├── monoweb.png │ │ │ ├── moon.svg │ │ │ ├── neon.svg │ │ │ ├── node.png │ │ │ ├── not-applicable.svg │ │ │ ├── not-found.png │ │ │ ├── oneleet.svg │ │ │ ├── pencil.png │ │ │ ├── pending.svg │ │ │ ├── pipelines.svg │ │ │ ├── placeholder.png │ │ │ ├── placeholder.svg │ │ │ ├── plus-square.svg │ │ │ ├── plus.svg │ │ │ ├── postgresql.svg │ │ │ ├── pr-grad.svg │ │ │ ├── pre_deploy.png │ │ │ ├── provider.svg │ │ │ ├── pull_request_icon.svg │ │ │ ├── quivr.png │ │ │ ├── redis.svg │ │ │ ├── refresh.png │ │ │ ├── rocket.png │ │ │ ├── role.svg │ │ │ ├── run_for.png │ │ │ ├── save-01.svg │ │ │ ├── search.png │ │ │ ├── seed.svg │ │ │ ├── settings-bold.png │ │ │ ├── settings-centered.svg │ │ │ ├── settings-grad.svg │ │ │ ├── settings.png │ │ │ ├── settings.svg │ │ │ ├── shield.svg │ │ │ ├── sidebar-highlight.png │ │ │ ├── sliders.svg │ │ │ ├── sort.svg │ │ │ ├── sparkle.svg │ │ │ ├── stars-white.svg │ │ │ ├── stars.svg │ │ │ ├── status-healthy.png │ │ │ ├── swap.svg │ │ │ ├── tag.png │ │ │ ├── tag.svg │ │ │ ├── target.svg │ │ │ ├── time.png │ │ │ ├── time.svg │ │ │ ├── trash.png │ │ │ ├── type.svg │ │ │ ├── upload.svg │ │ │ ├── upstash.svg │ │ │ ├── user-icon.png │ │ │ ├── vanta.svg │ │ │ ├── vector.svg │ │ │ ├── warning.png │ │ │ ├── warning.svg │ │ │ ├── web-bold.png │ │ │ ├── web.png │ │ │ ├── worker.png │ │ │ └── world.svg │ │ ├── components │ │ │ ├── AWSCostConsent.tsx │ │ │ ├── AzureCostConsent.tsx │ │ │ ├── AzureCredentialForm.tsx │ │ │ ├── AzureProvisionerSettings.tsx │ │ │ ├── Breadcrumb.tsx │ │ │ ├── Button.tsx │ │ │ ├── CheckboxRow.tsx │ │ │ ├── CloudFormationForm.tsx │ │ │ ├── ClusterProvisioningPlaceholder.tsx │ │ │ ├── ConfirmOverlay.tsx │ │ │ ├── CopyToClipboard.tsx │ │ │ ├── CreateDeploymentTargetModal.tsx │ │ │ ├── CredentialsForm.tsx │ │ │ ├── Description.tsx │ │ │ ├── DocsHelper.tsx │ │ │ ├── Dropdown.tsx │ │ │ ├── DynamicLink.tsx │ │ │ ├── ExpandableResource.tsx │ │ │ ├── GCPCostConsent.tsx │ │ │ ├── GCPCredentialsForm.tsx │ │ │ ├── GCPProvisionerSettings.tsx │ │ │ ├── GPUCostConsent.tsx │ │ │ ├── GPUProvisionSettings.tsx │ │ │ ├── Loading.tsx │ │ │ ├── LogQueryModeSelectionToggle.tsx │ │ │ ├── LogSearchBar.tsx │ │ │ ├── MultiSaveButton.tsx │ │ │ ├── NoClusterPlaceHolder.tsx │ │ │ ├── OldPlaceholder.tsx │ │ │ ├── OldTable.tsx │ │ │ ├── OptionsDropdown.tsx │ │ │ ├── PageIllustration.tsx │ │ │ ├── PageNotFound.tsx │ │ │ ├── Placeholder.tsx │ │ │ ├── PreflightChecks.tsx │ │ │ ├── ProvisionerFlow.tsx │ │ │ ├── ProvisionerForm.tsx │ │ │ ├── ProvisionerSettings.tsx │ │ │ ├── ProvisionerStatus.tsx │ │ │ ├── RadioFilter.tsx │ │ │ ├── RadioSelector.tsx │ │ │ ├── ResourceTab.tsx │ │ │ ├── SaveButton.tsx │ │ │ ├── SearchBar.tsx │ │ │ ├── SearchSelector.tsx │ │ │ ├── Selector.tsx │ │ │ ├── StatusIndicator.tsx │ │ │ ├── StatusSection.tsx │ │ │ ├── TabRegion.tsx │ │ │ ├── TabSelector.tsx │ │ │ ├── Table.tsx │ │ │ ├── TitleSection.tsx │ │ │ ├── UnexpectedErrorPage.tsx │ │ │ ├── YamlEditor.tsx │ │ │ ├── azureUtils.ts │ │ │ ├── date-time-picker │ │ │ │ ├── DateTimePicker.tsx │ │ │ │ └── react-datepicker.css │ │ │ ├── form-components │ │ │ │ ├── CheckboxList.tsx │ │ │ │ ├── CheckboxRow.tsx │ │ │ │ ├── Heading.tsx │ │ │ │ ├── Helper.tsx │ │ │ │ ├── InputRow.tsx │ │ │ │ ├── KeyValueArray.tsx │ │ │ │ ├── SelectRow.tsx │ │ │ │ ├── TextArea.tsx │ │ │ │ └── UploadArea.tsx │ │ │ ├── image-selector │ │ │ │ ├── ImageList.tsx │ │ │ │ ├── ImageSelector.tsx │ │ │ │ └── TagList.tsx │ │ │ ├── porter-form │ │ │ │ ├── FormDebugger.tsx │ │ │ │ ├── PorterForm.tsx │ │ │ │ ├── PorterFormContextProvider.tsx │ │ │ │ ├── PorterFormWrapper.tsx │ │ │ │ ├── field-components │ │ │ │ │ ├── ArrayInput.tsx │ │ │ │ │ ├── Checkbox.tsx │ │ │ │ │ ├── CronInput.tsx │ │ │ │ │ ├── Dictionary.tsx │ │ │ │ │ ├── DictionaryArray.tsx │ │ │ │ │ ├── Input.tsx │ │ │ │ │ ├── KeyValueArray.tsx │ │ │ │ │ ├── MultiSelect.tsx │ │ │ │ │ ├── ResourceList.tsx │ │ │ │ │ ├── Select.tsx │ │ │ │ │ ├── ServiceIPList.tsx │ │ │ │ │ ├── ServiceRow.tsx │ │ │ │ │ ├── TextAreaInput.tsx │ │ │ │ │ ├── UrlLink.tsx │ │ │ │ │ └── VeleroForm.tsx │ │ │ │ ├── hooks │ │ │ │ │ └── useFormField.tsx │ │ │ │ ├── types.ts │ │ │ │ └── utils.ts │ │ │ ├── porter │ │ │ │ ├── Back.tsx │ │ │ │ ├── Banner.tsx │ │ │ │ ├── BlockSelect.tsx │ │ │ │ ├── Button.tsx │ │ │ │ ├── Checkbox.tsx │ │ │ │ ├── ClickToCopy.tsx │ │ │ │ ├── Clickable.tsx │ │ │ │ ├── CollapsibleContainer.tsx │ │ │ │ ├── Container.tsx │ │ │ │ ├── ControlledInput.tsx │ │ │ │ ├── DashboardPlaceholder.tsx │ │ │ │ ├── DictionaryEditor.tsx │ │ │ │ ├── Dropdown.tsx │ │ │ │ ├── Error.tsx │ │ │ │ ├── Expandable.tsx │ │ │ │ ├── ExpandableSection.tsx │ │ │ │ ├── Fieldset.tsx │ │ │ │ ├── FileArray.tsx │ │ │ │ ├── Filter.tsx │ │ │ │ ├── Icon.tsx │ │ │ │ ├── Image.tsx │ │ │ │ ├── Input.tsx │ │ │ │ ├── InputSlider.tsx │ │ │ │ ├── Link.tsx │ │ │ │ ├── LoadingBar.tsx │ │ │ │ ├── Modal.tsx │ │ │ │ ├── Pagination.tsx │ │ │ │ ├── PorterOperatorComponent.tsx │ │ │ │ ├── RequestToEnable.tsx │ │ │ │ ├── SearchBar.tsx │ │ │ │ ├── Select.tsx │ │ │ │ ├── SelectableList.tsx │ │ │ │ ├── Selector.tsx │ │ │ │ ├── ShowIntercomButton.tsx │ │ │ │ ├── Spacer.tsx │ │ │ │ ├── StatusBar.tsx │ │ │ │ ├── StatusDot.tsx │ │ │ │ ├── Step.tsx │ │ │ │ ├── Tag.tsx │ │ │ │ ├── Text.tsx │ │ │ │ ├── Tiles.tsx │ │ │ │ ├── Toggle.tsx │ │ │ │ ├── ToggleRow.tsx │ │ │ │ ├── Tooltip.tsx │ │ │ │ ├── VerticalSteps.tsx │ │ │ │ └── collapsible-container.css │ │ │ └── repo-selector │ │ │ │ ├── ActionConfEditor.tsx │ │ │ │ ├── ActionDetails.tsx │ │ │ │ ├── BranchList.tsx │ │ │ │ ├── BuildpackSelection.tsx │ │ │ │ ├── ContentsList.tsx │ │ │ │ └── RepoList.tsx │ │ ├── lib │ │ │ ├── addons │ │ │ │ ├── datadog.ts │ │ │ │ ├── index.ts │ │ │ │ ├── metabase.ts │ │ │ │ ├── mezmo.ts │ │ │ │ ├── newrelic.ts │ │ │ │ ├── postgres.ts │ │ │ │ ├── quivr.ts │ │ │ │ ├── redis.ts │ │ │ │ ├── tailscale.ts │ │ │ │ └── template.ts │ │ │ ├── billing │ │ │ │ └── types.tsx │ │ │ ├── clusters │ │ │ │ ├── constants.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── databases │ │ │ │ └── types.ts │ │ │ ├── env-groups │ │ │ │ └── types.ts │ │ │ ├── environments │ │ │ │ └── types.ts │ │ │ ├── github │ │ │ │ └── workflows.ts │ │ │ ├── hooks │ │ │ │ ├── UseOutsideClick.ts │ │ │ │ ├── useAddon.ts │ │ │ │ ├── useAppAnalytics.ts │ │ │ │ ├── useAppStatus.ts │ │ │ │ ├── useAppValidation.ts │ │ │ │ ├── useAppWithPreviewOverrides.ts │ │ │ │ ├── useAuthWindow.ts │ │ │ │ ├── useCloudProvider.ts │ │ │ │ ├── useCloudSqlSecret.ts │ │ │ │ ├── useCluster.ts │ │ │ │ ├── useClusterAnalytics.ts │ │ │ │ ├── useDatabaseList.ts │ │ │ │ ├── useDatastore.ts │ │ │ │ ├── useDeploymentTarget.ts │ │ │ │ ├── useEnvGroups.ts │ │ │ │ ├── useGithubContents.ts │ │ │ │ ├── useGithubWorkflow.ts │ │ │ │ ├── useIntercom.ts │ │ │ │ ├── useJobs.ts │ │ │ │ ├── useLago.ts │ │ │ │ ├── useLatestAppRevisions.ts │ │ │ │ ├── useNeon.ts │ │ │ │ ├── useNodeGroups.ts │ │ │ │ ├── usePorterYaml.ts │ │ │ │ ├── useRevisionList.ts │ │ │ │ ├── useStripe.ts │ │ │ │ ├── useTemplateEnvs.ts │ │ │ │ └── useUpstash.ts │ │ │ ├── neon │ │ │ │ └── types.ts │ │ │ ├── notifications │ │ │ │ └── types.ts │ │ │ ├── porter-apps │ │ │ │ ├── build.ts │ │ │ │ ├── error.ts │ │ │ │ ├── index.ts │ │ │ │ ├── notification.ts │ │ │ │ ├── routing.ts │ │ │ │ ├── services.ts │ │ │ │ └── values.ts │ │ │ ├── revisions │ │ │ │ └── types.ts │ │ │ └── upstash │ │ │ │ └── types.ts │ │ ├── main │ │ │ ├── auth │ │ │ │ └── OryLogin.tsx │ │ │ └── home │ │ │ │ ├── Home.tsx │ │ │ │ ├── ModalHandler.tsx │ │ │ │ ├── NoClusterPlaceholder.tsx │ │ │ │ ├── add-on-dashboard │ │ │ │ ├── AddOnDashboard.tsx │ │ │ │ ├── AddonContextProvider.tsx │ │ │ │ ├── AddonForm.tsx │ │ │ │ ├── AddonFormContextProvider.tsx │ │ │ │ ├── AddonHeader.tsx │ │ │ │ ├── AddonSaveButton.tsx │ │ │ │ ├── AddonTabs.tsx │ │ │ │ ├── AddonTemplates.tsx │ │ │ │ ├── AddonView.tsx │ │ │ │ ├── ConfigureTemplate.tsx │ │ │ │ ├── ExpandedTemplate.tsx │ │ │ │ ├── common │ │ │ │ │ ├── Configuration.tsx │ │ │ │ │ ├── Logs.tsx │ │ │ │ │ └── Settings.tsx │ │ │ │ ├── datadog │ │ │ │ │ └── DatadogForm.tsx │ │ │ │ ├── legacy_AddOnDashboard.tsx │ │ │ │ ├── legacy_NewAddOnFlow.tsx │ │ │ │ ├── metabase │ │ │ │ │ └── MetabaseForm.tsx │ │ │ │ ├── mezmo │ │ │ │ │ └── MezmoForm.tsx │ │ │ │ ├── newrelic │ │ │ │ │ └── NewRelicForm.tsx │ │ │ │ ├── quivr │ │ │ │ │ └── QuivrForm.tsx │ │ │ │ └── tailscale │ │ │ │ │ ├── TailscaleForm.tsx │ │ │ │ │ └── TailscaleOverview.tsx │ │ │ │ ├── app-dashboard │ │ │ │ ├── app-view │ │ │ │ │ ├── AppDataContainer.tsx │ │ │ │ │ ├── AppHeader.tsx │ │ │ │ │ ├── AppSaveButton.tsx │ │ │ │ │ ├── AppView.tsx │ │ │ │ │ ├── ConfirmRedeployModal.tsx │ │ │ │ │ ├── GithubErrorBanner.tsx │ │ │ │ │ ├── LatestRevisionContext.tsx │ │ │ │ │ └── tabs │ │ │ │ │ │ ├── Activity.tsx │ │ │ │ │ │ ├── BuildSettingsTab.tsx │ │ │ │ │ │ ├── Environment.tsx │ │ │ │ │ │ ├── ExportAppModal.tsx │ │ │ │ │ │ ├── HelmEditorTab.tsx │ │ │ │ │ │ ├── HelmLatestValuesTab.tsx │ │ │ │ │ │ ├── ImageSettingsTab.tsx │ │ │ │ │ │ ├── JobsTab.tsx │ │ │ │ │ │ ├── LogsTab.tsx │ │ │ │ │ │ ├── MetricsTab.tsx │ │ │ │ │ │ ├── Notifications.tsx │ │ │ │ │ │ ├── Overview.tsx │ │ │ │ │ │ ├── Settings.tsx │ │ │ │ │ │ ├── Webhooks.tsx │ │ │ │ │ │ ├── activity-feed │ │ │ │ │ │ ├── ActivityFeed.tsx │ │ │ │ │ │ └── events │ │ │ │ │ │ │ ├── cards │ │ │ │ │ │ │ ├── BuildEventCard.tsx │ │ │ │ │ │ │ ├── DeployEventCard.tsx │ │ │ │ │ │ │ ├── EventCard.tsx │ │ │ │ │ │ │ ├── InitialDeployEventCard.tsx │ │ │ │ │ │ │ ├── PreDeployEventCard.tsx │ │ │ │ │ │ │ ├── RevertModal.tsx │ │ │ │ │ │ │ ├── RollbackEventCard.tsx │ │ │ │ │ │ │ └── ServiceStatusDetail.tsx │ │ │ │ │ │ │ ├── focus-views │ │ │ │ │ │ │ ├── BuildEventFocusView.tsx │ │ │ │ │ │ │ ├── EventFocusView.tsx │ │ │ │ │ │ │ ├── InitialDeployEventFocusView.tsx │ │ │ │ │ │ │ └── PredeployEventFocusView.tsx │ │ │ │ │ │ │ ├── modals │ │ │ │ │ │ │ └── RevisionDiffModal.tsx │ │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ └── notifications │ │ │ │ │ │ ├── NotificationFeed.tsx │ │ │ │ │ │ ├── NotificationList.tsx │ │ │ │ │ │ ├── NotificationTile.tsx │ │ │ │ │ │ └── expanded-views │ │ │ │ │ │ ├── NotificationContextProvider.tsx │ │ │ │ │ │ ├── NotificationExpandedView.tsx │ │ │ │ │ │ ├── RevisionNotificationExpandedView.tsx │ │ │ │ │ │ ├── ServiceNotificationExpandedView.tsx │ │ │ │ │ │ └── messages │ │ │ │ │ │ └── ServiceMessage.tsx │ │ │ │ ├── apps │ │ │ │ │ ├── Addon.tsx │ │ │ │ │ ├── AppGrid.tsx │ │ │ │ │ ├── AppMeta.tsx │ │ │ │ │ ├── Apps.tsx │ │ │ │ │ └── types.ts │ │ │ │ ├── build-settings │ │ │ │ │ ├── BranchSelector.tsx │ │ │ │ │ ├── ProviderSelector.tsx │ │ │ │ │ └── RepositorySelector.tsx │ │ │ │ ├── create-app │ │ │ │ │ ├── BuildSettings.tsx │ │ │ │ │ ├── CreateApp.tsx │ │ │ │ │ ├── PorterYamlInput.tsx │ │ │ │ │ └── RepoSettings.tsx │ │ │ │ ├── expanded-app │ │ │ │ │ ├── DeleteApplicationModal.tsx │ │ │ │ │ ├── GHABanner.tsx │ │ │ │ │ ├── logs │ │ │ │ │ │ └── types.ts │ │ │ │ │ └── metrics │ │ │ │ │ │ ├── AreaChart.tsx │ │ │ │ │ │ ├── MetricsChart.tsx │ │ │ │ │ │ ├── StackedAreaChart.tsx │ │ │ │ │ │ ├── StatusCodeDataLegend.tsx │ │ │ │ │ │ ├── themes │ │ │ │ │ │ └── area.tsx │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ └── utils.ts │ │ │ │ ├── image-settings │ │ │ │ │ ├── ImageList.tsx │ │ │ │ │ ├── ImageSettings.tsx │ │ │ │ │ ├── TagList.tsx │ │ │ │ │ └── types.ts │ │ │ │ ├── new-app-flow │ │ │ │ │ ├── GithubActionModal.tsx │ │ │ │ │ ├── SourceSelector.tsx │ │ │ │ │ └── utils.ts │ │ │ │ ├── types │ │ │ │ │ └── porterApp.ts │ │ │ │ └── validate-apply │ │ │ │ │ ├── app-settings │ │ │ │ │ ├── EnvGroupModal.tsx │ │ │ │ │ ├── EnvGroupRow.tsx │ │ │ │ │ ├── EnvGroups.tsx │ │ │ │ │ ├── EnvSettings.tsx │ │ │ │ │ ├── EnvVarRow.tsx │ │ │ │ │ ├── EnvVariables.tsx │ │ │ │ │ └── types.ts │ │ │ │ │ ├── build-settings │ │ │ │ │ ├── FileSelector.tsx │ │ │ │ │ ├── buildpacks │ │ │ │ │ │ ├── AddCustomBuildpack.tsx │ │ │ │ │ │ ├── BuildpackCard.tsx │ │ │ │ │ │ ├── BuildpackConfigurationModal.tsx │ │ │ │ │ │ ├── BuildpackList.tsx │ │ │ │ │ │ └── BuildpackSettings.tsx │ │ │ │ │ └── docker │ │ │ │ │ │ └── DockerfileSettings.tsx │ │ │ │ │ ├── helm │ │ │ │ │ ├── HelmLatestValues.tsx │ │ │ │ │ └── HelmOverrides.tsx │ │ │ │ │ ├── jobs │ │ │ │ │ ├── JobRunDetails.tsx │ │ │ │ │ ├── JobsSection.tsx │ │ │ │ │ ├── TriggerJobButton.tsx │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── logs │ │ │ │ │ ├── Logs.tsx │ │ │ │ │ ├── StyledLogs.tsx │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── metrics │ │ │ │ │ └── MetricsSection.tsx │ │ │ │ │ ├── revisions-list │ │ │ │ │ └── GHStatusBanner.tsx │ │ │ │ │ └── services-settings │ │ │ │ │ ├── ServiceContainer.tsx │ │ │ │ │ ├── ServiceList.tsx │ │ │ │ │ ├── footers │ │ │ │ │ ├── JobFooter.tsx │ │ │ │ │ └── ServiceStatusFooter.tsx │ │ │ │ │ └── tabs │ │ │ │ │ ├── Advanced.tsx │ │ │ │ │ ├── CustomDomains.tsx │ │ │ │ │ ├── GPUResources.tsx │ │ │ │ │ ├── Health.tsx │ │ │ │ │ ├── IngressCustomAnnotations.tsx │ │ │ │ │ ├── IntelligentSlider.tsx │ │ │ │ │ ├── JobTabs.tsx │ │ │ │ │ ├── Main.tsx │ │ │ │ │ ├── Networking.tsx │ │ │ │ │ ├── Resources.tsx │ │ │ │ │ ├── WebTabs.tsx │ │ │ │ │ └── WorkerTabs.tsx │ │ │ │ ├── cluster-dashboard │ │ │ │ ├── DashboardHeader.tsx │ │ │ │ ├── DashboardRouter.tsx │ │ │ │ ├── LastRunStatusSelector.tsx │ │ │ │ ├── NamespaceSelector.tsx │ │ │ │ ├── SortSelector.tsx │ │ │ │ ├── TagFilter.tsx │ │ │ │ ├── apps │ │ │ │ │ └── AppDashboard.tsx │ │ │ │ ├── chart │ │ │ │ │ ├── Chart.tsx │ │ │ │ │ ├── ChartList.tsx │ │ │ │ │ └── JobRunTable.tsx │ │ │ │ ├── dashboard │ │ │ │ │ ├── ClusterRevisionSelector.tsx │ │ │ │ │ ├── ClusterSettings.tsx │ │ │ │ │ ├── ClusterSettingsModal.tsx │ │ │ │ │ ├── Dashboard.tsx │ │ │ │ │ ├── Metrics.tsx │ │ │ │ │ ├── NamespaceList.tsx │ │ │ │ │ ├── NodeList.tsx │ │ │ │ │ ├── ProvisionerStatus.tsx │ │ │ │ │ ├── Routes.tsx │ │ │ │ │ └── node-view │ │ │ │ │ │ ├── ConditionsTable.tsx │ │ │ │ │ │ ├── ExpandedNodeView.tsx │ │ │ │ │ │ └── NodeUsage.tsx │ │ │ │ ├── env-groups │ │ │ │ │ ├── CreateEnvGroup.tsx │ │ │ │ │ ├── EnvGroup.tsx │ │ │ │ │ ├── EnvGroupArray.tsx │ │ │ │ │ ├── EnvGroupDashboard.tsx │ │ │ │ │ ├── EnvGroupList.tsx │ │ │ │ │ ├── ExpandedEnvGroup.tsx │ │ │ │ │ └── ExpandedEnvGroupDashboard.tsx │ │ │ │ ├── expanded-chart │ │ │ │ │ ├── CanonicalName.tsx │ │ │ │ │ ├── DeploymentType.tsx │ │ │ │ │ ├── ExpandedChart.tsx │ │ │ │ │ ├── ExpandedChartWrapper.tsx │ │ │ │ │ ├── ExpandedJobChart.tsx │ │ │ │ │ ├── GraphSection.tsx │ │ │ │ │ ├── ListSection.tsx │ │ │ │ │ ├── NotificationSettingsSection.tsx │ │ │ │ │ ├── RevisionSection.tsx │ │ │ │ │ ├── SettingsSection.tsx │ │ │ │ │ ├── TagSelector.tsx │ │ │ │ │ ├── ValuesYaml.tsx │ │ │ │ │ ├── build-settings │ │ │ │ │ │ ├── BuildSettingsTab.tsx │ │ │ │ │ │ ├── _BuildpackConfigSection.tsx │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── deploy-status-section │ │ │ │ │ │ ├── ControllerTab.tsx │ │ │ │ │ │ ├── DeployStatusSection.tsx │ │ │ │ │ │ ├── PodDropdown.tsx │ │ │ │ │ │ ├── PodRow.tsx │ │ │ │ │ │ ├── ResourceTab.tsx │ │ │ │ │ │ └── util.ts │ │ │ │ │ ├── events │ │ │ │ │ │ ├── EventList.tsx │ │ │ │ │ │ ├── EventsTab.tsx │ │ │ │ │ │ └── styles.ts │ │ │ │ │ ├── graph │ │ │ │ │ │ ├── Edge.tsx │ │ │ │ │ │ ├── GraphDisplay.tsx │ │ │ │ │ │ ├── InfoPanel.tsx │ │ │ │ │ │ ├── Node.tsx │ │ │ │ │ │ ├── SelectRegion.tsx │ │ │ │ │ │ └── ZoomPanel.tsx │ │ │ │ │ ├── incidents │ │ │ │ │ │ └── DisabledNamespaces.ts │ │ │ │ │ ├── jobs │ │ │ │ │ │ ├── ConnectToJobInstructionsModal.tsx │ │ │ │ │ │ ├── ExpandedJobRun.tsx │ │ │ │ │ │ ├── JobList.tsx │ │ │ │ │ │ ├── JobResource.tsx │ │ │ │ │ │ └── useJobs.ts │ │ │ │ │ ├── logs-section │ │ │ │ │ │ ├── LogsSection.tsx │ │ │ │ │ │ └── useAgentLogs.ts │ │ │ │ │ ├── metrics │ │ │ │ │ │ ├── AggregatedDataLegend.tsx │ │ │ │ │ │ ├── AreaChart.tsx │ │ │ │ │ │ ├── JobMetricsSection.tsx │ │ │ │ │ │ ├── MetricNormalizer.ts │ │ │ │ │ │ ├── MetricsSection.tsx │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── status │ │ │ │ │ │ ├── ControllerTab.tsx │ │ │ │ │ │ ├── Logs.tsx │ │ │ │ │ │ ├── PodRow.tsx │ │ │ │ │ │ ├── StatusSection.tsx │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ └── useLogs.ts │ │ │ │ │ └── useStackEnvGroups.ts │ │ │ │ ├── jobs │ │ │ │ │ └── JobDashboard.tsx │ │ │ │ ├── preview-environments │ │ │ │ │ ├── ConnectNewRepo.tsx │ │ │ │ │ ├── ConnectNewRepoActionConfEditor.tsx │ │ │ │ │ ├── components │ │ │ │ │ │ ├── ActionButton.tsx │ │ │ │ │ │ ├── BranchFilterSelector.tsx │ │ │ │ │ │ ├── ButtonEnablePREnvironments.tsx │ │ │ │ │ │ ├── NamespaceLabels.tsx │ │ │ │ │ │ ├── PorterYAMLErrorsModal.tsx │ │ │ │ │ │ ├── PreviewEnvironmentsHeader.tsx │ │ │ │ │ │ └── styled.tsx │ │ │ │ │ ├── deployments │ │ │ │ │ │ ├── DeploymentCard.tsx │ │ │ │ │ │ ├── DeploymentDetail.tsx │ │ │ │ │ │ ├── DeploymentList.tsx │ │ │ │ │ │ └── PreviewEnvDeleted.tsx │ │ │ │ │ ├── environments │ │ │ │ │ │ ├── CreateBranchEnvironment.tsx │ │ │ │ │ │ ├── CreateEnvironment.tsx │ │ │ │ │ │ ├── CreatePREnvironment.tsx │ │ │ │ │ │ ├── EnvironmentCard.tsx │ │ │ │ │ │ ├── EnvironmentSettings.tsx │ │ │ │ │ │ └── EnvironmentsList.tsx │ │ │ │ │ ├── errors.ts │ │ │ │ │ ├── mocks.ts │ │ │ │ │ ├── routes.tsx │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── utils.ts │ │ │ │ │ └── v2 │ │ │ │ │ │ ├── ConfigurableAppList.tsx │ │ │ │ │ │ ├── ConfigurableAppRow.tsx │ │ │ │ │ │ ├── EnvTemplateContextProvider.tsx │ │ │ │ │ │ ├── PreviewEnvGrid.tsx │ │ │ │ │ │ ├── PreviewEnvs.tsx │ │ │ │ │ │ ├── setup-app │ │ │ │ │ │ ├── Addons.tsx │ │ │ │ │ │ ├── AppSelector.tsx │ │ │ │ │ │ ├── ConsolidatedServices.tsx │ │ │ │ │ │ ├── CreateTemplate.tsx │ │ │ │ │ │ ├── PreviewAppDataContainer.tsx │ │ │ │ │ │ ├── PreviewGHAModal.tsx │ │ │ │ │ │ ├── PreviewSaveButton.tsx │ │ │ │ │ │ ├── RequiredApps.tsx │ │ │ │ │ │ ├── RevisionLoader.tsx │ │ │ │ │ │ ├── ServiceSettings.tsx │ │ │ │ │ │ └── SetupApp.tsx │ │ │ │ │ │ └── types.ts │ │ │ │ └── stacks │ │ │ │ │ ├── Dashboard.tsx │ │ │ │ │ ├── ExpandedStack │ │ │ │ │ ├── ExpandedStack.tsx │ │ │ │ │ ├── NewAppResource │ │ │ │ │ │ ├── _Settings.tsx │ │ │ │ │ │ ├── _TemplateSelector.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── NewEnvGroup.tsx │ │ │ │ │ ├── Store.tsx │ │ │ │ │ ├── _RevisionList.tsx │ │ │ │ │ ├── _SourceConfig.tsx │ │ │ │ │ ├── components │ │ │ │ │ │ ├── EnvGroups.tsx │ │ │ │ │ │ ├── Select.tsx │ │ │ │ │ │ ├── Settings.tsx │ │ │ │ │ │ └── SourceEditorDocker.tsx │ │ │ │ │ └── routes.tsx │ │ │ │ │ ├── _StackList.tsx │ │ │ │ │ ├── components │ │ │ │ │ ├── NewAppResourceForm.tsx │ │ │ │ │ ├── NewEnvGroupForm.tsx │ │ │ │ │ ├── Status.tsx │ │ │ │ │ └── styles.ts │ │ │ │ │ ├── launch │ │ │ │ │ ├── NewApp.tsx │ │ │ │ │ ├── NewEnvGroup.tsx │ │ │ │ │ ├── Overview.tsx │ │ │ │ │ ├── SelectSource.tsx │ │ │ │ │ ├── Store.tsx │ │ │ │ │ ├── components │ │ │ │ │ │ ├── AddResourceButton.tsx │ │ │ │ │ │ ├── TemplateSelector.tsx │ │ │ │ │ │ ├── VersionSelector.tsx │ │ │ │ │ │ └── styles.tsx │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── routes.tsx │ │ │ │ │ ├── shared.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── compliance-dashboard │ │ │ │ ├── ActionBanner.tsx │ │ │ │ ├── ComplianceContext.tsx │ │ │ │ ├── ComplianceDashboard.tsx │ │ │ │ ├── ConfigSelectors.tsx │ │ │ │ ├── ProfileHeader.tsx │ │ │ │ ├── SOC2CostConsent.tsx │ │ │ │ ├── VendorChecksList.tsx │ │ │ │ └── types.ts │ │ │ │ ├── dashboard │ │ │ │ ├── ClusterList.tsx │ │ │ │ ├── ClusterPlaceholder.tsx │ │ │ │ ├── ClusterPlaceholderContainer.tsx │ │ │ │ ├── ClusterSection.tsx │ │ │ │ ├── Dashboard.tsx │ │ │ │ └── OldClusterList.tsx │ │ │ │ ├── database-dashboard │ │ │ │ ├── DatabaseContextProvider.tsx │ │ │ │ ├── DatabaseDashboard.tsx │ │ │ │ ├── DatabaseHeader.tsx │ │ │ │ ├── DatabaseTabs.tsx │ │ │ │ ├── DatabaseView.tsx │ │ │ │ ├── DatastoreFormContextProvider.tsx │ │ │ │ ├── DatastoreProvisioningIndicator.tsx │ │ │ │ ├── constants.ts │ │ │ │ ├── forms │ │ │ │ │ ├── CreateDatastore.tsx │ │ │ │ │ ├── DatastoreForm.tsx │ │ │ │ │ └── SandboxDatastoreForm.tsx │ │ │ │ ├── shared │ │ │ │ │ ├── ConnectAppsModal.tsx │ │ │ │ │ ├── ConnectionInfo.tsx │ │ │ │ │ ├── NeonIntegrationModal.tsx │ │ │ │ │ └── Resources.tsx │ │ │ │ ├── tabs │ │ │ │ │ ├── ConfigurationTab.tsx │ │ │ │ │ ├── ConnectTab.tsx │ │ │ │ │ ├── PublicDatastoreConnectTab.tsx │ │ │ │ │ └── SettingsTab.tsx │ │ │ │ └── tags │ │ │ │ │ └── EngineTag.tsx │ │ │ │ ├── env-dashboard │ │ │ │ ├── CreateEnvGroup.tsx │ │ │ │ ├── EnvDashboard.tsx │ │ │ │ ├── EnvGroup.tsx │ │ │ │ ├── EnvGroupArray.tsx │ │ │ │ ├── ExpandedEnv.tsx │ │ │ │ └── tabs │ │ │ │ │ ├── EnvVarsTab.tsx │ │ │ │ │ ├── SettingsTab.tsx │ │ │ │ │ └── SyncedAppsTab.tsx │ │ │ │ ├── infrastructure-dashboard │ │ │ │ ├── ClusterContextProvider.tsx │ │ │ │ ├── ClusterContractViewModal.tsx │ │ │ │ ├── ClusterDashboard.tsx │ │ │ │ ├── ClusterFormContextProvider.tsx │ │ │ │ ├── ClusterHeader.tsx │ │ │ │ ├── ClusterProvisioningIndicator.tsx │ │ │ │ ├── ClusterSaveButton.tsx │ │ │ │ ├── ClusterStatus.tsx │ │ │ │ ├── ClusterTabs.tsx │ │ │ │ ├── ClusterView.tsx │ │ │ │ ├── forms │ │ │ │ │ ├── CloudProviderSelect.tsx │ │ │ │ │ ├── CreateClusterForm.tsx │ │ │ │ │ ├── aws │ │ │ │ │ │ ├── ConfigureEKSCluster.tsx │ │ │ │ │ │ ├── CreateEKSClusterForm.tsx │ │ │ │ │ │ └── GrantAWSPermissions.tsx │ │ │ │ │ ├── azure │ │ │ │ │ │ ├── ConfigureAKSCluster.tsx │ │ │ │ │ │ ├── CreateAKSClusterForm.tsx │ │ │ │ │ │ └── GrantAzurePermissions.tsx │ │ │ │ │ └── gcp │ │ │ │ │ │ ├── ConfigureGKECluster.tsx │ │ │ │ │ │ ├── CreateGKEClusterForm.tsx │ │ │ │ │ │ └── GrantGCPPermissions.tsx │ │ │ │ ├── modals │ │ │ │ │ ├── PreflightChecksModal.tsx │ │ │ │ │ ├── cost-consent │ │ │ │ │ │ ├── AWSCostConsentModalContents.tsx │ │ │ │ │ │ ├── AzureCostConsentModalContents.tsx │ │ │ │ │ │ ├── CostConsentModal.tsx │ │ │ │ │ │ └── GCPCostConsentModalContents.tsx │ │ │ │ │ └── help │ │ │ │ │ │ ├── permissions │ │ │ │ │ │ └── GrantAWSPermissionsHelpModal.tsx │ │ │ │ │ │ └── preflight │ │ │ │ │ │ └── ResolutionStepsModalContents.tsx │ │ │ │ ├── shared │ │ │ │ │ ├── NodeGroups.tsx │ │ │ │ │ └── advanced │ │ │ │ │ │ ├── AdvancedSettings.tsx │ │ │ │ │ │ └── EKSClusterAdvancedSettings.tsx │ │ │ │ └── tabs │ │ │ │ │ ├── AdvancedSettingsTab.tsx │ │ │ │ │ ├── Settings.tsx │ │ │ │ │ ├── SystemStatus.tsx │ │ │ │ │ └── overview │ │ │ │ │ ├── AKSClusterOverview.tsx │ │ │ │ │ ├── ClusterOverview.tsx │ │ │ │ │ ├── EKSClusterOverview.tsx │ │ │ │ │ └── GKEClusterOverview.tsx │ │ │ │ ├── integrations │ │ │ │ ├── DopplerIntegrationList.tsx │ │ │ │ ├── GitlabIntegrationList.tsx │ │ │ │ ├── IntegrationCategories.tsx │ │ │ │ ├── IntegrationList.tsx │ │ │ │ ├── IntegrationRow.tsx │ │ │ │ ├── Integrations.tsx │ │ │ │ ├── SlackIntegrationList.tsx │ │ │ │ ├── create-integration │ │ │ │ │ ├── CreateIntegrationForm.tsx │ │ │ │ │ ├── DockerHubForm.tsx │ │ │ │ │ ├── ECRForm.tsx │ │ │ │ │ ├── EKSForm.tsx │ │ │ │ │ ├── GARForm.tsx │ │ │ │ │ ├── GCRForm.tsx │ │ │ │ │ ├── GKEForm.tsx │ │ │ │ │ └── GitlabForm.tsx │ │ │ │ └── infisical │ │ │ │ │ ├── AddInfisicalEnvModal.tsx │ │ │ │ │ └── InfisicalIntegrationList.tsx │ │ │ │ ├── launch │ │ │ │ ├── Launch.tsx │ │ │ │ ├── LaunchWrapper.tsx │ │ │ │ ├── TemplateList.tsx │ │ │ │ ├── expanded-template │ │ │ │ │ ├── ExpandedTemplate.tsx │ │ │ │ │ └── TemplateInfo.tsx │ │ │ │ └── launch-flow │ │ │ │ │ ├── LaunchFlow.tsx │ │ │ │ │ ├── SettingsPage.tsx │ │ │ │ │ ├── SourcePage.tsx │ │ │ │ │ └── WorkflowPage.tsx │ │ │ │ ├── modals │ │ │ │ ├── AccountSettingsModal.tsx │ │ │ │ ├── BillingModal.tsx │ │ │ │ ├── ClusterInstructionsModal.tsx │ │ │ │ ├── ConnectToDatabaseInstructionsModal.tsx │ │ │ │ ├── DeleteNamespaceModal.tsx │ │ │ │ ├── EditInviteOrCollaboratorModal.tsx │ │ │ │ ├── EnvEditorModal.tsx │ │ │ │ ├── IntegrationsInstructionsModal.tsx │ │ │ │ ├── IntegrationsModal.tsx │ │ │ │ ├── LoadEnvGroupModal.tsx │ │ │ │ ├── Modal.tsx │ │ │ │ ├── NamespaceModal.tsx │ │ │ │ ├── PaymentSetupForm.tsx │ │ │ │ ├── PreviewEnvSettingsModal.tsx │ │ │ │ ├── RedirectToOnboardingModal.tsx │ │ │ │ ├── SkipProvisioningModal.tsx │ │ │ │ ├── UpdateClusterModal.tsx │ │ │ │ └── UsageWarningModal.tsx │ │ │ │ ├── navbar │ │ │ │ ├── Help.tsx │ │ │ │ └── Navbar.tsx │ │ │ │ ├── new-project │ │ │ │ ├── NewProject.tsx │ │ │ │ └── WelcomeForm.tsx │ │ │ │ ├── onboarding │ │ │ │ ├── Onboarding.tsx │ │ │ │ ├── Routes.tsx │ │ │ │ ├── components │ │ │ │ │ └── ProviderSelector.tsx │ │ │ │ ├── state │ │ │ │ │ ├── StateHandler.ts │ │ │ │ │ ├── StepHandler.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── steps │ │ │ │ │ ├── ConnectRegistry │ │ │ │ │ │ ├── ConnectRegistry.tsx │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ └── Registry.tsx │ │ │ │ │ │ └── forms │ │ │ │ │ │ │ ├── FormFlow.tsx │ │ │ │ │ │ │ ├── _AWSRegistryForm.tsx │ │ │ │ │ │ │ └── _GCPRegistryForm.tsx │ │ │ │ │ ├── ConnectSource.tsx │ │ │ │ │ └── ProvisionResources │ │ │ │ │ │ ├── ProvisionResources.tsx │ │ │ │ │ │ └── forms │ │ │ │ │ │ ├── FormFlow.tsx │ │ │ │ │ │ ├── StatusPage.tsx │ │ │ │ │ │ ├── _AWSProvisionerForm.tsx │ │ │ │ │ │ ├── _ConnectExternalCluster.tsx │ │ │ │ │ │ └── _GCPProvisionerForm.tsx │ │ │ │ └── types.ts │ │ │ │ ├── project-settings │ │ │ │ ├── APITokensSection.tsx │ │ │ │ ├── BillingPage.tsx │ │ │ │ ├── InviteList.tsx │ │ │ │ ├── Metadata.tsx │ │ │ │ ├── PermissionGroup.tsx │ │ │ │ ├── ProjectDeleteConsent.tsx │ │ │ │ ├── ProjectSettings.tsx │ │ │ │ ├── RoleModal.tsx │ │ │ │ ├── UsagePage.tsx │ │ │ │ └── api-tokens │ │ │ │ │ ├── CreateAPITokenForm.tsx │ │ │ │ │ ├── CustomPolicyForm.tsx │ │ │ │ │ └── TokenList.tsx │ │ │ │ ├── provisioner │ │ │ │ ├── AWSFormSection.tsx │ │ │ │ ├── AzureFormSection.tsx │ │ │ │ ├── DOFormSection.tsx │ │ │ │ ├── ExistingClusterSection.tsx │ │ │ │ ├── GCPFormSection.tsx │ │ │ │ └── ProvisionerSettings.tsx │ │ │ │ └── sidebar │ │ │ │ ├── AddCluster │ │ │ │ ├── AWSCredentialForm.tsx │ │ │ │ ├── AWSCredentialList.tsx │ │ │ │ └── CredentialList.tsx │ │ │ │ ├── ClusterList.tsx │ │ │ │ ├── ClusterListContainer.tsx │ │ │ │ ├── ClusterSection.tsx │ │ │ │ ├── Clusters.tsx │ │ │ │ ├── ProjectButton.tsx │ │ │ │ ├── ProjectSectionContainer.tsx │ │ │ │ ├── ProjectSelectionModal.tsx │ │ │ │ ├── ProvisionClusterModal.tsx │ │ │ │ ├── Sidebar.tsx │ │ │ │ └── SidebarLink.tsx │ │ ├── shared │ │ │ ├── ace-porter-theme.js │ │ │ ├── anayltics │ │ │ │ ├── index.ts │ │ │ │ └── onboarding │ │ │ │ │ ├── events.ts │ │ │ │ │ ├── tracks.ts │ │ │ │ │ └── types.ts │ │ │ ├── api.tsx │ │ │ ├── array_utils.ts │ │ │ ├── baseApi.ts │ │ │ ├── common.tsx │ │ │ ├── error_handling │ │ │ │ ├── PorterErrorBoundary.tsx │ │ │ │ ├── logger.ts │ │ │ │ └── stack_trace_utils.ts │ │ │ ├── hardcodedNameDict.tsx │ │ │ ├── hooks │ │ │ │ ├── useChart.ts │ │ │ │ ├── useOutsideAlerter.ts │ │ │ │ ├── usePagination.ts │ │ │ │ ├── usePods.ts │ │ │ │ ├── usePrevious.ts │ │ │ │ └── useWebsockets.ts │ │ │ ├── icons │ │ │ │ ├── PullRequest.tsx │ │ │ │ └── types.ts │ │ │ ├── images.d.ts │ │ │ ├── release │ │ │ │ └── utils.ts │ │ │ ├── rosettaStone.tsx │ │ │ ├── routing.tsx │ │ │ ├── search.ts │ │ │ ├── string_utils.ts │ │ │ ├── themes │ │ │ │ ├── midnight.ts │ │ │ │ ├── opal.ts │ │ │ │ └── standard.ts │ │ │ ├── types.tsx │ │ │ └── util.ts │ │ └── test-utils.tsx │ ├── lib │ │ ├── addons │ │ │ ├── datadog.ts │ │ │ ├── index.ts │ │ │ ├── metabase.ts │ │ │ ├── mezmo.ts │ │ │ ├── newrelic.ts │ │ │ ├── postgres.ts │ │ │ ├── quivr.ts │ │ │ ├── redis.ts │ │ │ ├── tailscale.ts │ │ │ └── template.ts │ │ ├── billing │ │ │ └── types.tsx │ │ ├── clusters │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── databases │ │ │ └── types.ts │ │ ├── env-groups │ │ │ └── types.ts │ │ ├── environments │ │ │ └── types.ts │ │ ├── github │ │ │ └── workflows.ts │ │ ├── hooks │ │ │ ├── UseOutsideClick.ts │ │ │ ├── useAddon.ts │ │ │ ├── useAppAnalytics.ts │ │ │ ├── useAppStatus.ts │ │ │ ├── useAppValidation.ts │ │ │ ├── useAppWithPreviewOverrides.ts │ │ │ ├── useAuthWindow.ts │ │ │ ├── useCloudProvider.ts │ │ │ ├── useCloudSqlSecret.ts │ │ │ ├── useCluster.ts │ │ │ ├── useClusterAnalytics.ts │ │ │ ├── useDatabaseList.ts │ │ │ ├── useDatastore.ts │ │ │ ├── useDeploymentTarget.ts │ │ │ ├── useEnvGroups.ts │ │ │ ├── useGithubContents.ts │ │ │ ├── useGithubWorkflow.ts │ │ │ ├── useIntercom.ts │ │ │ ├── useJobs.ts │ │ │ ├── useLago.ts │ │ │ ├── useLatestAppRevisions.ts │ │ │ ├── useNeon.ts │ │ │ ├── useNodeGroups.ts │ │ │ ├── usePorterYaml.ts │ │ │ ├── useRevisionList.ts │ │ │ ├── useStripe.ts │ │ │ ├── useTemplateEnvs.ts │ │ │ └── useUpstash.ts │ │ ├── neon │ │ │ └── types.ts │ │ ├── notifications │ │ │ └── types.ts │ │ ├── porter-apps │ │ │ ├── build.ts │ │ │ ├── error.ts │ │ │ ├── index.ts │ │ │ ├── notification.ts │ │ │ ├── routing.ts │ │ │ ├── services.ts │ │ │ └── values.ts │ │ ├── revisions │ │ │ └── types.ts │ │ └── upstash │ │ │ └── types.ts │ ├── main │ │ ├── CurrentError.tsx │ │ ├── Main.tsx │ │ ├── MainWrapper.tsx │ │ ├── auth │ │ │ ├── InfoPanel.tsx │ │ │ ├── Login.tsx │ │ │ ├── LoginWrapper.tsx │ │ │ ├── OryLogin.tsx │ │ │ ├── Register.tsx │ │ │ ├── ResetPasswordFinalize.tsx │ │ │ ├── ResetPasswordInit.tsx │ │ │ ├── SetInfo.tsx │ │ │ └── VerifyEmail.tsx │ │ └── home │ │ │ ├── Home.tsx │ │ │ ├── ModalHandler.tsx │ │ │ ├── NoClusterPlaceholder.tsx │ │ │ ├── add-on-dashboard │ │ │ ├── AddOnDashboard.tsx │ │ │ ├── AddonContextProvider.tsx │ │ │ ├── AddonForm.tsx │ │ │ ├── AddonFormContextProvider.tsx │ │ │ ├── AddonHeader.tsx │ │ │ ├── AddonSaveButton.tsx │ │ │ ├── AddonTabs.tsx │ │ │ ├── AddonTemplates.tsx │ │ │ ├── AddonView.tsx │ │ │ ├── ConfigureTemplate.tsx │ │ │ ├── ExpandedTemplate.tsx │ │ │ ├── common │ │ │ │ ├── Configuration.tsx │ │ │ │ ├── Logs.tsx │ │ │ │ └── Settings.tsx │ │ │ ├── datadog │ │ │ │ └── DatadogForm.tsx │ │ │ ├── legacy_AddOnDashboard.tsx │ │ │ ├── legacy_NewAddOnFlow.tsx │ │ │ ├── metabase │ │ │ │ └── MetabaseForm.tsx │ │ │ ├── mezmo │ │ │ │ └── MezmoForm.tsx │ │ │ ├── newrelic │ │ │ │ └── NewRelicForm.tsx │ │ │ ├── quivr │ │ │ │ └── QuivrForm.tsx │ │ │ └── tailscale │ │ │ │ ├── TailscaleForm.tsx │ │ │ │ └── TailscaleOverview.tsx │ │ │ ├── app-dashboard │ │ │ ├── app-view │ │ │ │ ├── AppDataContainer.tsx │ │ │ │ ├── AppHeader.tsx │ │ │ │ ├── AppSaveButton.tsx │ │ │ │ ├── AppView.tsx │ │ │ │ ├── ConfirmRedeployModal.tsx │ │ │ │ ├── GithubErrorBanner.tsx │ │ │ │ ├── LatestRevisionContext.tsx │ │ │ │ └── tabs │ │ │ │ │ ├── Activity.tsx │ │ │ │ │ ├── BuildSettingsTab.tsx │ │ │ │ │ ├── Environment.tsx │ │ │ │ │ ├── ExportAppModal.tsx │ │ │ │ │ ├── HelmEditorTab.tsx │ │ │ │ │ ├── HelmLatestValuesTab.tsx │ │ │ │ │ ├── ImageSettingsTab.tsx │ │ │ │ │ ├── JobsTab.tsx │ │ │ │ │ ├── LogsTab.tsx │ │ │ │ │ ├── MetricsTab.tsx │ │ │ │ │ ├── Notifications.tsx │ │ │ │ │ ├── Overview.tsx │ │ │ │ │ ├── Settings.tsx │ │ │ │ │ ├── Webhooks.tsx │ │ │ │ │ ├── activity-feed │ │ │ │ │ ├── ActivityFeed.tsx │ │ │ │ │ └── events │ │ │ │ │ │ ├── cards │ │ │ │ │ │ ├── BuildEventCard.tsx │ │ │ │ │ │ ├── DeployEventCard.tsx │ │ │ │ │ │ ├── EventCard.tsx │ │ │ │ │ │ ├── InitialDeployEventCard.tsx │ │ │ │ │ │ ├── PreDeployEventCard.tsx │ │ │ │ │ │ ├── RevertModal.tsx │ │ │ │ │ │ ├── RollbackEventCard.tsx │ │ │ │ │ │ └── ServiceStatusDetail.tsx │ │ │ │ │ │ ├── focus-views │ │ │ │ │ │ ├── BuildEventFocusView.tsx │ │ │ │ │ │ ├── EventFocusView.tsx │ │ │ │ │ │ ├── InitialDeployEventFocusView.tsx │ │ │ │ │ │ └── PredeployEventFocusView.tsx │ │ │ │ │ │ ├── modals │ │ │ │ │ │ └── RevisionDiffModal.tsx │ │ │ │ │ │ ├── types.ts │ │ │ │ │ │ └── utils.ts │ │ │ │ │ └── notifications │ │ │ │ │ ├── NotificationFeed.tsx │ │ │ │ │ ├── NotificationList.tsx │ │ │ │ │ ├── NotificationTile.tsx │ │ │ │ │ └── expanded-views │ │ │ │ │ ├── NotificationContextProvider.tsx │ │ │ │ │ ├── NotificationExpandedView.tsx │ │ │ │ │ ├── RevisionNotificationExpandedView.tsx │ │ │ │ │ ├── ServiceNotificationExpandedView.tsx │ │ │ │ │ └── messages │ │ │ │ │ └── ServiceMessage.tsx │ │ │ ├── apps │ │ │ │ ├── Addon.tsx │ │ │ │ ├── AppGrid.tsx │ │ │ │ ├── AppMeta.tsx │ │ │ │ ├── Apps.tsx │ │ │ │ ├── SelectableAppList.tsx │ │ │ │ └── types.ts │ │ │ ├── build-settings │ │ │ │ ├── BranchSelector.tsx │ │ │ │ ├── ProviderSelector.tsx │ │ │ │ └── RepositorySelector.tsx │ │ │ ├── create-app │ │ │ │ ├── BuildSettings.tsx │ │ │ │ ├── CreateApp.tsx │ │ │ │ ├── PorterYamlInput.tsx │ │ │ │ └── RepoSettings.tsx │ │ │ ├── expanded-app │ │ │ │ ├── DeleteApplicationModal.tsx │ │ │ │ ├── GHABanner.tsx │ │ │ │ ├── logs │ │ │ │ │ └── types.ts │ │ │ │ └── metrics │ │ │ │ │ ├── AreaChart.tsx │ │ │ │ │ ├── MetricsChart.tsx │ │ │ │ │ ├── StackedAreaChart.tsx │ │ │ │ │ ├── StatusCodeDataLegend.tsx │ │ │ │ │ ├── themes │ │ │ │ │ └── area.tsx │ │ │ │ │ ├── types.ts │ │ │ │ │ └── utils.ts │ │ │ ├── image-settings │ │ │ │ ├── ImageList.tsx │ │ │ │ ├── ImageSettings.tsx │ │ │ │ ├── TagList.tsx │ │ │ │ └── types.ts │ │ │ ├── new-app-flow │ │ │ │ ├── GithubActionModal.tsx │ │ │ │ ├── SourceSelector.tsx │ │ │ │ └── utils.ts │ │ │ ├── types │ │ │ │ ├── buildpack.ts │ │ │ │ └── porterApp.ts │ │ │ └── validate-apply │ │ │ │ ├── app-settings │ │ │ │ ├── EnvGroupModal.tsx │ │ │ │ ├── EnvGroupRow.tsx │ │ │ │ ├── EnvGroups.tsx │ │ │ │ ├── EnvSettings.tsx │ │ │ │ ├── EnvVarRow.tsx │ │ │ │ ├── EnvVariables.tsx │ │ │ │ └── types.ts │ │ │ │ ├── build-settings │ │ │ │ ├── FileSelector.tsx │ │ │ │ ├── buildpacks │ │ │ │ │ ├── AddCustomBuildpack.tsx │ │ │ │ │ ├── BuildpackCard.tsx │ │ │ │ │ ├── BuildpackConfigurationModal.tsx │ │ │ │ │ ├── BuildpackList.tsx │ │ │ │ │ └── BuildpackSettings.tsx │ │ │ │ └── docker │ │ │ │ │ └── DockerfileSettings.tsx │ │ │ │ ├── helm │ │ │ │ ├── HelmLatestValues.tsx │ │ │ │ └── HelmOverrides.tsx │ │ │ │ ├── jobs │ │ │ │ ├── JobRunDetails.tsx │ │ │ │ ├── JobsSection.tsx │ │ │ │ ├── TriggerJobButton.tsx │ │ │ │ └── utils.ts │ │ │ │ ├── logs │ │ │ │ ├── Logs.tsx │ │ │ │ ├── StyledLogs.tsx │ │ │ │ └── utils.ts │ │ │ │ ├── metrics │ │ │ │ └── MetricsSection.tsx │ │ │ │ ├── revisions-list │ │ │ │ └── GHStatusBanner.tsx │ │ │ │ └── services-settings │ │ │ │ ├── ServiceContainer.tsx │ │ │ │ ├── ServiceList.tsx │ │ │ │ ├── footers │ │ │ │ ├── JobFooter.tsx │ │ │ │ └── ServiceStatusFooter.tsx │ │ │ │ └── tabs │ │ │ │ ├── Advanced.tsx │ │ │ │ ├── CustomDomains.tsx │ │ │ │ ├── GPUResources.tsx │ │ │ │ ├── Health.tsx │ │ │ │ ├── IngressCustomAnnotations.tsx │ │ │ │ ├── IntelligentSlider.tsx │ │ │ │ ├── JobTabs.tsx │ │ │ │ ├── Main.tsx │ │ │ │ ├── Networking.tsx │ │ │ │ ├── Resources.tsx │ │ │ │ ├── WebTabs.tsx │ │ │ │ └── WorkerTabs.tsx │ │ │ ├── cluster-dashboard │ │ │ ├── DashboardHeader.tsx │ │ │ ├── dashboard │ │ │ │ └── ClusterRevisionSelector.tsx │ │ │ ├── env-groups │ │ │ │ └── EnvGroupArray.tsx │ │ │ ├── expanded-chart │ │ │ │ └── metrics │ │ │ │ │ ├── AggregatedDataLegend.tsx │ │ │ │ │ ├── types.ts │ │ │ │ │ └── utils.ts │ │ │ ├── preview-environments │ │ │ │ ├── types.ts │ │ │ │ └── v2 │ │ │ │ │ ├── ConfigurableAppList.tsx │ │ │ │ │ ├── ConfigurableAppRow.tsx │ │ │ │ │ ├── DeleteEnvModal.tsx │ │ │ │ │ ├── EnvTemplateContextProvider.tsx │ │ │ │ │ ├── PreviewEnvGrid.tsx │ │ │ │ │ ├── PreviewEnvs.tsx │ │ │ │ │ ├── setup-app │ │ │ │ │ ├── Addons.tsx │ │ │ │ │ ├── AppSelector.tsx │ │ │ │ │ ├── ConsolidatedServices.tsx │ │ │ │ │ ├── CreateTemplate.tsx │ │ │ │ │ ├── PreviewAppDataContainer.tsx │ │ │ │ │ ├── PreviewGHAModal.tsx │ │ │ │ │ ├── PreviewSaveButton.tsx │ │ │ │ │ ├── RequiredApps.tsx │ │ │ │ │ ├── RevisionLoader.tsx │ │ │ │ │ ├── ServiceSettings.tsx │ │ │ │ │ └── SetupApp.tsx │ │ │ │ │ └── types.ts │ │ │ └── stacks │ │ │ │ ├── components │ │ │ │ └── styles.ts │ │ │ │ └── types.ts │ │ │ ├── compliance-dashboard │ │ │ ├── ActionBanner.tsx │ │ │ ├── ComplianceContext.tsx │ │ │ ├── ComplianceDashboard.tsx │ │ │ ├── ConfigSelectors.tsx │ │ │ ├── ProfileHeader.tsx │ │ │ ├── SOC2CostConsent.tsx │ │ │ ├── VendorChecksList.tsx │ │ │ └── types.ts │ │ │ ├── dashboard │ │ │ ├── ClusterList.tsx │ │ │ ├── ClusterPlaceholder.tsx │ │ │ ├── ClusterPlaceholderContainer.tsx │ │ │ ├── ClusterSection.tsx │ │ │ ├── Dashboard.tsx │ │ │ └── OldClusterList.tsx │ │ │ ├── database-dashboard │ │ │ ├── DatabaseContextProvider.tsx │ │ │ ├── DatabaseDashboard.tsx │ │ │ ├── DatabaseHeader.tsx │ │ │ ├── DatabaseTabs.tsx │ │ │ ├── DatabaseView.tsx │ │ │ ├── DatastoreFormContextProvider.tsx │ │ │ ├── DatastoreProvisioningIndicator.tsx │ │ │ ├── constants.ts │ │ │ ├── forms │ │ │ │ ├── CreateDatastore.tsx │ │ │ │ ├── DatastoreForm.tsx │ │ │ │ └── SandboxDatastoreForm.tsx │ │ │ ├── shared │ │ │ │ ├── ConnectAppsModal.tsx │ │ │ │ ├── ConnectionInfo.tsx │ │ │ │ ├── NeonIntegrationModal.tsx │ │ │ │ └── Resources.tsx │ │ │ ├── tabs │ │ │ │ ├── ConfigurationTab.tsx │ │ │ │ ├── ConnectTab.tsx │ │ │ │ ├── PublicDatastoreConnectTab.tsx │ │ │ │ └── SettingsTab.tsx │ │ │ └── tags │ │ │ │ └── EngineTag.tsx │ │ │ ├── env-dashboard │ │ │ ├── CreateEnvGroup.tsx │ │ │ ├── EnvDashboard.tsx │ │ │ ├── EnvGroup.tsx │ │ │ ├── EnvGroupArray.tsx │ │ │ ├── ExpandedEnv.tsx │ │ │ └── tabs │ │ │ │ ├── EnvVarsTab.tsx │ │ │ │ ├── SettingsTab.tsx │ │ │ │ └── SyncedAppsTab.tsx │ │ │ ├── infrastructure-dashboard │ │ │ ├── ClusterContextProvider.tsx │ │ │ ├── ClusterContractViewModal.tsx │ │ │ ├── ClusterDashboard.tsx │ │ │ ├── ClusterFormContextProvider.tsx │ │ │ ├── ClusterHeader.tsx │ │ │ ├── ClusterProvisioningIndicator.tsx │ │ │ ├── ClusterSaveButton.tsx │ │ │ ├── ClusterStatus.tsx │ │ │ ├── ClusterTabs.tsx │ │ │ ├── ClusterView.tsx │ │ │ ├── forms │ │ │ │ ├── CloudProviderSelect.tsx │ │ │ │ ├── CreateClusterForm.tsx │ │ │ │ ├── aws │ │ │ │ │ ├── ConfigureEKSCluster.tsx │ │ │ │ │ ├── CreateEKSClusterForm.tsx │ │ │ │ │ └── GrantAWSPermissions.tsx │ │ │ │ ├── azure │ │ │ │ │ ├── ConfigureAKSCluster.tsx │ │ │ │ │ ├── CreateAKSClusterForm.tsx │ │ │ │ │ └── GrantAzurePermissions.tsx │ │ │ │ └── gcp │ │ │ │ │ ├── ConfigureGKECluster.tsx │ │ │ │ │ ├── CreateGKEClusterForm.tsx │ │ │ │ │ └── GrantGCPPermissions.tsx │ │ │ ├── modals │ │ │ │ ├── PreflightChecksModal.tsx │ │ │ │ ├── cost-consent │ │ │ │ │ ├── AWSCostConsentModalContents.tsx │ │ │ │ │ ├── AzureCostConsentModalContents.tsx │ │ │ │ │ ├── CostConsentModal.tsx │ │ │ │ │ └── GCPCostConsentModalContents.tsx │ │ │ │ └── help │ │ │ │ │ ├── permissions │ │ │ │ │ └── GrantAWSPermissionsHelpModal.tsx │ │ │ │ │ └── preflight │ │ │ │ │ └── ResolutionStepsModalContents.tsx │ │ │ ├── shared │ │ │ │ ├── NodeGroups.tsx │ │ │ │ └── advanced │ │ │ │ │ ├── AdvancedSettings.tsx │ │ │ │ │ └── EKSClusterAdvancedSettings.tsx │ │ │ └── tabs │ │ │ │ ├── AdvancedSettingsTab.tsx │ │ │ │ ├── Settings.tsx │ │ │ │ ├── SystemStatus.tsx │ │ │ │ └── overview │ │ │ │ ├── AKSClusterOverview.tsx │ │ │ │ ├── ClusterOverview.tsx │ │ │ │ ├── EKSClusterOverview.tsx │ │ │ │ └── GKEClusterOverview.tsx │ │ │ ├── integrations │ │ │ ├── DopplerIntegrationList.tsx │ │ │ ├── GitlabIntegrationList.tsx │ │ │ ├── IntegrationCategories.tsx │ │ │ ├── IntegrationList.tsx │ │ │ ├── IntegrationRow.tsx │ │ │ ├── Integrations.tsx │ │ │ ├── SlackIntegrationList.tsx │ │ │ ├── create-integration │ │ │ │ ├── CreateIntegrationForm.tsx │ │ │ │ ├── DockerHubForm.tsx │ │ │ │ ├── ECRForm.tsx │ │ │ │ ├── EKSForm.tsx │ │ │ │ ├── GARForm.tsx │ │ │ │ ├── GCRForm.tsx │ │ │ │ ├── GKEForm.tsx │ │ │ │ └── GitlabForm.tsx │ │ │ └── infisical │ │ │ │ ├── AddInfisicalEnvModal.tsx │ │ │ │ └── InfisicalIntegrationList.tsx │ │ │ ├── launch │ │ │ ├── Launch.tsx │ │ │ ├── LaunchWrapper.tsx │ │ │ ├── TemplateList.tsx │ │ │ ├── expanded-template │ │ │ │ ├── ExpandedTemplate.tsx │ │ │ │ └── TemplateInfo.tsx │ │ │ └── launch-flow │ │ │ │ ├── LaunchFlow.tsx │ │ │ │ ├── SettingsPage.tsx │ │ │ │ ├── SourcePage.tsx │ │ │ │ └── WorkflowPage.tsx │ │ │ ├── managed-addons │ │ │ ├── AddonListRow.tsx │ │ │ ├── AddonsList.tsx │ │ │ └── tabs │ │ │ │ ├── PostgresTabs.tsx │ │ │ │ ├── RedisTabs.tsx │ │ │ │ └── shared.tsx │ │ │ ├── modals │ │ │ ├── AccountSettingsModal.tsx │ │ │ ├── BillingModal.tsx │ │ │ ├── ClusterInstructionsModal.tsx │ │ │ ├── ConnectToDatabaseInstructionsModal.tsx │ │ │ ├── DeleteNamespaceModal.tsx │ │ │ ├── EditInviteOrCollaboratorModal.tsx │ │ │ ├── EnvEditorModal.tsx │ │ │ ├── IntegrationsInstructionsModal.tsx │ │ │ ├── IntegrationsModal.tsx │ │ │ ├── LoadEnvGroupModal.tsx │ │ │ ├── Modal.tsx │ │ │ ├── NamespaceModal.tsx │ │ │ ├── PaymentSetupForm.tsx │ │ │ ├── PreviewEnvSettingsModal.tsx │ │ │ ├── RedirectToOnboardingModal.tsx │ │ │ ├── SkipProvisioningModal.tsx │ │ │ ├── UpdateClusterModal.tsx │ │ │ ├── UpgradeChartModal.tsx │ │ │ └── UsageWarningModal.tsx │ │ │ ├── navbar │ │ │ ├── Help.tsx │ │ │ └── Navbar.tsx │ │ │ ├── new-project │ │ │ ├── NewProject.tsx │ │ │ └── WelcomeForm.tsx │ │ │ ├── onboarding │ │ │ ├── Onboarding.tsx │ │ │ ├── Routes.tsx │ │ │ ├── components │ │ │ │ ├── ProviderSelector.tsx │ │ │ │ └── RegistryImageList.tsx │ │ │ ├── constants.ts │ │ │ ├── state │ │ │ │ ├── StateHandler.ts │ │ │ │ ├── StepHandler.ts │ │ │ │ └── index.ts │ │ │ ├── steps │ │ │ │ ├── ConnectRegistry │ │ │ │ │ ├── ConnectRegistry.tsx │ │ │ │ │ ├── components │ │ │ │ │ │ └── Registry.tsx │ │ │ │ │ └── forms │ │ │ │ │ │ ├── FormFlow.tsx │ │ │ │ │ │ ├── _AWSRegistryForm.tsx │ │ │ │ │ │ └── _GCPRegistryForm.tsx │ │ │ │ ├── ConnectSource.tsx │ │ │ │ └── ProvisionResources │ │ │ │ │ ├── ProvisionResources.tsx │ │ │ │ │ └── forms │ │ │ │ │ ├── FormFlow.tsx │ │ │ │ │ ├── StatusPage.tsx │ │ │ │ │ ├── _AWSProvisionerForm.tsx │ │ │ │ │ ├── _ConnectExternalCluster.tsx │ │ │ │ │ └── _GCPProvisionerForm.tsx │ │ │ └── types.ts │ │ │ ├── project-settings │ │ │ ├── APITokensSection.tsx │ │ │ ├── BillingPage.tsx │ │ │ ├── InviteList.tsx │ │ │ ├── Metadata.tsx │ │ │ ├── PermissionGroup.tsx │ │ │ ├── ProjectDeleteConsent.tsx │ │ │ ├── ProjectSettings.tsx │ │ │ ├── RoleModal.tsx │ │ │ ├── UsagePage.tsx │ │ │ └── api-tokens │ │ │ │ ├── CreateAPITokenForm.tsx │ │ │ │ ├── CustomPolicyForm.tsx │ │ │ │ └── TokenList.tsx │ │ │ ├── provisioner │ │ │ ├── AWSFormSection.tsx │ │ │ ├── AzureFormSection.tsx │ │ │ ├── DOFormSection.tsx │ │ │ ├── ExistingClusterSection.tsx │ │ │ ├── GCPFormSection.tsx │ │ │ └── ProvisionerSettings.tsx │ │ │ └── sidebar │ │ │ ├── AddCluster │ │ │ ├── AWSCredentialForm.tsx │ │ │ ├── AWSCredentialList.tsx │ │ │ └── CredentialList.tsx │ │ │ ├── ClusterList.tsx │ │ │ ├── ClusterListContainer.tsx │ │ │ ├── ClusterSection.tsx │ │ │ ├── Clusters.tsx │ │ │ ├── ProjectButton.tsx │ │ │ ├── ProjectSectionContainer.tsx │ │ │ ├── ProjectSelectionModal.tsx │ │ │ ├── ProvisionClusterModal.tsx │ │ │ ├── Sidebar.tsx │ │ │ └── SidebarLink.tsx │ ├── shared │ │ ├── Context.tsx │ │ ├── DeploymentTargetContext.tsx │ │ ├── ace-porter-theme.js │ │ ├── anayltics │ │ │ ├── index.ts │ │ │ └── onboarding │ │ │ │ ├── events.ts │ │ │ │ ├── tracks.ts │ │ │ │ └── types.ts │ │ ├── api.tsx │ │ ├── auth │ │ │ ├── AuthnContext.tsx │ │ │ ├── AuthorizationHoc.tsx │ │ │ ├── AuthzContext.tsx │ │ │ ├── RouteGuard.tsx │ │ │ ├── authorization-helpers.ts │ │ │ ├── ory.ts │ │ │ ├── types.ts │ │ │ └── useAuth.ts │ │ ├── baseApi.ts │ │ ├── common.tsx │ │ ├── error_handling │ │ │ ├── MainWrapperErrorBoundary.tsx │ │ │ ├── PorterErrorBoundary.tsx │ │ │ ├── logger.ts │ │ │ ├── sentry │ │ │ │ └── setup.ts │ │ │ ├── stack_trace_utils.ts │ │ │ └── window_error_handling.ts │ │ ├── hardcodedNameDict.tsx │ │ ├── hooks │ │ │ ├── useOutsideAlerter.ts │ │ │ └── useWebsockets.ts │ │ ├── icons │ │ │ ├── PullRequest.tsx │ │ │ └── types.ts │ │ ├── images.d.ts │ │ ├── regex.tsx │ │ ├── rosettaStone.tsx │ │ ├── routing.tsx │ │ ├── search.ts │ │ ├── string_utils.ts │ │ ├── themes │ │ │ ├── midnight.ts │ │ │ └── standard.ts │ │ ├── types.tsx │ │ └── util.ts │ ├── test-utils.tsx │ └── utils │ │ └── ip.ts ├── tsconfig.json └── vite.config.ts ├── docker ├── Dockerfile ├── bin │ └── start.sh ├── cli.Dockerfile └── dev.Dockerfile ├── docs ├── deploy │ ├── addons │ │ ├── mongo.md │ │ ├── overview.md │ │ ├── postgres.md │ │ ├── redis.md │ │ └── strapi.md │ └── applications │ │ ├── deploying-django-application-non-docker.md │ │ ├── deploying-from-docker-registry.md │ │ ├── deploying-from-git-repo.md │ │ ├── deploying-from-the-cli.md │ │ └── overview.md ├── developing │ ├── analytics.md │ ├── backend-refactor-status.md │ ├── backend-refactor.md │ ├── forms.md │ ├── frontend-guide.md │ ├── frontend-roadmap-status.md │ ├── frontend-roadmap.md │ ├── setup-gh-app-locally.md │ ├── setup.md │ └── test-autoscaling.md ├── getting-started │ ├── aws.md │ ├── digitalocean.md │ └── gcp.md ├── guides │ ├── advanced-nginx-settings.md │ ├── authorization-and-team-management.md │ ├── connecting-to-cloud-sql.md │ ├── deleting-dangling-resources.md │ ├── https-and-custom-domains.md │ ├── jobs-and-cron-jobs.md │ ├── linking-existing-container-registry.md │ ├── linking-github-account.md │ ├── linking-slack-integration.md │ ├── metrics-visualization.md │ ├── preserving-client-ip-addresses.md │ ├── running-porter-locally.md │ ├── slack-integration.md │ ├── template-versioning-and-upgrades.md │ ├── update-instance-type-eks.md │ └── using-env-groups.md └── reference │ ├── auto-build.md │ └── cli.md ├── ee ├── LICENSE ├── api │ ├── server │ │ └── handlers │ │ │ ├── credentials │ │ │ └── get_credentials.go │ │ │ └── invite │ │ │ ├── accept.go │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── list.go │ │ │ └── update_role.go │ └── types │ │ └── cred_exchange.go ├── docker │ ├── ee.Dockerfile │ └── provisioner.Dockerfile ├── integrations │ ├── httpbackend │ │ ├── backend.go │ │ └── types.go │ └── vault │ │ ├── types.go │ │ └── vault.go ├── migrate │ └── migrate_vault.go ├── models │ ├── project_billing.go │ └── user_billing.go ├── repository │ ├── gorm │ │ ├── project_billing.go │ │ ├── repository.go │ │ └── user_billing.go │ ├── project_billing.go │ ├── repository.go │ └── user_billing.go └── usage │ └── limit.go ├── go.mod ├── go.sum ├── go.work ├── internal ├── adapter │ ├── gorm.go │ └── redis.go ├── analytics │ ├── identifiers.go │ ├── segment.go │ ├── track_events.go │ ├── track_scopes.go │ └── tracks.go ├── auth │ ├── sessionstore │ │ ├── sessionstore.go │ │ └── sessionstore_test.go │ └── token │ │ ├── token.go │ │ └── token_test.go ├── billing │ ├── billing.go │ ├── stripe.go │ └── usage.go ├── compliance │ └── convert.go ├── datastore │ └── datastore.go ├── deployment_target │ └── get.go ├── encryption │ └── encrypt.go ├── features │ └── launch_darkly.go ├── helm │ ├── agent.go │ ├── agent_test.go │ ├── config.go │ ├── grapher │ │ ├── object.go │ │ ├── object_test.go │ │ ├── parser.go │ │ ├── relation.go │ │ ├── relation_test.go │ │ └── test_yaml │ │ │ ├── cassandra.yaml │ │ │ ├── ingress.yaml │ │ │ ├── kafka.yaml │ │ │ └── volumes.yaml │ ├── loader │ │ └── loader.go │ ├── postrenderer.go │ ├── repo │ │ └── repo.go │ ├── storage.go │ ├── storage_test.go │ ├── upgrade │ │ └── upgrade.go │ └── urlcache │ │ └── urlcache.go ├── integrations │ ├── buildpacks │ │ ├── go.go │ │ ├── nodejs.go │ │ ├── python.go │ │ ├── ruby.go │ │ └── shared.go │ ├── ci │ │ ├── actions │ │ │ ├── actions.go │ │ │ ├── preview.go │ │ │ ├── stack.go │ │ │ └── steps.go │ │ └── gitlab │ │ │ └── ci.go │ ├── cloudflare │ │ └── cloudflare.go │ ├── dns │ │ └── dns.go │ ├── powerdns │ │ └── powerdns.go │ ├── preview │ │ ├── dep_resolver.go │ │ ├── driver_validators.go │ │ ├── schema_validate.go │ │ ├── utils.go │ │ └── validate.go │ └── slack │ │ └── slack.go ├── kubernetes │ ├── agent.go │ ├── agent_test.go │ ├── config.go │ ├── domain │ │ └── domain.go │ ├── envgroup │ │ ├── create.go │ │ ├── delete.go │ │ └── get.go │ ├── environment_groups │ │ ├── create.go │ │ ├── delete.go │ │ ├── get.go │ │ ├── list.go │ │ └── sync.go │ ├── errors.go │ ├── fixtures │ │ └── kubeconfig.go │ ├── kubeconfig.go │ ├── kubeconfig_test.go │ ├── local │ │ └── kubeconfig.go │ ├── nodes │ │ ├── helpers.go │ │ └── nodes.go │ ├── porter_agent │ │ ├── logs.go │ │ └── v2 │ │ │ └── agent_server.go │ ├── porter_app │ │ └── create.go │ ├── prometheus │ │ ├── metrics.go │ │ └── metrics_test.go │ ├── resolver │ │ └── resolver.go │ └── utils.go ├── models │ ├── allowlist.go │ ├── api_contract_revision.go │ ├── api_token.go │ ├── app_event_webhook.go │ ├── app_instance.go │ ├── app_revision.go │ ├── app_template.go │ ├── auth_code.go │ ├── aws_assume_role_chain.go │ ├── build_config.go │ ├── cluster.go │ ├── cluster_health_report.go │ ├── cred_exchange_token.go │ ├── database.go │ ├── datastore.go │ ├── db_migration.go │ ├── deployment_target.go │ ├── dns_record.go │ ├── environment.go │ ├── event.go │ ├── github_webhook.go │ ├── gitrepo.go │ ├── helm_repo.go │ ├── infra.go │ ├── integrations │ │ ├── aws.go │ │ ├── azure.go │ │ ├── basic.go │ │ ├── gcp.go │ │ ├── github_app.go │ │ ├── gitlab.go │ │ ├── kube.go │ │ ├── neon.go │ │ ├── oauth.go │ │ ├── oidc.go │ │ ├── slack.go │ │ ├── token_cache.go │ │ └── upstash.go │ ├── invite.go │ ├── ipam.go │ ├── kube_events.go │ ├── monitor.go │ ├── notification.go │ ├── onboarding.go │ ├── policy.go │ ├── porter_app.go │ ├── porter_app_event.go │ ├── project.go │ ├── pw_reset_token.go │ ├── referral.go │ ├── registry.go │ ├── release.go │ ├── role.go │ ├── session.go │ ├── stack.go │ ├── system_service_status.go │ ├── tag.go │ ├── usage.go │ └── user.go ├── nats │ └── nats.go ├── notifier │ ├── deployment_notifier.go │ ├── incident_notifier.go │ ├── sendgrid │ │ ├── client.go │ │ ├── incident_notifier.go │ │ └── user_notifier.go │ ├── slack │ │ ├── deployment_notifier.go │ │ ├── helpers.go │ │ └── incident_notifier.go │ └── user_notifier.go ├── oauth │ └── config.go ├── opa │ ├── config.yaml │ ├── loader.go │ ├── opa.go │ └── policies │ │ ├── cert-manager │ │ ├── cainjector_memory_limits.rego │ │ ├── cert_manager_version.rego │ │ ├── controller_memory_limits.rego │ │ └── webhook_memory_limits.rego │ │ ├── certificates │ │ ├── expired.rego │ │ └── expiry_two_weeks.rego │ │ ├── daemonset │ │ └── running.rego │ │ ├── nginx │ │ ├── memory_limits.rego │ │ ├── nginx_topology_spread_constraints.rego │ │ ├── nginx_version.rego │ │ └── wait_shutdown.rego │ │ ├── node │ │ ├── healthy.rego │ │ ├── k8s_version.rego │ │ ├── porter_run_labels.rego │ │ └── porter_run_taints.rego │ │ ├── pod │ │ └── running.rego │ │ ├── prometheus │ │ ├── alertmanager_memory_limits.rego │ │ ├── kubestatemetrics_memory_limits.rego │ │ ├── nodeexporter_memory_limits.rego │ │ ├── prometheus_version.rego │ │ ├── pushgateway_memory_limits.rego │ │ └── server_memory_limits.rego │ │ └── web │ │ └── web_version.rego ├── porter_app │ ├── create.go │ ├── create_subdomain.go │ ├── environment.go │ ├── github.go │ ├── job_runs.go │ ├── logs.go │ ├── notifications │ │ ├── app_event.go │ │ └── notification.go │ ├── parse.go │ ├── revisions.go │ ├── status.go │ ├── test │ │ ├── parse_test.go │ │ ├── patch_test.go │ │ └── porter_app_to_yaml_test.go │ ├── testdata │ │ ├── app_proto_postpatch.json │ │ ├── app_proto_prepatch.json │ │ ├── v1_input_no_build_no_image.yaml │ │ ├── v2_input_no_build_no_env.yaml │ │ └── v2_input_nobuild.yaml │ ├── v1 │ │ ├── types.go │ │ └── yaml.go │ └── v2 │ │ ├── addons.go │ │ ├── apply_flags.go │ │ ├── env.go │ │ ├── patch.go │ │ └── yaml.go ├── random │ └── string.go ├── registry │ └── registry.go ├── repository │ ├── allowlist.go │ ├── api_contract.go │ ├── api_token.go │ ├── app_event_webhook.go │ ├── app_instance.go │ ├── app_revision.go │ ├── app_template.go │ ├── auth_code.go │ ├── aws_assume_role_chain.go │ ├── build_config.go │ ├── cluster.go │ ├── cred_exchange_token.go │ ├── credentials │ │ └── credentials.go │ ├── database.go │ ├── datastore.go │ ├── deployment_target.go │ ├── dns_record.go │ ├── environment.go │ ├── event.go │ ├── git_action_config.go │ ├── github_webhook.go │ ├── gitrepo.go │ ├── gorm │ │ ├── allowlist.go │ │ ├── allowlist_test.go │ │ ├── api_contract.go │ │ ├── api_token.go │ │ ├── api_token_test.go │ │ ├── app_event_webhook_repository.go │ │ ├── app_instance.go │ │ ├── app_revision.go │ │ ├── app_template.go │ │ ├── auth.go │ │ ├── auth_code.go │ │ ├── auth_test.go │ │ ├── aws_assume_role_chain.go │ │ ├── build_config.go │ │ ├── cluster.go │ │ ├── cluster_test.go │ │ ├── cred_exchange_token.go │ │ ├── database.go │ │ ├── datastore.go │ │ ├── deployment_target.go │ │ ├── dns_record.go │ │ ├── environment.go │ │ ├── event.go │ │ ├── event_test.go │ │ ├── git_action_config.go │ │ ├── git_action_config_test.go │ │ ├── github_webhook.go │ │ ├── gitrepo.go │ │ ├── gitrepo_test.go │ │ ├── helm_repo.go │ │ ├── helm_repo_test.go │ │ ├── helpers │ │ │ ├── helpers.go │ │ │ └── query.go │ │ ├── helpers_test.go │ │ ├── infra.go │ │ ├── infra_test.go │ │ ├── invite.go │ │ ├── invite_test.go │ │ ├── ipam.go │ │ ├── migrate.go │ │ ├── monitor.go │ │ ├── neon.go │ │ ├── notification.go │ │ ├── onboarding.go │ │ ├── policy.go │ │ ├── porter_app.go │ │ ├── porter_app_event.go │ │ ├── project.go │ │ ├── project_test.go │ │ ├── pw_reset_token.go │ │ ├── referrals.go │ │ ├── registry.go │ │ ├── registry_test.go │ │ ├── release.go │ │ ├── release_test.go │ │ ├── repository.go │ │ ├── session.go │ │ ├── slack.go │ │ ├── stack.go │ │ ├── system_service_status.go │ │ ├── tag.go │ │ ├── tag_test.go │ │ ├── upstash.go │ │ ├── usage.go │ │ ├── user.go │ │ └── user_test.go │ ├── helm_repo.go │ ├── infra.go │ ├── integrations.go │ ├── invite.go │ ├── ipam.go │ ├── monitor.go │ ├── neon.go │ ├── notification.go │ ├── onboarding.go │ ├── policy.go │ ├── porter_app.go │ ├── porter_app_event.go │ ├── project.go │ ├── pw_reset_token.go │ ├── referral.go │ ├── registry.go │ ├── release.go │ ├── repository.go │ ├── session.go │ ├── stack.go │ ├── system_service_status.go │ ├── tag.go │ ├── test │ │ ├── allowlist.go │ │ ├── api_contract.go │ │ ├── api_token.go │ │ ├── app_event_webhook.go │ │ ├── app_instance.go │ │ ├── app_revision.go │ │ ├── app_template.go │ │ ├── auth.go │ │ ├── auth_code.go │ │ ├── aws_assume_role_chain.go │ │ ├── build_config.go │ │ ├── cluster.go │ │ ├── cred_exchange_token.go │ │ ├── database.go │ │ ├── datastore.go │ │ ├── deployment_target.go │ │ ├── dns_record.go │ │ ├── environment.go │ │ ├── event.go │ │ ├── git_action_config.go │ │ ├── github_webhook.go │ │ ├── gitrepo.go │ │ ├── helm_repo.go │ │ ├── infra.go │ │ ├── invite.go │ │ ├── monitor.go │ │ ├── neon.go │ │ ├── notification.go │ │ ├── onboarding.go │ │ ├── policy.go │ │ ├── porter_app.go │ │ ├── porter_app_event.go │ │ ├── project.go │ │ ├── pw_reset_token.go │ │ ├── referrral.go │ │ ├── registry.go │ │ ├── release.go │ │ ├── repository.go │ │ ├── session.go │ │ ├── slack.go │ │ ├── stack.go │ │ ├── system_service_status.go │ │ ├── tag.go │ │ ├── upstash.go │ │ ├── usage.go │ │ └── user.go │ ├── upstash.go │ ├── usage.go │ └── user.go ├── stacks │ ├── helpers.go │ └── hooks.go ├── telemetry │ ├── README.md │ ├── baggage.go │ ├── span.go │ └── tracer.go ├── templater │ ├── dynamic │ │ ├── reader.go │ │ └── writer.go │ ├── form.go │ ├── helm │ │ ├── manifests │ │ │ └── reader.go │ │ └── values │ │ │ ├── reader.go │ │ │ └── writer.go │ ├── infra │ │ └── reader.go │ ├── parser │ │ └── parser.go │ └── utils │ │ ├── query.go │ │ └── values.go ├── usage │ ├── limit_ce.go │ ├── limit_ee.go │ └── usage.go ├── validator │ └── validator.go └── worker │ ├── dispatcher.go │ ├── dispatcher_test.go │ ├── worker.go │ └── worker_test.go ├── pkg └── logger │ └── logger.go ├── provisioner ├── client │ ├── apply.go │ ├── client.go │ ├── create_resource.go │ ├── delete.go │ ├── delete_resource.go │ ├── get_logs.go │ ├── get_raw_state.go │ ├── get_state.go │ └── report_error.go ├── integrations │ ├── provisioner │ │ ├── k8s │ │ │ └── k8s_provisioner.go │ │ ├── local │ │ │ └── local_provisioner.go │ │ └── provisioner.go │ ├── redis_stream │ │ ├── global.go │ │ └── operation.go │ └── storage │ │ ├── s3 │ │ └── s3.go │ │ └── storage.go ├── pb │ ├── provisioner.pb.go │ ├── provisioner.proto │ └── provisioner_grpc.pb.go ├── server │ ├── authn │ │ ├── authn.go │ │ └── basic.go │ ├── authz │ │ ├── infra.go │ │ ├── project.go │ │ └── workspace.go │ ├── config │ │ ├── config.go │ │ ├── init_ce.go │ │ └── init_ee.go │ ├── grpc │ │ ├── get_log.go │ │ ├── get_state.go │ │ ├── grpc.go │ │ └── store_log.go │ ├── handlers │ │ ├── credentials │ │ │ ├── get_credentials_ce.go │ │ │ └── get_credentials_ee.go │ │ ├── healthcheck │ │ │ ├── livez.go │ │ │ └── readyz.go │ │ ├── provision │ │ │ ├── apply.go │ │ │ └── destroy.go │ │ └── state │ │ │ ├── create_resource.go │ │ │ ├── delete_resource.go │ │ │ ├── get.go │ │ │ ├── get_logs.go │ │ │ ├── get_raw.go │ │ │ ├── report_error.go │ │ │ └── update_raw.go │ └── router │ │ └── router.go └── types │ ├── provision.go │ ├── raw_state.go │ ├── state.go │ ├── terraform.go │ └── transformers.go ├── scripts ├── build │ ├── generate-spec.sh │ ├── osx.sh │ ├── proto.sh │ └── win.sh └── dev-environment │ ├── CheckPreviewEnvLocal.sh │ ├── CreateDefaultEnvFiles.sh │ ├── RunMigrateDev.sh │ ├── SetupEnvironment.sh │ ├── StartDevServer.sh │ ├── StartProvisionerServer.sh │ └── StartWorkerServer.sh ├── services ├── cli_install_script_container │ ├── Dockerfile │ ├── go.mod │ ├── go.sum │ ├── install.sh │ └── main.go ├── deploy_init_container │ ├── Dockerfile │ ├── assets │ │ ├── init.html │ │ └── porter.png │ ├── default-backend-deployment.yaml │ ├── default-backend-service.yaml │ ├── main.go │ └── start.sh ├── deploy_job_init_container │ ├── Dockerfile │ └── start.sh ├── job_sidecar_container │ ├── Dockerfile │ ├── job_killer.sh │ ├── sidecar_killer.sh │ ├── signal.sh │ └── wait_for_job.sh ├── migrator │ └── Dockerfile ├── porter_cli_container │ ├── Dockerfile │ ├── dev.Dockerfile │ └── get-porter-cli.sh ├── preview_env_setup_job │ ├── Dockerfile │ ├── go.mod │ ├── go.sum │ └── main.go └── usage │ └── usage.go ├── workers ├── Dockerfile ├── doc.go ├── jobs │ ├── helm_revisions_count_tracker.go │ ├── preview_deployments_ttl_deleter.go │ └── recommender.go ├── main.go └── utils │ └── retry_helm_agent.go └── zarf ├── cloudformation-policy.json ├── docker ├── Dockerfile.production └── Dockerfile.server.tilt └── helm ├── .envlocal ├── .serverenv ├── auth.yaml ├── dashboard.yaml ├── kustomization.yaml └── server.yaml /.dockerignore: -------------------------------------------------------------------------------- 1 | /dashboard/node_modules 2 | .env 3 | docker/.env 4 | *.db -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: 🐛 Found a bug? Let us know! 4 | --- 5 | 6 | # Description 7 | 8 | 9 | 10 | # Location 11 | 12 | - [ ] Browser 13 | - [ ] CLI 14 | - [ ] API 15 | 16 | # Steps to reproduce 17 | 18 | 1. 19 | 2. 20 | 3. 21 | 22 | # Additional Details 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/change.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Change 3 | about: 🛠️ Update functionality that already exists. 4 | --- 5 | 6 | # Location 7 | 8 | - [ ] Browser 9 | - [ ] CLI 10 | - [ ] API 11 | 12 | # Motivation 13 | 14 | # Requirements 15 | 16 | # Additional Details 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature 3 | about: ✨ Add new functionality to the project. 4 | --- 5 | 6 | # Location 7 | 8 | - [ ] Browser 9 | - [ ] CLI 10 | - [ ] API 11 | 12 | # Requirements 13 | 14 | # Additional Details 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## POR- 2 | 3 | ## What does this PR do? 4 | 5 | 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: gomod 5 | directory: "/" 6 | schedule: 7 | interval: daily 8 | open-pull-requests-limit: 2 9 | -------------------------------------------------------------------------------- /.github/workflows/app_tests_internal_tools.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_run: 3 | workflows: ["Deploy Porter to Internal Tooling"] 4 | branches: [master] 5 | types: 6 | - completed 7 | 8 | name: Run internal tools app tests 9 | jobs: 10 | call-base-workflow: 11 | uses: ./.github/workflows/app_tests_base.yml 12 | with: 13 | stage: internal-tools 14 | project: "301" 15 | cluster: "142" 16 | host: https://dashboard.internal-tools.porter.run 17 | secrets: 18 | token: ${{ secrets.APP_INTEGRATION_PROJECT_TOKEN }} 19 | slack_webhook_url: ${{ secrets.APP_INTEGRATION_SLACK_WEBHOOK }} -------------------------------------------------------------------------------- /.github/workflows/app_tests_production.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_run: 3 | workflows: ["Deploy Porter to Production"] 4 | branches: [master] 5 | types: 6 | - completed 7 | 8 | name: Run production app tests 9 | jobs: 10 | call-base-workflow: 11 | uses: ./.github/workflows/app_tests_base.yml 12 | with: 13 | stage: production 14 | project: "11646" 15 | cluster: "3618" 16 | host: https://dashboard.getporter.dev 17 | secrets: 18 | token: ${{ secrets.APP_TESTS_PRODUCTION_TOKEN }} 19 | slack_webhook_url: ${{ secrets.APP_INTEGRATION_SLACK_WEBHOOK }} -------------------------------------------------------------------------------- /.github/workflows/app_tests_sandbox.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_run: 3 | workflows: ['Deploy to porter-sandbox'] 4 | branches: [master] 5 | types: 6 | - completed 7 | 8 | name: Run sandbox app tests 9 | jobs: 10 | call-base-workflow: 11 | uses: ./.github/workflows/app_tests_base.yml 12 | with: 13 | stage: sandbox 14 | project: '242' 15 | cluster: '240' 16 | host: https://cloud.porter.run 17 | secrets: 18 | token: ${{ secrets.APP_TESTS_SANDBOX_TOKEN }} 19 | slack_webhook_url: ${{ secrets.APP_INTEGRATION_SLACK_WEBHOOK }} 20 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules -------------------------------------------------------------------------------- /api/client/base.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | 6 | sharedConfig "github.com/porter-dev/porter/api/server/shared/config" 7 | ) 8 | 9 | func (c *Client) GetPorterInstanceMetadata(ctx context.Context) (*sharedConfig.Metadata, error) { 10 | resp := &sharedConfig.Metadata{} 11 | 12 | err := c.getRequest( 13 | "/metadata", 14 | nil, 15 | resp, 16 | ) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | return resp, nil 22 | } 23 | -------------------------------------------------------------------------------- /api/client/domain.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/porter-dev/porter/api/types" 8 | ) 9 | 10 | // CreateDNSRecord creates a Github action with basic authentication 11 | func (c *Client) CreateDNSRecord( 12 | ctx context.Context, 13 | projID, clusterID uint, 14 | namespace, name string, 15 | ) (*types.DNSRecord, error) { 16 | resp := &types.DNSRecord{} 17 | 18 | err := c.postRequest( 19 | fmt.Sprintf( 20 | "/projects/%d/clusters/%d/namespaces/%s/releases/%s/subdomain", 21 | projID, clusterID, 22 | namespace, name, 23 | ), 24 | nil, 25 | resp, 26 | ) 27 | 28 | return resp, err 29 | } 30 | -------------------------------------------------------------------------------- /api/client/event.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/porter-dev/porter/api/types" 8 | ) 9 | 10 | // CreateEvent sends an event from deployment to the api 11 | func (c *Client) CreateEvent( 12 | ctx context.Context, 13 | projID, clusterID uint, 14 | namespace, name string, 15 | req *types.UpdateReleaseStepsRequest, 16 | ) error { 17 | return c.postRequest( 18 | fmt.Sprintf( 19 | "/projects/%d/clusters/%d/namespaces/%s/releases/%s/steps", 20 | projID, clusterID, 21 | namespace, name, 22 | ), 23 | req, 24 | nil, 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /api/client/release.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/porter-dev/porter/api/types" 8 | "github.com/stefanmcshane/helm/pkg/release" 9 | ) 10 | 11 | func (c *Client) ListReleases( 12 | ctx context.Context, 13 | projectID, clusterID uint, 14 | namespace string, 15 | req *types.ListReleasesRequest, 16 | ) ([]*release.Release, error) { 17 | resp := make([]*release.Release, 0) 18 | 19 | err := c.getRequest( 20 | fmt.Sprintf( 21 | "/projects/%d/clusters/%d/namespaces/%s/releases", 22 | projectID, clusterID, 23 | namespace, 24 | ), 25 | req, 26 | &resp, 27 | ) 28 | 29 | return resp, err 30 | } 31 | -------------------------------------------------------------------------------- /api/server/authz/policy/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package policy provides methods for parsing RBAC policies to determine if a user 3 | has access to a given resource. 4 | 5 | TODO: more details about policy trees + "MostRestrictiveParent" + "LeastRestrictiveSibling" 6 | 7 | Caveats: 8 | - one policy document to match the entire action 9 | - list/create are not resource-specific actions, so granting list/create permissions for a scope 10 | means that a user can list all resources or create a new resource in that scope. 11 | */ 12 | package policy 13 | -------------------------------------------------------------------------------- /api/server/handlers/credentials/get_credentials_ee.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package credentials 5 | 6 | import ( 7 | "net/http" 8 | 9 | "github.com/porter-dev/porter/api/server/shared" 10 | "github.com/porter-dev/porter/api/server/shared/config" 11 | "github.com/porter-dev/porter/ee/api/server/handlers/credentials" 12 | ) 13 | 14 | var NewGetCredentialsHandler func( 15 | config *config.Config, 16 | decoderValidator shared.RequestDecoderValidator, 17 | writer shared.ResultWriter, 18 | ) http.Handler 19 | 20 | func init() { 21 | NewGetCredentialsHandler = credentials.NewCredentialsGetHandler 22 | } 23 | -------------------------------------------------------------------------------- /api/server/router/middleware/content_type_json.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import "net/http" 4 | 5 | // ContentTypeJSON sets the content type for requests to application/json 6 | func ContentTypeJSON(next http.Handler) http.Handler { 7 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 8 | w.Header().Set("Content-Type", "application/json;charset=utf8") 9 | next.ServeHTTP(w, r) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /api/server/shared/apierrors/alerter/alerter.go: -------------------------------------------------------------------------------- 1 | package alerter 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type Alerter interface { 8 | SendAlert(ctx context.Context, err error, data map[string]interface{}) *string 9 | } 10 | -------------------------------------------------------------------------------- /api/server/shared/apierrors/alerter/noop.go: -------------------------------------------------------------------------------- 1 | package alerter 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type NoOpAlerter struct{} 8 | 9 | func (s NoOpAlerter) SendAlert(ctx context.Context, err error, data map[string]interface{}) *string { 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /api/server/shared/config/loader/init_ce.go: -------------------------------------------------------------------------------- 1 | //go:build !ee 2 | // +build !ee 3 | 4 | package loader 5 | 6 | func init() { 7 | sharedInit() 8 | } 9 | -------------------------------------------------------------------------------- /api/server/shared/router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/go-chi/chi/v5" 7 | "github.com/porter-dev/porter/api/server/shared" 8 | "github.com/porter-dev/porter/api/server/shared/config" 9 | "github.com/porter-dev/porter/api/types" 10 | ) 11 | 12 | type Route struct { 13 | Endpoint *shared.APIEndpoint 14 | Handler http.Handler 15 | Router chi.Router 16 | } 17 | 18 | type Registerer struct { 19 | GetRoutes func( 20 | r chi.Router, 21 | config *config.Config, 22 | basePath *types.Path, 23 | factory shared.APIEndpointFactory, 24 | children ...*Registerer, 25 | ) []*Route 26 | 27 | Children []*Registerer 28 | } 29 | -------------------------------------------------------------------------------- /api/types/agent.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type DetectAgentResponse struct { 4 | Version string `json:"version"` 5 | LatestVersion string `json:"latest_version"` 6 | ShouldUpgrade bool `json:"should_upgrade"` 7 | Image string `json:"image"` 8 | } 9 | 10 | type GetAgentStatusResponse struct { 11 | Loki string `json:"loki"` 12 | } 13 | -------------------------------------------------------------------------------- /api/types/billing_stripe.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // PaymentMethod is a subset of the Stripe PaymentMethod type, 4 | // with only the fields used in the dashboard 5 | type PaymentMethod struct { 6 | ID string `json:"id"` 7 | DisplayBrand string `json:"display_brand"` 8 | Last4 string `json:"last4"` 9 | ExpMonth int64 `json:"exp_month"` 10 | ExpYear int64 `json:"exp_year"` 11 | Default bool `json:"is_default"` 12 | } 13 | -------------------------------------------------------------------------------- /api/types/cluster_integration.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type AWSSubnet struct { 4 | SubnetID string `json:"subnet_id"` 5 | AvailabilityZone string `json:"availability_zone"` 6 | AvailableIPAddressCount int64 `json:"available_ip_address_count"` 7 | } 8 | 9 | type GetAWSClusterInfoResponse struct { 10 | Name string `json:"name"` 11 | ARN string `json:"arn"` 12 | K8sVersion string `json:"kubernetes_server_version"` 13 | EKSVersion string `json:"eks_version"` 14 | Status string `json:"status"` 15 | Subnets []*AWSSubnet `json:"subnets"` 16 | } 17 | -------------------------------------------------------------------------------- /api/types/crd.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type DeleteCRDRequest struct { 4 | Name string `schema:"name" form:"required"` 5 | Namespace string `schema:"namespace" form:"required"` 6 | Group string `schema:"group" form:"required"` 7 | Version string `schema:"version" form:"required"` 8 | Resource string `schema:"resource" form:"required"` 9 | } 10 | 11 | type StreamCRDRequest struct { 12 | Namespace string `json:"namespace"` 13 | Group string `json:"group" form:"required"` 14 | Version string `json:"version" form:"required"` 15 | Resource string `json:"resource" form:"required"` 16 | } 17 | -------------------------------------------------------------------------------- /api/types/error.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | const ( 4 | ErrCodeUnavailable uint = 601 5 | ) 6 | 7 | type ExternalError struct { 8 | // Optional error code for well-known error types 9 | Code uint `json:"code,omitempty"` 10 | 11 | Error string `json:"error"` 12 | } 13 | -------------------------------------------------------------------------------- /api/types/helm_release.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type StreamHelmReleaseRequest struct { 4 | Selectors string `schema:"selectors"` 5 | Charts []string `schema:"charts"` 6 | Namespace string `schema:"namespace"` 7 | } 8 | -------------------------------------------------------------------------------- /api/types/helm_repo.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type HelmRepo struct { 4 | ID uint `json:"id"` 5 | 6 | // The project that this integration belongs to 7 | ProjectID uint `json:"project_id"` 8 | 9 | // Name of the repo 10 | Name string `json:"name"` 11 | 12 | RepoURL string `json:"repo_name"` 13 | } 14 | 15 | type GetHelmRepoResponse HelmRepo 16 | 17 | type CreateUpdateHelmRepoRequest struct { 18 | URL string `json:"url" form:"required"` 19 | Name string `json:"name" form:"required"` 20 | BasicIntegrationID uint `json:"basic_integration_id"` 21 | } 22 | -------------------------------------------------------------------------------- /api/types/jobs.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import v1 "k8s.io/api/batch/v1" 4 | 5 | const ( 6 | URLParamJobName URLParam = "name" 7 | ) 8 | 9 | type GetJobsResponse []v1.Job 10 | -------------------------------------------------------------------------------- /api/types/provision.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type CreateRDSInfraRequest struct { 4 | // version of the postgres engine 5 | DBEngineVersion string `json:"db_engine_version"` 6 | 7 | // db type - postgres / mysql 8 | DBFamily string `json:"db_family"` 9 | 10 | // db instance credentials specifications 11 | DBName string `json:"db_name"` 12 | Username string `json:"username"` 13 | Password string `json:"password"` 14 | 15 | MachineType string `json:"machine_type"` 16 | DBStorage string `json:"db_allocated_storage"` 17 | DBMaxStorage string `json:"db_max_allocated_storage"` 18 | DBEncryption bool `json:"db_storage_encrypted"` 19 | } 20 | -------------------------------------------------------------------------------- /api/types/referral.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // Referral is a struct that represents a referral in the Porter API 4 | type Referral struct { 5 | ID uint `json:"id"` 6 | // Code is the referral code that is shared with the referred user 7 | Code string `json:"referral_code"` 8 | // ReferredUserID is the ID of the user who was referred 9 | ReferredUserID uint `json:"referred_user_id"` 10 | // Status is the status of the referral (pending, signed_up, etc.) 11 | Status string `json:"status"` 12 | } 13 | -------------------------------------------------------------------------------- /api/types/role.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type RoleKind string 4 | 5 | const ( 6 | RoleAdmin RoleKind = "admin" 7 | RoleDeveloper RoleKind = "developer" 8 | RoleViewer RoleKind = "viewer" 9 | RoleCustom RoleKind = "custom" 10 | ) 11 | 12 | type Role struct { 13 | Kind RoleKind `json:"kind"` 14 | UserID uint `json:"user_id"` 15 | ProjectID uint `json:"project_id"` 16 | } 17 | -------------------------------------------------------------------------------- /api/types/status.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | const ( 4 | URLParamKind URLParam = "kind" 5 | ) 6 | 7 | type StreamStatusRequest struct { 8 | Selectors string `schema:"selectors"` 9 | } 10 | 11 | type GithubUnresolvedIncidents struct { 12 | Incidents []*struct { 13 | ID string `json:"id"` 14 | } `json:"incidents"` 15 | } 16 | -------------------------------------------------------------------------------- /api/types/tag.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type CreateTagRequest struct { 4 | Name string `json:"name" form:"required"` 5 | Color string `json:"color" form:"required"` 6 | } 7 | -------------------------------------------------------------------------------- /api/utils/porter_app/namespace.go: -------------------------------------------------------------------------------- 1 | package porter_app 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func NamespaceFromPorterAppName(porterAppName string) string { 9 | return fmt.Sprintf("porter-stack-%s", porterAppName) 10 | } 11 | 12 | func PorterAppNameFromNamespace(namespace string) string { 13 | return strings.TrimPrefix(namespace, "porter-stack-") 14 | } 15 | 16 | func PredeployJobNameFromPorterAppName(porterAppName string) string { 17 | return fmt.Sprintf("%s-r", porterAppName) 18 | } 19 | -------------------------------------------------------------------------------- /build/Dockerfile.osx: -------------------------------------------------------------------------------- 1 | ARG GO_VERSION=1.18 2 | 3 | FROM golang:${GO_VERSION} 4 | 5 | RUN apt-get update && apt-get install -y zip unzip 6 | 7 | WORKDIR /go/src/github.com/docker/cli 8 | COPY . . 9 | 10 | ENV GOOS darwin 11 | ENV GOARCH amd64 12 | 13 | RUN chmod +x ./scripts/build/osx.sh 14 | 15 | ENTRYPOINT [ "./scripts/build/osx.sh" ] -------------------------------------------------------------------------------- /build/Dockerfile.win: -------------------------------------------------------------------------------- 1 | ARG GO_VERSION=1.18 2 | 3 | FROM golang:${GO_VERSION} 4 | 5 | RUN apt-get update && apt-get install -y zip unzip 6 | 7 | WORKDIR /go/src/github.com/docker/cli 8 | COPY . . 9 | 10 | ENV GOOS windows 11 | ENV GOARCH amd64 12 | 13 | RUN chmod +x ./scripts/build/win.sh 14 | 15 | ENTRYPOINT [ "./scripts/build/win.sh" ] -------------------------------------------------------------------------------- /cli/cmd/commands/version.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/porter-dev/porter/cli/cmd/config" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | func registerCommand_Version(_ config.CLIConfig) *cobra.Command { 11 | versionCmd := &cobra.Command{ 12 | Use: "version", 13 | Aliases: []string{"v", "--version"}, 14 | Short: "Prints the version of the Porter CLI", 15 | Run: func(cmd *cobra.Command, args []string) { 16 | fmt.Println(config.Version) 17 | }, 18 | } 19 | return versionCmd 20 | } 21 | -------------------------------------------------------------------------------- /cli/cmd/config/version.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "strings" 4 | 5 | // Version will be linked by an ldflag during build 6 | var Version string = "v0.21.2" 7 | 8 | type VersionWriter struct { 9 | Version string 10 | } 11 | 12 | func (v *VersionWriter) Write(p []byte) (n int, err error) { 13 | v.Version = strings.TrimSpace(string(p)) 14 | 15 | return len(p), nil 16 | } 17 | -------------------------------------------------------------------------------- /cli/cmd/docker/agent_test.go: -------------------------------------------------------------------------------- 1 | package docker_test 2 | 3 | // import ( 4 | // "testing" 5 | 6 | // "github.com/porter-dev/porter/cli/cmd/docker" 7 | // ) 8 | 9 | // func TestGetServerURL(t *testing.T) { 10 | // res, err := docker.GetServerURLFromTag("docker.io/testing/test") 11 | 12 | // if err != nil { 13 | // t.Fatalf("%v", err) 14 | // } 15 | 16 | // t.Errorf("%s", res) 17 | // } 18 | -------------------------------------------------------------------------------- /cli/cmd/porter_app/env.go: -------------------------------------------------------------------------------- 1 | package porter_app 2 | 3 | func CopyEnv(env map[string]string) map[string]string { 4 | envCopy := make(map[string]string) 5 | if env == nil { 6 | return envCopy 7 | } 8 | 9 | for k, v := range env { 10 | if k == "" || v == "" { 11 | continue 12 | } 13 | envCopy[k] = v 14 | } 15 | 16 | return envCopy 17 | } 18 | -------------------------------------------------------------------------------- /cli/cmd/porter_app/utils.go: -------------------------------------------------------------------------------- 1 | package porter_app 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type MessageLevel string 8 | 9 | const ( 10 | Warning MessageLevel = "WARN" 11 | Error MessageLevel = "ERR" 12 | Success MessageLevel = "OK" 13 | Info MessageLevel = "INFO" 14 | ) 15 | 16 | func composePreviewMessage(msg string, level MessageLevel) string { 17 | return fmt.Sprintf("[porter.yaml stack][%s] -- %s", level, msg) 18 | } 19 | -------------------------------------------------------------------------------- /cli/cmd/preview/v2beta1/helm_chart.go: -------------------------------------------------------------------------------- 1 | package v2beta1 2 | 3 | func (c *HelmChart) GetName() string { 4 | if c == nil || c.Name == nil { 5 | return "" 6 | } 7 | 8 | return *c.Name 9 | } 10 | 11 | func (c *HelmChart) GetURL() string { 12 | if c == nil || c.URL == nil { 13 | return "" 14 | } 15 | 16 | return *c.URL 17 | } 18 | 19 | func (c *HelmChart) GetVersion() string { 20 | if c == nil || c.Version == nil { 21 | return "" 22 | } 23 | 24 | return *c.Version 25 | } 26 | -------------------------------------------------------------------------------- /cli/cmd/utils/close.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "os/signal" 6 | "syscall" 7 | 8 | "github.com/fatih/color" 9 | ) 10 | 11 | func closeHandler(closer func() error) { 12 | sig := make(chan os.Signal, 1) 13 | signal.Notify(sig, os.Interrupt, syscall.SIGTERM) 14 | go func() { 15 | <-sig 16 | err := closer() 17 | 18 | if err == nil { 19 | color.New(color.FgRed).Println("shutdown successful") 20 | os.Exit(0) 21 | } 22 | 23 | color.New(color.FgRed).Fprintf(os.Stderr, "shutdown unsuccessful: %s\n", err.Error()) 24 | os.Exit(1) 25 | }() 26 | } 27 | -------------------------------------------------------------------------------- /cli/cmd/utils/flags.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import flag "github.com/spf13/pflag" 4 | 5 | // shared sets of flags used by multiple commands 6 | var ( 7 | DriverFlagSet = flag.NewFlagSet("driver", flag.ExitOnError) 8 | DefaultFlagSet = flag.NewFlagSet("shared", flag.ExitOnError) // used by all commands 9 | RegistryFlagSet = flag.NewFlagSet("registry", flag.ExitOnError) 10 | HelmRepoFlagSet = flag.NewFlagSet("helmrepo", flag.ExitOnError) 11 | ) 12 | -------------------------------------------------------------------------------- /cli/cmd/utils/sanitize.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // SlugifyRepoSuffix return a sanitized repository name based on a Git repo owner and name. 9 | func SlugifyRepoSuffix(repoOwner, repoName string) string { 10 | initialSuffix := fmt.Sprintf("%s-%s", repoOwner, repoName) 11 | sanitizedSuffix := strings.ReplaceAll(strings.ReplaceAll(initialSuffix, "_", "-"), ".", "-") 12 | return strings.ToLower(sanitizedSuffix) 13 | } 14 | -------------------------------------------------------------------------------- /cli/cmd/v2/bluegreen.go: -------------------------------------------------------------------------------- 1 | package v2 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | // BlueGreenSwitch implements the functionality of the `porter deply blue-green-switch` command for validate apply v2 projects 9 | func BlueGreenSwitch(ctx context.Context) error { 10 | fmt.Println("This command is not supported for your project. Contact support@porter.run for more information.") 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /cli/cmd/v2/create.go: -------------------------------------------------------------------------------- 1 | package v2 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | // CreateFull implements the functionality of the `porter create` command for validate apply v2 projects 9 | func CreateFull(ctx context.Context) error { 10 | fmt.Println("This command is not supported for your project. Contact support@porter.run for more information.") 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /cli/cmd/v2/deployment_target.go: -------------------------------------------------------------------------------- 1 | package v2 2 | -------------------------------------------------------------------------------- /cli/cmd/v2/get.go: -------------------------------------------------------------------------------- 1 | package v2 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | // Get implements the functionality of the `porter get` command for validate apply v2 projects 9 | func Get(ctx context.Context) error { 10 | fmt.Println("This command is not supported for your project. Contact support@porter.run for more information.") 11 | return nil 12 | } 13 | 14 | // GetValues implements the functionality of the `porter get values` command for validate apply v2 projects 15 | func GetValues(ctx context.Context) error { 16 | fmt.Println("This command is not supported for your project. Contact support@porter.run for more information.") 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /cmd/migrate/migrate_ce.go: -------------------------------------------------------------------------------- 1 | //go:build !ee 2 | // +build !ee 3 | 4 | package main 5 | 6 | import ( 7 | "github.com/porter-dev/porter/api/server/shared/config/env" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | func InstanceMigrate(db *gorm.DB, dbConf *env.DBConf) error { 12 | return nil 13 | } 14 | -------------------------------------------------------------------------------- /cmd/migrate/startup_migrations/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | === Mandatory Migrations at Startup === 3 | 4 | This package contains the migrations that are run at startup. Such migrations are 5 | mandatory by nature, especially for self-hosted customers. 6 | 7 | A globally accessible map structure shall be maintained and updated with the respective 8 | migration scripts (functions) attached with the migration version they should be run with. 9 | */ 10 | 11 | package startup_migrations 12 | -------------------------------------------------------------------------------- /dashboard/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /dashboard/.eslintignore: -------------------------------------------------------------------------------- 1 | src/legacy/ -------------------------------------------------------------------------------- /dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | .env 3 | 4 | # dependencies 5 | /node_modules 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /dashboard/.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | cd dashboard && npm run lint-staged 5 | -------------------------------------------------------------------------------- /dashboard/.npmrc: -------------------------------------------------------------------------------- 1 | porter-dev:registry=https://npm.pkg.github.com 2 | -------------------------------------------------------------------------------- /dashboard/.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore artifacts: 2 | build 3 | coverage 4 | src/legacy/ -------------------------------------------------------------------------------- /dashboard/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "lodash", 4 | "babel-plugin-styled-components", 5 | "@babel/plugin-syntax-dynamic-import" 6 | ], 7 | "presets": [ 8 | "@babel/preset-env", 9 | "@babel/preset-react", 10 | "@babel/preset-typescript" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /dashboard/decs.d.ts: -------------------------------------------------------------------------------- 1 | declare module "js-yaml"; 2 | -------------------------------------------------------------------------------- /dashboard/docker/dev.Dockerfile: -------------------------------------------------------------------------------- 1 | # Development environment 2 | # ----------------------- 3 | FROM node:lts 4 | WORKDIR /webpack 5 | 6 | COPY package*.json ./ 7 | 8 | ENV NODE_ENV=development 9 | 10 | RUN npm ci --legacy-peer-deps 11 | RUN npm i -g http-parser-js 12 | 13 | COPY . ./ 14 | 15 | CMD npm start 16 | -------------------------------------------------------------------------------- /dashboard/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | testEnvironment: "jsdom", 4 | moduleNameMapper: { 5 | "^.+\\.(jpg|jpeg|png|gif|webp|svg)$": "/src/__mocks__/fileMock.js", 6 | "^shared/(.*)$": "/src/shared/$1", 7 | "^components/(.*)$": "/src/components/$1", 8 | "^assets/(.*)$": "/src/assets/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /dashboard/src/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = ""; 2 | -------------------------------------------------------------------------------- /dashboard/src/assets/Light Gradient 08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/Light Gradient 08.png -------------------------------------------------------------------------------- /dashboard/src/assets/add-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/add-circle.png -------------------------------------------------------------------------------- /dashboard/src/assets/add-on-grad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dashboard/src/assets/add-ons-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/add-ons-bold.png -------------------------------------------------------------------------------- /dashboard/src/assets/add-ons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/add-ons.png -------------------------------------------------------------------------------- /dashboard/src/assets/add-ons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/alert-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/alert-triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/alert-warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/alert_square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/amazon-rds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/amazon-rds.png -------------------------------------------------------------------------------- /dashboard/src/assets/app_event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/app_event.png -------------------------------------------------------------------------------- /dashboard/src/assets/applications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/applications.png -------------------------------------------------------------------------------- /dashboard/src/assets/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/arrow-left-square-contained.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/aws-elasticache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/aws-elasticache.png -------------------------------------------------------------------------------- /dashboard/src/assets/aws-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/aws-normal.png -------------------------------------------------------------------------------- /dashboard/src/assets/aws-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/aws-white.png -------------------------------------------------------------------------------- /dashboard/src/assets/aws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/aws.png -------------------------------------------------------------------------------- /dashboard/src/assets/azure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/azure.png -------------------------------------------------------------------------------- /dashboard/src/assets/back_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/back_arrow.png -------------------------------------------------------------------------------- /dashboard/src/assets/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/blog.png -------------------------------------------------------------------------------- /dashboard/src/assets/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/box.png -------------------------------------------------------------------------------- /dashboard/src/assets/branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/branch.png -------------------------------------------------------------------------------- /dashboard/src/assets/build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/build.png -------------------------------------------------------------------------------- /dashboard/src/assets/calendar-02.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/calendar-number.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dashboard/src/assets/canceled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/check.png -------------------------------------------------------------------------------- /dashboard/src/assets/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/close-rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/close-rounded.png -------------------------------------------------------------------------------- /dashboard/src/assets/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/close.png -------------------------------------------------------------------------------- /dashboard/src/assets/close_rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/close_rounded.png -------------------------------------------------------------------------------- /dashboard/src/assets/cloud-formation-stack-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/cloud-formation-stack-complete.png -------------------------------------------------------------------------------- /dashboard/src/assets/collapse-sidebar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/community.png -------------------------------------------------------------------------------- /dashboard/src/assets/compliance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/compliance.png -------------------------------------------------------------------------------- /dashboard/src/assets/compliance.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/copy-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/credit-card.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/creds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/creds.png -------------------------------------------------------------------------------- /dashboard/src/assets/database.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/deploy.png -------------------------------------------------------------------------------- /dashboard/src/assets/do.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/do.png -------------------------------------------------------------------------------- /dashboard/src/assets/docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/docs.png -------------------------------------------------------------------------------- /dashboard/src/assets/doppler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/doppler.png -------------------------------------------------------------------------------- /dashboard/src/assets/down-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/assets/drawer-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/drawer-bg.png -------------------------------------------------------------------------------- /dashboard/src/assets/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/expand.png -------------------------------------------------------------------------------- /dashboard/src/assets/external-link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/eye-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/failure.png -------------------------------------------------------------------------------- /dashboard/src/assets/failure.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/file-diff.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/filter-outline-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/filter-outline-new.png -------------------------------------------------------------------------------- /dashboard/src/assets/filter-outline-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/filter-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/filter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/folder_v2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/gcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/gcp.png -------------------------------------------------------------------------------- /dashboard/src/assets/gear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/git-compare.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/github-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/github-icon.png -------------------------------------------------------------------------------- /dashboard/src/assets/github-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/github-white.png -------------------------------------------------------------------------------- /dashboard/src/assets/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/github.png -------------------------------------------------------------------------------- /dashboard/src/assets/globe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/gradient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/gradient.jpg -------------------------------------------------------------------------------- /dashboard/src/assets/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/gradient.png -------------------------------------------------------------------------------- /dashboard/src/assets/green-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/grid.png -------------------------------------------------------------------------------- /dashboard/src/assets/hash-02.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/history.png -------------------------------------------------------------------------------- /dashboard/src/assets/information-circle-contained.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/infra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/infra.png -------------------------------------------------------------------------------- /dashboard/src/assets/integrations-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/integrations-bold.png -------------------------------------------------------------------------------- /dashboard/src/assets/integrations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/integrations.png -------------------------------------------------------------------------------- /dashboard/src/assets/job-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/job-bold.png -------------------------------------------------------------------------------- /dashboard/src/assets/job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/job.png -------------------------------------------------------------------------------- /dashboard/src/assets/last-run.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/assets/left-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/assets/lightning-square-contained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/lightning-square-contained.png -------------------------------------------------------------------------------- /dashboard/src/assets/lightning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/lightning.png -------------------------------------------------------------------------------- /dashboard/src/assets/lightning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dashboard/src/assets/link-external.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/list.png -------------------------------------------------------------------------------- /dashboard/src/assets/loading-dots.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/loading-dots.gif -------------------------------------------------------------------------------- /dashboard/src/assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/loading.gif -------------------------------------------------------------------------------- /dashboard/src/assets/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/logo.png -------------------------------------------------------------------------------- /dashboard/src/assets/monojob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/monojob.png -------------------------------------------------------------------------------- /dashboard/src/assets/monoweb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/monoweb.png -------------------------------------------------------------------------------- /dashboard/src/assets/node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/node.png -------------------------------------------------------------------------------- /dashboard/src/assets/not-applicable.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/not-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/not-found.png -------------------------------------------------------------------------------- /dashboard/src/assets/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/pencil.png -------------------------------------------------------------------------------- /dashboard/src/assets/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/placeholder.png -------------------------------------------------------------------------------- /dashboard/src/assets/plus-square.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/pre_deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/pre_deploy.png -------------------------------------------------------------------------------- /dashboard/src/assets/provider.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/quivr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/quivr.png -------------------------------------------------------------------------------- /dashboard/src/assets/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/refresh.png -------------------------------------------------------------------------------- /dashboard/src/assets/rocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/rocket.png -------------------------------------------------------------------------------- /dashboard/src/assets/run_for.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/run_for.png -------------------------------------------------------------------------------- /dashboard/src/assets/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/search.png -------------------------------------------------------------------------------- /dashboard/src/assets/seed.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/assets/settings-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/settings-bold.png -------------------------------------------------------------------------------- /dashboard/src/assets/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/settings.png -------------------------------------------------------------------------------- /dashboard/src/assets/shield.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/sidebar-highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/sidebar-highlight.png -------------------------------------------------------------------------------- /dashboard/src/assets/sort.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dashboard/src/assets/stars-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/assets/stars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/assets/status-healthy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/status-healthy.png -------------------------------------------------------------------------------- /dashboard/src/assets/swap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dashboard/src/assets/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/tag.png -------------------------------------------------------------------------------- /dashboard/src/assets/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dashboard/src/assets/target.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/time.png -------------------------------------------------------------------------------- /dashboard/src/assets/time.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/assets/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/trash.png -------------------------------------------------------------------------------- /dashboard/src/assets/type.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/user-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/user-icon.png -------------------------------------------------------------------------------- /dashboard/src/assets/vector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/warning.png -------------------------------------------------------------------------------- /dashboard/src/assets/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/assets/web-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/web-bold.png -------------------------------------------------------------------------------- /dashboard/src/assets/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/web.png -------------------------------------------------------------------------------- /dashboard/src/assets/worker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/assets/worker.png -------------------------------------------------------------------------------- /dashboard/src/components/Description.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | const Description = styled.div<{ margin?: string }>` 4 | width: 100%; 5 | color: white; 6 | font-size: 13px; 7 | color: #aaaabb; 8 | margin: ${(props) => props.margin || "20px 0 10px 0"}; 9 | display: flex; 10 | align-items: center; 11 | `; 12 | 13 | export default Description; 14 | -------------------------------------------------------------------------------- /dashboard/src/components/form-components/Helper.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Helper = styled.div<{ color?: string }>` 4 | color: ${({ color }) => color || "#aaaabb"}; 5 | line-height: 1.6em; 6 | font-size: 13px; 7 | margin-bottom: 20px; 8 | margin-top: 20px; 9 | `; 10 | 11 | export default Helper; 12 | -------------------------------------------------------------------------------- /dashboard/src/components/porter/CollapsibleContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { type ReactNode } from "react"; 2 | import { Collapse } from "react-collapse"; 3 | 4 | import "./collapsible-container.css"; 5 | 6 | type Props = { 7 | isOpened: boolean; 8 | children: ReactNode; 9 | }; 10 | 11 | const CollapsibleContainer: React.FC = ({ isOpened, children }) => { 12 | return {children}; 13 | }; 14 | 15 | export default CollapsibleContainer; 16 | -------------------------------------------------------------------------------- /dashboard/src/components/porter/collapsible-container.css: -------------------------------------------------------------------------------- 1 | .ReactCollapse--collapse { 2 | transition: height 500ms; 3 | } 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = ""; 2 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/Light Gradient 08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/Light Gradient 08.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/add-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/add-circle.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/add-on-grad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/add-ons-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/add-ons-bold.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/add-ons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/add-ons.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/add-ons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/alert-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/alert-triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/alert-warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/alert_square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/amazon-rds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/amazon-rds.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/app_event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/app_event.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/applications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/applications.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/arrow-left-square-contained.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/aws-elasticache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/aws-elasticache.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/aws-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/aws-normal.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/aws-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/aws-white.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/aws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/aws.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/azure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/azure.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/back_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/back_arrow.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/blog.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/box.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/branch.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/build.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/calendar-02.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/calendar-number.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/canceled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/check.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/close-rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/close-rounded.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/close.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/close_rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/close_rounded.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/cloud-formation-stack-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/cloud-formation-stack-complete.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/collapse-sidebar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/community.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/compliance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/compliance.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/compliance.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/copy-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/credit-card.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/creds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/creds.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/database.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/deploy.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/do.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/do.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/docs.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/doppler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/doppler.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/down-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/drawer-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/drawer-bg.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/expand.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/external-link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/eye-off.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/failure.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/failure.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/file-diff.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/filter-outline-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/filter-outline-new.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/filter-outline-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/filter-outline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/filter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/folder_v2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/gcp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/gcp.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/gear.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/git-compare.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/github-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/github-icon.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/github-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/github-white.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/github.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/globe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/gradient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/gradient.jpg -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/gradient.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/green-check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/grid.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/hash-02.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/history.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/information-circle-contained.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/infra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/infra.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/integrations-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/integrations-bold.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/integrations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/integrations.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/job-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/job-bold.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/job.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/last-run.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/left-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/lightning-square-contained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/lightning-square-contained.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/lightning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/lightning.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/lightning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/link-external.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/list.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/loading-dots.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/loading-dots.gif -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/loading.gif -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/logo.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/monojob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/monojob.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/monoweb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/monoweb.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/node.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/not-applicable.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/not-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/not-found.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/pencil.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/placeholder.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/plus-square.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/pre_deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/pre_deploy.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/provider.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/quivr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/quivr.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/refresh.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/rocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/rocket.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/run_for.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/run_for.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/search.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/seed.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/settings-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/settings-bold.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/settings.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/shield.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/sidebar-highlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/sidebar-highlight.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/sort.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/stars-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/stars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/status-healthy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/status-healthy.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/swap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/tag.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/target.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/time.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/time.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/trash.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/type.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/user-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/user-icon.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/vector.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/warning.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/web-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/web-bold.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/web.png -------------------------------------------------------------------------------- /dashboard/src/legacy/assets/worker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/dashboard/src/legacy/assets/worker.png -------------------------------------------------------------------------------- /dashboard/src/legacy/components/Description.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | const Description = styled.div<{ margin?: string }>` 4 | width: 100%; 5 | color: white; 6 | font-size: 13px; 7 | color: #aaaabb; 8 | margin: ${(props) => props.margin || "20px 0 10px 0"}; 9 | display: flex; 10 | align-items: center; 11 | `; 12 | 13 | export default Description; 14 | -------------------------------------------------------------------------------- /dashboard/src/legacy/components/form-components/Helper.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | 4 | export const Helper = styled.div<{ color?: string }>` 5 | color: ${({ color }) => (color ? color : "#aaaabb")}; 6 | line-height: 1.6em; 7 | font-size: 13px; 8 | margin-bottom: 20px; 9 | margin-top: 20px; 10 | `; 11 | 12 | export default Helper; 13 | -------------------------------------------------------------------------------- /dashboard/src/legacy/components/porter/CollapsibleContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { type ReactNode } from "react"; 2 | import { Collapse } from "react-collapse"; 3 | 4 | import "./collapsible-container.css"; 5 | 6 | type Props = { 7 | isOpened: boolean; 8 | children: ReactNode; 9 | }; 10 | 11 | const CollapsibleContainer: React.FC = ({ isOpened, children }) => { 12 | return {children}; 13 | }; 14 | 15 | export default CollapsibleContainer; 16 | -------------------------------------------------------------------------------- /dashboard/src/legacy/components/porter/collapsible-container.css: -------------------------------------------------------------------------------- 1 | .ReactCollapse--collapse { 2 | transition: height 500ms; 3 | } -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/addons/datadog.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const datadogConfigValidator = z.object({ 4 | type: z.literal("datadog"), 5 | cpuCores: z.number().default(0.5), 6 | ramMegabytes: z.number().default(512), 7 | site: z.string().nonempty().default("datadoghq.com"), 8 | apiKey: z.string().nonempty().default("*******"), 9 | loggingEnabled: z.boolean().default(false), 10 | apmEnabled: z.boolean().default(false), 11 | dogstatsdEnabled: z.boolean().default(false), 12 | }); 13 | export type DatadogConfigValidator = z.infer; 14 | -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/addons/mezmo.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const mezmoConfigValidator = z.object({ 4 | type: z.literal("mezmo"), 5 | ingestionKey: z.string().nonempty().default("*******"), 6 | }); 7 | export type MezmoConfigValidator = z.infer; 8 | -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/addons/tailscale.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const subnetRouteValidator = z.object({ 4 | route: z.string(), 5 | }); 6 | export const tailscaleConfigValidator = z.object({ 7 | type: z.literal("tailscale"), 8 | authKey: z.string().nonempty().default("*******"), 9 | subnetRoutes: z.array(subnetRouteValidator).default([]), 10 | }); 11 | export type TailscaleConfigValidator = z.infer; 12 | -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/environments/types.ts: -------------------------------------------------------------------------------- 1 | import { clientAddonValidator } from "legacy/lib/addons"; 2 | import { clientAppValidator } from "legacy/lib/porter-apps"; 3 | import { z } from "zod"; 4 | 5 | const environmentValidator = z.object({ 6 | name: z.string(), 7 | apps: z.array(clientAppValidator), 8 | addons: z.array(clientAddonValidator), 9 | }); 10 | 11 | export type Environment = z.infer; 12 | -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/neon/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const neonIntegrationValidator = z.object({ 4 | created_at: z.string(), 5 | }); 6 | export type ClientNeonIntegration = z.infer; 7 | -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/porter-apps/error.ts: -------------------------------------------------------------------------------- 1 | const ERROR_CODE_UPDATE_FAILED = 90; 2 | export const ERROR_CODE_APPLICATION_ROLLBACK = 91; 3 | export const ERROR_CODE_APPLICATION_ROLLBACK_FAILED = 92; 4 | 5 | export const ERROR_CODE_TO_SUMMARY: Record = { 6 | [ERROR_CODE_UPDATE_FAILED]: "The latest version failed to deploy", 7 | [ERROR_CODE_APPLICATION_ROLLBACK]: 8 | "A version deployment failure triggered an auto-rollback", 9 | [ERROR_CODE_APPLICATION_ROLLBACK_FAILED]: 10 | "Porter attempted a rollback, but the new deployment failed", 11 | }; 12 | -------------------------------------------------------------------------------- /dashboard/src/legacy/lib/upstash/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const upstashIntegrationValidator = z.object({ 4 | created_at: z.string(), 5 | }); 6 | export type ClientUpstashIntegration = z.infer< 7 | typeof upstashIntegrationValidator 8 | >; 9 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/app-dashboard/app-view/tabs/Activity.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { useLatestRevision } from "../LatestRevisionContext"; 4 | import ActivityFeed from "./activity-feed/ActivityFeed"; 5 | 6 | const Activity: React.FC = () => { 7 | const { projectId, clusterId, latestProto, deploymentTarget } = 8 | useLatestRevision(); 9 | 10 | return ( 11 | 17 | ); 18 | }; 19 | 20 | export default Activity; 21 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/app-dashboard/image-settings/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const artifactValidator = z.object({ 4 | tag: z.string(), 5 | updated_at: z.string(), 6 | }) 7 | export type ArtifactType = z.infer; 8 | 9 | export const imageValidator = z.object({ 10 | uri: z.string(), 11 | artifacts: z.array(artifactValidator), 12 | }) 13 | export type ImageType = z.infer; -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/cluster-dashboard/expanded-chart/incidents/DisabledNamespaces.ts: -------------------------------------------------------------------------------- 1 | export const DisabledNamespacesForIncidents = [ 2 | "cert-manager", 3 | "ingress-nginx", 4 | "kube-node-lease", 5 | "kube-public", 6 | "kube-system", 7 | "monitoring", 8 | "porter-agent-system", 9 | ]; 10 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/cluster-dashboard/expanded-chart/metrics/utils.ts: -------------------------------------------------------------------------------- 1 | export const AggregatedDataColors: Record = { 2 | min: "#4C4F6B", 3 | avg: "#F2C94C", 4 | max: "#B04649", 5 | }; 6 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/cluster-dashboard/expanded-chart/status/types.ts: -------------------------------------------------------------------------------- 1 | export type SelectedPodType = { 2 | spec: { 3 | [key: string]: any; 4 | containers: { 5 | [key: string]: any; 6 | name: string; 7 | }[]; 8 | }; 9 | metadata: { 10 | name: string; 11 | namespace: string; 12 | labels: { 13 | [key: string]: string; 14 | }; 15 | }; 16 | status: { 17 | phase: string; 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/cluster-dashboard/preview-environments/errors.ts: -------------------------------------------------------------------------------- 1 | export enum PorterYAMLErrors { 2 | FileNotFound = "porter.yaml does not exist in the root of this repository", 3 | } 4 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/compliance-dashboard/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const checkGroupValidator = z.object({ 4 | name: z.string(), 5 | status: z.enum(["PASSED", "FAILED"]), 6 | message: z.string().optional().default(""), 7 | }); 8 | export type CheckGroup = z.infer; 9 | 10 | export const vendorCheckValidator = z.object({ 11 | check: z.string(), 12 | check_group: z.string(), 13 | status: z.enum(["passed", "failing", "not_applicable"]), 14 | reason: z.string(), 15 | vendor_check_id: z.string(), 16 | }); 17 | export type VendorCheck = z.infer; 18 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/launch/LaunchWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import styled from "styled-components"; 3 | 4 | import { Context } from "shared/Context"; 5 | 6 | import Launch from "./Launch"; 7 | 8 | type Props = {}; 9 | 10 | const LaunchWrapper: React.FC = (props) => { 11 | const { capabilities } = useContext(Context); 12 | return <>{capabilities && }; 13 | }; 14 | 15 | export default LaunchWrapper; 16 | 17 | const StyledLaunchWrapper = styled.div``; 18 | -------------------------------------------------------------------------------- /dashboard/src/legacy/main/home/sidebar/ClusterListContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | 3 | import { Context } from "shared/Context"; 4 | 5 | import ClusterList from "./ClusterList"; 6 | 7 | const ClusterListContainer = (): JSX.Element => { 8 | const context = useContext(Context); 9 | 10 | return ( 11 | 15 | ); 16 | }; 17 | 18 | export default ClusterListContainer; 19 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/anayltics/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./onboarding/tracks"; 2 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/array_utils.ts: -------------------------------------------------------------------------------- 1 | export function onlyInLeft( 2 | left: Array, 3 | right: Array, 4 | compareFunction: (leftValue: T, rightValue: T) => boolean 5 | ): Array { 6 | return left.filter( 7 | (leftValue) => 8 | !right.some((rightValue) => compareFunction(leftValue, rightValue)) 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/error_handling/stack_trace_utils.ts: -------------------------------------------------------------------------------- 1 | import { StackFrame } from "stacktrace-js"; 2 | 3 | export const stackFramesToString = (stackFrames: StackFrame[]) => { 4 | return stackFrames 5 | .map(function (sf) { 6 | return sf.toString(); 7 | }) 8 | .join("\n"); 9 | }; 10 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/hooks/usePrevious.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export const usePrevious = (value: any, initialValue: any) => { 4 | const ref = useRef(initialValue); 5 | useEffect(() => { 6 | ref.current = value; 7 | }); 8 | return ref.current; 9 | }; 10 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/icons/types.ts: -------------------------------------------------------------------------------- 1 | export type IconProps = { 2 | className?: string; 3 | styles?: React.CSSProperties; 4 | fill?: string; 5 | }; 6 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.gif" { 2 | const value: any; 3 | export = value; 4 | } 5 | 6 | declare module "*.jpg" { 7 | const value: any; 8 | export = value; 9 | } 10 | 11 | declare module "*.png" { 12 | const value: any; 13 | export = value; 14 | } 15 | 16 | declare module "*.svg" { 17 | const value: any; 18 | export = value; 19 | } 20 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/release/utils.ts: -------------------------------------------------------------------------------- 1 | import { ChartTypeWithExtendedConfig } from "legacy/shared/types"; 2 | 3 | export const isDeployedFromGithub = (release: ChartTypeWithExtendedConfig) => { 4 | const githubRepository = release?.git_action_config?.git_repo; 5 | 6 | return !!githubRepository?.length; 7 | }; 8 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/search.ts: -------------------------------------------------------------------------------- 1 | import Fuse from "fuse.js"; 2 | 3 | export const search = ( 4 | items: T[], 5 | searchTerm: string, 6 | options?: Fuse.IFuseOptions 7 | ) => { 8 | if (!searchTerm) { 9 | return items; 10 | } 11 | 12 | const fuse = new Fuse(items, options); 13 | return fuse.search(searchTerm).map((result) => result.item); 14 | }; 15 | -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/themes/midnight.ts: -------------------------------------------------------------------------------- 1 | const theme = { 2 | bg: "#121212", 3 | fg: "#171B21", 4 | fg2: "#1E232B", 5 | border: "#494b4f", 6 | button: "#3A48CA", 7 | clickable: { 8 | bg: "linear-gradient(180deg, #171B21, #121212)", 9 | clickedBg: "#202126", 10 | }, 11 | modalBg: "#171B2111", 12 | text: { 13 | primary: "#DFDFE1", 14 | }, 15 | } 16 | 17 | export default theme; -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/themes/opal.ts: -------------------------------------------------------------------------------- 1 | const theme = { 2 | bg: "#f3f5f8", 3 | fg: "#ffffff", 4 | fg2: "#ffffff11", 5 | border: "#bbbbcc", 6 | border2: "#9999aa", 7 | button: "#3A48CA", 8 | clickable: { 9 | bg: "linear-gradient(180deg, #ffffff, #f3f5f8)", 10 | }, 11 | modalBg: "#171B2111", 12 | text: { 13 | primary: "#414142", 14 | helper: "#aaaabb", 15 | }, 16 | } 17 | 18 | export default theme; -------------------------------------------------------------------------------- /dashboard/src/legacy/shared/themes/standard.ts: -------------------------------------------------------------------------------- 1 | const theme = { 2 | bg: "#202227", 3 | fg: "#27292e", 4 | fg2: "#2e3036", 5 | button: "#5561C0", 6 | clickable: { 7 | bg: "linear-gradient(180deg, #26292e, #24272c)", 8 | }, 9 | text: { 10 | primary: "#fefefe", 11 | secondary: "#9999aa", 12 | }, 13 | } 14 | 15 | export default theme; -------------------------------------------------------------------------------- /dashboard/src/lib/addons/datadog.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const datadogConfigValidator = z.object({ 4 | type: z.literal("datadog"), 5 | cpuCores: z.number().default(0.5), 6 | ramMegabytes: z.number().default(512), 7 | site: z.string().nonempty().default("datadoghq.com"), 8 | apiKey: z.string().nonempty().default("*******"), 9 | loggingEnabled: z.boolean().default(false), 10 | apmEnabled: z.boolean().default(false), 11 | dogstatsdEnabled: z.boolean().default(false), 12 | }); 13 | export type DatadogConfigValidator = z.infer; 14 | -------------------------------------------------------------------------------- /dashboard/src/lib/addons/mezmo.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const mezmoConfigValidator = z.object({ 4 | type: z.literal("mezmo"), 5 | ingestionKey: z.string().nonempty().default("*******"), 6 | }); 7 | export type MezmoConfigValidator = z.infer; 8 | -------------------------------------------------------------------------------- /dashboard/src/lib/addons/tailscale.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const subnetRouteValidator = z.object({ 4 | route: z.string(), 5 | }); 6 | export const tailscaleConfigValidator = z.object({ 7 | type: z.literal("tailscale"), 8 | authKey: z.string().nonempty().default("*******"), 9 | subnetRoutes: z.array(subnetRouteValidator).default([]), 10 | }); 11 | export type TailscaleConfigValidator = z.infer; 12 | -------------------------------------------------------------------------------- /dashboard/src/lib/environments/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | import { clientAddonValidator } from "lib/addons"; 4 | import { clientAppValidator } from "lib/porter-apps"; 5 | 6 | const environmentValidator = z.object({ 7 | name: z.string(), 8 | apps: z.array(clientAppValidator), 9 | addons: z.array(clientAddonValidator), 10 | }); 11 | 12 | export type Environment = z.infer; 13 | -------------------------------------------------------------------------------- /dashboard/src/lib/neon/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const neonIntegrationValidator = z.object({ 4 | created_at: z.string(), 5 | }); 6 | export type ClientNeonIntegration = z.infer; 7 | -------------------------------------------------------------------------------- /dashboard/src/lib/porter-apps/error.ts: -------------------------------------------------------------------------------- 1 | const ERROR_CODE_UPDATE_FAILED = 90; 2 | export const ERROR_CODE_APPLICATION_ROLLBACK = 91; 3 | export const ERROR_CODE_APPLICATION_ROLLBACK_FAILED = 92; 4 | 5 | export const ERROR_CODE_TO_SUMMARY: Record = { 6 | [ERROR_CODE_UPDATE_FAILED]: "The latest version failed to deploy", 7 | [ERROR_CODE_APPLICATION_ROLLBACK]: 8 | "A version deployment failure triggered an auto-rollback", 9 | [ERROR_CODE_APPLICATION_ROLLBACK_FAILED]: 10 | "Porter attempted a rollback, but the new deployment failed", 11 | }; 12 | -------------------------------------------------------------------------------- /dashboard/src/lib/upstash/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const upstashIntegrationValidator = z.object({ 4 | created_at: z.string(), 5 | }); 6 | export type ClientUpstashIntegration = z.infer< 7 | typeof upstashIntegrationValidator 8 | >; 9 | -------------------------------------------------------------------------------- /dashboard/src/main/home/app-dashboard/app-view/tabs/Activity.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { useLatestRevision } from "../LatestRevisionContext"; 4 | import ActivityFeed from "./activity-feed/ActivityFeed"; 5 | 6 | const Activity: React.FC = () => { 7 | const { projectId, clusterId, latestProto, deploymentTarget } = 8 | useLatestRevision(); 9 | 10 | return ( 11 | 17 | ); 18 | }; 19 | 20 | export default Activity; 21 | -------------------------------------------------------------------------------- /dashboard/src/main/home/app-dashboard/image-settings/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | const artifactValidator = z.object({ 4 | tag: z.string(), 5 | updated_at: z.string(), 6 | }); 7 | export type ArtifactType = z.infer; 8 | 9 | export const imageValidator = z.object({ 10 | uri: z.string(), 11 | artifacts: z.array(artifactValidator), 12 | }); 13 | export type ImageType = z.infer; 14 | -------------------------------------------------------------------------------- /dashboard/src/main/home/cluster-dashboard/expanded-chart/metrics/utils.ts: -------------------------------------------------------------------------------- 1 | export const AggregatedDataColors: Record = { 2 | min: "#4C4F6B", 3 | avg: "#F2C94C", 4 | max: "#B04649", 5 | }; 6 | -------------------------------------------------------------------------------- /dashboard/src/main/home/compliance-dashboard/types.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const checkGroupValidator = z.object({ 4 | name: z.string(), 5 | status: z.enum(["PASSED", "FAILED"]), 6 | message: z.string().optional().default(""), 7 | }); 8 | export type CheckGroup = z.infer; 9 | 10 | export const vendorCheckValidator = z.object({ 11 | check: z.string(), 12 | check_group: z.string(), 13 | status: z.enum(["passed", "failing", "not_applicable"]), 14 | reason: z.string(), 15 | vendor_check_id: z.string(), 16 | }); 17 | export type VendorCheck = z.infer; 18 | -------------------------------------------------------------------------------- /dashboard/src/main/home/launch/LaunchWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import styled from "styled-components"; 3 | 4 | import { Context } from "shared/Context"; 5 | 6 | import Launch from "./Launch"; 7 | 8 | type Props = {}; 9 | 10 | const LaunchWrapper: React.FC = (props) => { 11 | const { capabilities } = useContext(Context); 12 | return <>{capabilities && }; 13 | }; 14 | 15 | export default LaunchWrapper; 16 | 17 | const StyledLaunchWrapper = styled.div``; 18 | -------------------------------------------------------------------------------- /dashboard/src/main/home/sidebar/ClusterListContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | 3 | import { Context } from "shared/Context"; 4 | 5 | import ClusterList from "./ClusterList"; 6 | 7 | const ClusterListContainer = (): JSX.Element => { 8 | const context = useContext(Context); 9 | 10 | return ( 11 | 15 | ); 16 | }; 17 | 18 | export default ClusterListContainer; 19 | -------------------------------------------------------------------------------- /dashboard/src/shared/anayltics/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./onboarding/tracks"; 2 | -------------------------------------------------------------------------------- /dashboard/src/shared/auth/useAuth.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useContext } from "react"; 2 | 3 | import { isAuthorized } from "./authorization-helpers"; 4 | import { AuthzContext } from "./AuthzContext"; 5 | import { type ScopeType, type Verbs } from "./types"; 6 | 7 | const useAuth = () => { 8 | const authContext = useContext(AuthzContext); 9 | 10 | const isAuth = useCallback( 11 | (scope: ScopeType, resource: string | string[], verb: Verbs | Verbs[]) => 12 | isAuthorized(authContext.currentPolicy, scope, resource, verb), 13 | [authContext.currentPolicy] 14 | ); 15 | 16 | return [isAuth]; 17 | }; 18 | 19 | export default useAuth; 20 | -------------------------------------------------------------------------------- /dashboard/src/shared/error_handling/stack_trace_utils.ts: -------------------------------------------------------------------------------- 1 | import { type StackFrame } from "stacktrace-js"; 2 | 3 | export const stackFramesToString = (stackFrames: StackFrame[]) => { 4 | return stackFrames 5 | .map(function (sf) { 6 | return sf.toString(); 7 | }) 8 | .join("\n"); 9 | }; 10 | -------------------------------------------------------------------------------- /dashboard/src/shared/icons/types.ts: -------------------------------------------------------------------------------- 1 | export type IconProps = { 2 | className?: string; 3 | styles?: React.CSSProperties; 4 | fill?: string; 5 | }; 6 | -------------------------------------------------------------------------------- /dashboard/src/shared/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.gif" { 2 | const value: any; 3 | export = value; 4 | } 5 | 6 | declare module "*.jpg" { 7 | const value: any; 8 | export = value; 9 | } 10 | 11 | declare module "*.png" { 12 | const value: any; 13 | export = value; 14 | } 15 | 16 | declare module "*.svg" { 17 | const value: any; 18 | export = value; 19 | } 20 | -------------------------------------------------------------------------------- /dashboard/src/shared/regex.tsx: -------------------------------------------------------------------------------- 1 | export const emailRegex = 2 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 3 | -------------------------------------------------------------------------------- /dashboard/src/shared/search.ts: -------------------------------------------------------------------------------- 1 | import Fuse from "fuse.js"; 2 | 3 | export const search = ( 4 | items: T[], 5 | searchTerm: string, 6 | options?: Fuse.IFuseOptions 7 | ) => { 8 | if (!searchTerm) { 9 | return items; 10 | } 11 | 12 | const fuse = new Fuse(items, options); 13 | return fuse.search(searchTerm).map((result) => result.item); 14 | }; 15 | -------------------------------------------------------------------------------- /dashboard/src/shared/themes/midnight.ts: -------------------------------------------------------------------------------- 1 | const theme = { 2 | bg: "#121212", 3 | fg: "#171B21", 4 | fg2: "#1E232B", 5 | border: "#494b4f", 6 | button: "#3A48CA", 7 | clickable: { 8 | bg: "linear-gradient(180deg, #171B21, #121212)", 9 | clickedBg: "#202126", 10 | }, 11 | modalBg: "#171B2111", 12 | text: { 13 | primary: "#DFDFE1", 14 | }, 15 | }; 16 | 17 | export default theme; 18 | -------------------------------------------------------------------------------- /dashboard/src/shared/themes/standard.ts: -------------------------------------------------------------------------------- 1 | const theme = { 2 | bg: "#202227", 3 | fg: "#27292e", 4 | fg2: "#2e3036", 5 | button: "#5561C0", 6 | clickable: { 7 | bg: "linear-gradient(180deg, #26292e, #24272c)", 8 | }, 9 | text: { 10 | primary: "#fefefe", 11 | secondary: "#9999aa", 12 | }, 13 | }; 14 | 15 | export default theme; 16 | -------------------------------------------------------------------------------- /dashboard/src/utils/ip.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const isIP = (value: string): boolean => { 4 | const ip = z.string().ip(); 5 | 6 | const parsed = ip.safeParse(value); 7 | 8 | return parsed.success; 9 | }; 10 | 11 | export const stringifiedDNSRecordType = (value: string): string => { 12 | if (isIP(value)) { 13 | return "an A record"; 14 | } else { 15 | return "a CNAME record"; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /docker/bin/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo 'Running migrations...' 3 | # /porter/bin/migrate 4 | 5 | echo 'Starting application...' 6 | /porter/bin/app 7 | -------------------------------------------------------------------------------- /docker/dev.Dockerfile: -------------------------------------------------------------------------------- 1 | # Development environment 2 | # ----------------------- 3 | # pinned because of https://github.com/moby/moby/issues/45935 4 | FROM golang:1.20.5-alpine 5 | WORKDIR /porter 6 | 7 | RUN apk update && apk add --no-cache gcc musl-dev git 8 | 9 | # for live reloading of go container 10 | RUN go install github.com/cosmtrek/air@latest 11 | 12 | COPY go.mod go.sum ./ 13 | RUN go mod download 14 | 15 | COPY . ./ 16 | 17 | RUN chmod +x /porter/docker/bin/* 18 | 19 | CMD air -c .air.toml 20 | -------------------------------------------------------------------------------- /docs/deploy/addons/overview.md: -------------------------------------------------------------------------------- 1 | For deployments that do not fall into the three application types (i.e. web service, worker, and cron job), you can deploy them as add-ons on Porter. Below is the list of add-ons that are currently supported. 2 | 3 | If you have requests for add-ons you'd like us to support, please let us know in the #suggestions channel of our [community](https://discord.gg/mmGAw5nNjr). 4 | 5 | - [PostgresDB](doc:postgresdb) 6 | - [Redis](doc:redis) 7 | - [MongoDB](doc:mongodb) -------------------------------------------------------------------------------- /ee/api/types/cred_exchange.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "github.com/porter-dev/porter/internal/repository/credentials" 4 | 5 | type CredentialsExchangeRequest struct { 6 | CredExchangeID uint 7 | CredExchangeToken string 8 | 9 | // (optional) Vault token, if required 10 | VaultToken string 11 | } 12 | 13 | type CredentialsExchangeResponse struct { 14 | DO *credentials.OAuthCredential `json:"do,omitempty"` 15 | GCP *credentials.GCPCredential `json:"gcp,omitempty"` 16 | AWS *credentials.AWSCredential `json:"aws,omitempty"` 17 | Azure *credentials.AzureCredential `json:"azure,omitempty"` 18 | } 19 | -------------------------------------------------------------------------------- /ee/models/project_billing.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package models 5 | 6 | import "gorm.io/gorm" 7 | 8 | // ProjectBilling stores a billing data per project 9 | type ProjectBilling struct { 10 | *gorm.Model 11 | 12 | ProjectID uint 13 | BillingTeamID string 14 | } 15 | -------------------------------------------------------------------------------- /ee/models/user_billing.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package models 5 | 6 | import "gorm.io/gorm" 7 | 8 | // UserBilling stores a billing token per user in a project 9 | type UserBilling struct { 10 | *gorm.Model 11 | 12 | ProjectID uint 13 | UserID uint 14 | TeammateID string 15 | Token []byte 16 | } 17 | -------------------------------------------------------------------------------- /ee/repository/project_billing.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package repository 5 | 6 | import "github.com/porter-dev/porter/ee/models" 7 | 8 | type ProjectBillingRepository interface { 9 | CreateProjectBilling(userBilling *models.ProjectBilling) (*models.ProjectBilling, error) 10 | ReadProjectBillingByProjectID(projectID uint) (*models.ProjectBilling, error) 11 | ReadProjectBillingByTeamID(teamID string) (*models.ProjectBilling, error) 12 | } 13 | -------------------------------------------------------------------------------- /ee/repository/repository.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package repository 5 | 6 | type EERepository interface { 7 | UserBilling() UserBillingRepository 8 | ProjectBilling() ProjectBillingRepository 9 | } 10 | -------------------------------------------------------------------------------- /ee/repository/user_billing.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package repository 5 | 6 | import "github.com/porter-dev/porter/ee/models" 7 | 8 | type UserBillingRepository interface { 9 | CreateUserBilling(userBilling *models.UserBilling) (*models.UserBilling, error) 10 | ReadUserBilling(projectID, userID uint) (*models.UserBilling, error) 11 | UpdateUserBilling(userBilling *models.UserBilling) (*models.UserBilling, error) 12 | } 13 | -------------------------------------------------------------------------------- /go.work: -------------------------------------------------------------------------------- 1 | go 1.20 2 | 3 | use ( 4 | . 5 | ./services/cli_install_script_container 6 | ./services/preview_env_setup_job 7 | ) 8 | -------------------------------------------------------------------------------- /internal/adapter/redis.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | redis "github.com/go-redis/redis/v8" 8 | "github.com/porter-dev/porter/api/server/shared/config/env" 9 | ) 10 | 11 | // NewRedisClient returns a new redis client instance 12 | func NewRedisClient(conf *env.RedisConf) (*redis.Client, error) { 13 | client := redis.NewClient(&redis.Options{ 14 | Addr: fmt.Sprintf("%s:%s", conf.Host, conf.Port), 15 | Username: conf.Username, 16 | Password: conf.Password, 17 | DB: conf.DB, 18 | }) 19 | 20 | _, err := client.Ping(context.Background()).Result() 21 | return client, err 22 | } 23 | -------------------------------------------------------------------------------- /internal/billing/billing.go: -------------------------------------------------------------------------------- 1 | package billing 2 | 3 | // Manager contains methods for managing billing for a project 4 | type Manager struct { 5 | StripeClient StripeClient 6 | StripeConfigLoaded bool 7 | LagoClient LagoClient 8 | LagoConfigLoaded bool 9 | } 10 | -------------------------------------------------------------------------------- /internal/kubernetes/envgroup/delete.go: -------------------------------------------------------------------------------- 1 | package envgroup 2 | 3 | import "github.com/porter-dev/porter/internal/kubernetes" 4 | 5 | func DeleteEnvGroup(agent *kubernetes.Agent, name, namespace string) error { 6 | if err := agent.DeleteVersionedSecret(name, namespace); err != nil { 7 | return err 8 | } 9 | 10 | if err := agent.DeleteVersionedConfigMap(name, namespace); err != nil { 11 | return err 12 | } 13 | 14 | return nil 15 | } 16 | -------------------------------------------------------------------------------- /internal/kubernetes/porter_app/create.go: -------------------------------------------------------------------------------- 1 | package porter_app 2 | 3 | // TODO: migrate all kubernetes-level operations from /api/server/handlers/porter_app/{create,parse}.go to this file 4 | 5 | const ( 6 | LabelKey_PorterApplication = "porter.run/porter-application" 7 | LabelKey_PorterApplicationPreDeploy = "porter.run/porter-application-pre-deploy" 8 | LabelValue_PorterApplication = "true" 9 | ) 10 | -------------------------------------------------------------------------------- /internal/models/allowlist.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "gorm.io/gorm" 5 | ) 6 | 7 | // Allowlist is a simple list with all the users emails allowed to create new projects 8 | type Allowlist struct { 9 | gorm.Model 10 | 11 | UserEmail string `json:"user_email" gorm:"unique;not null"` 12 | } 13 | -------------------------------------------------------------------------------- /internal/models/auth_code.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | 6 | "gorm.io/gorm" 7 | ) 8 | 9 | // AuthCode type that extends gorm.Model 10 | type AuthCode struct { 11 | gorm.Model 12 | 13 | Token string `gorm:"unique"` 14 | AuthorizationCode string `gorm:"unique"` 15 | Expiry *time.Time 16 | } 17 | 18 | func (a *AuthCode) IsExpired() bool { 19 | timeLeft := a.Expiry.Sub(time.Now()) 20 | return timeLeft < 0 21 | } 22 | -------------------------------------------------------------------------------- /internal/models/build_config.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/porter-dev/porter/api/types" 7 | "gorm.io/gorm" 8 | ) 9 | 10 | type BuildConfig struct { 11 | gorm.Model 12 | 13 | Name string `json:"name"` 14 | Builder string `json:"builder"` 15 | Buildpacks string `json:"buildpacks"` 16 | Config []byte `json:"config"` 17 | } 18 | 19 | func (conf *BuildConfig) ToBuildConfigType() *types.BuildConfig { 20 | return &types.BuildConfig{ 21 | Builder: conf.Builder, 22 | Buildpacks: strings.Split(conf.Buildpacks, ","), 23 | Config: conf.Config, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /internal/models/cred_exchange_token.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | 6 | "gorm.io/gorm" 7 | ) 8 | 9 | type CredentialsExchangeToken struct { 10 | gorm.Model 11 | 12 | ProjectID uint 13 | Token []byte 14 | Expiry *time.Time 15 | 16 | DOCredentialID uint 17 | AWSCredentialID uint 18 | GCPCredentialID uint 19 | AzureCredentialID uint 20 | } 21 | 22 | func (t *CredentialsExchangeToken) IsExpired() bool { 23 | timeLeft := t.Expiry.Sub(time.Now()) 24 | return timeLeft < 0 25 | } 26 | -------------------------------------------------------------------------------- /internal/models/db_migration.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import "gorm.io/gorm" 4 | 5 | type DbMigration struct { 6 | gorm.Model 7 | 8 | Version uint 9 | } 10 | -------------------------------------------------------------------------------- /internal/models/integrations/neon.go: -------------------------------------------------------------------------------- 1 | package integrations 2 | 3 | import "gorm.io/gorm" 4 | 5 | // NeonIntegration is an integration for the Neon service 6 | type NeonIntegration struct { 7 | gorm.Model 8 | 9 | ProjectID uint `json:"project_id"` 10 | 11 | SharedOAuthModel 12 | } 13 | -------------------------------------------------------------------------------- /internal/models/integrations/upstash.go: -------------------------------------------------------------------------------- 1 | package integrations 2 | 3 | import "gorm.io/gorm" 4 | 5 | // UpstashIntegration is an integration for the Upstash service 6 | type UpstashIntegration struct { 7 | gorm.Model 8 | 9 | ProjectID uint `json:"project_id"` 10 | 11 | SharedOAuthModel 12 | 13 | DeveloperApiKey []byte `json:"developer_api_key"` 14 | 15 | UpstashEmail string `json:"upstash_email"` 16 | } 17 | -------------------------------------------------------------------------------- /internal/models/pw_reset_token.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | 6 | "gorm.io/gorm" 7 | ) 8 | 9 | // PWResetToken type that extends gorm.Model 10 | type PWResetToken struct { 11 | gorm.Model 12 | 13 | Email string 14 | IsValid bool 15 | Expiry *time.Time 16 | 17 | // Token is hashed like a password before storage 18 | Token string 19 | } 20 | 21 | func (p *PWResetToken) IsExpired() bool { 22 | timeLeft := p.Expiry.Sub(time.Now()) 23 | return timeLeft < 0 24 | } 25 | -------------------------------------------------------------------------------- /internal/models/role.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/porter-dev/porter/api/types" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | // The roles available for a project 9 | const ( 10 | RoleAdmin string = "admin" 11 | RoleDeveloper string = "developer" 12 | RoleViewer string = "viewer" 13 | ) 14 | 15 | // Role type that extends gorm.Model 16 | type Role struct { 17 | gorm.Model 18 | types.Role 19 | } 20 | 21 | func (r *Role) ToRoleType() *types.Role { 22 | return &types.Role{ 23 | Kind: r.Kind, 24 | UserID: r.UserID, 25 | ProjectID: r.ProjectID, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /internal/models/session.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "time" 5 | 6 | "gorm.io/gorm" 7 | ) 8 | 9 | // Session type that extends gorm.Model. 10 | type Session struct { 11 | gorm.Model 12 | // Session ID 13 | Key string `gorm:"unique"` 14 | // encrypted cookie 15 | Data []byte 16 | // Time the session will expire 17 | ExpiresAt time.Time 18 | } 19 | -------------------------------------------------------------------------------- /internal/models/tag.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "gorm.io/gorm" 5 | ) 6 | 7 | // Tag model used to group releases. 8 | 9 | // Tag type that extends gorm.Model 10 | type Tag struct { 11 | gorm.Model 12 | 13 | ProjectID uint `json:"project_id"` 14 | Name string `json:"name"` 15 | Color string `json:"color"` 16 | Releases []*Release `json:"releases" gorm:"many2many:release_tags"` 17 | } 18 | -------------------------------------------------------------------------------- /internal/notifier/sendgrid/client.go: -------------------------------------------------------------------------------- 1 | package sendgrid 2 | 3 | type SharedOpts struct { 4 | APIKey string 5 | SenderEmail string 6 | } 7 | -------------------------------------------------------------------------------- /internal/random/string.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "crypto/rand" 5 | "math/big" 6 | ) 7 | 8 | const randCharset string = "abcdefghijklmnopqrstuvwxyz1234567890" 9 | 10 | func StringWithCharset(length int, charset string) (string, error) { 11 | letters := charset 12 | 13 | if charset == "" { 14 | letters = randCharset 15 | } 16 | 17 | ret := make([]byte, length) 18 | for i := 0; i < length; i++ { 19 | num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) 20 | if err != nil { 21 | return "", err 22 | } 23 | ret[i] = letters[num.Int64()] 24 | } 25 | 26 | return string(ret), nil 27 | } 28 | -------------------------------------------------------------------------------- /internal/repository/allowlist.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | // AllowlistRepository represents the set of queries on the 4 | // Allowlist model 5 | type AllowlistRepository interface { 6 | UserEmailExists(email string) (bool, error) 7 | } 8 | -------------------------------------------------------------------------------- /internal/repository/api_token.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // APITokenRepository represents the set of queries on the APIToken model 8 | type APITokenRepository interface { 9 | CreateAPIToken(token *models.APIToken) (*models.APIToken, error) 10 | ListAPITokensByProjectID(projectID uint) ([]*models.APIToken, error) 11 | ReadAPIToken(projectID uint, uid string) (*models.APIToken, error) 12 | UpdateAPIToken(token *models.APIToken) (*models.APIToken, error) 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/app_event_webhook.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/porter-dev/porter/internal/models" 7 | ) 8 | 9 | // AppEventWebhookRepository provides storage for app event webhook config 10 | type AppEventWebhookRepository interface { 11 | Insert(ctx context.Context, webhook models.AppEventWebhooks) (models.AppEventWebhooks, error) 12 | } 13 | -------------------------------------------------------------------------------- /internal/repository/app_instance.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/porter-dev/porter/internal/models" 7 | ) 8 | 9 | // AppInstanceRepository represents the set of queries on the AppInstance model 10 | type AppInstanceRepository interface { 11 | // Get returns an app instance by its id 12 | Get(ctx context.Context, id string) (*models.AppInstance, error) 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/app_revision.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // AppRevisionRepository represents the set of queries on the AppRevision model 8 | type AppRevisionRepository interface { 9 | // AppRevisionById finds an app revision by id 10 | AppRevisionById(projectID uint, appRevisionId string) (*models.AppRevision, error) 11 | } 12 | -------------------------------------------------------------------------------- /internal/repository/app_template.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // AppTemplateRepository represents the set of queries on the AppTemplate model 8 | type AppTemplateRepository interface { 9 | // AppTemplateByPorterAppID finds an app template by its porter app id 10 | AppTemplateByPorterAppID(projectID, appID uint) (*models.AppTemplate, error) 11 | // CreateAppTemplate creates a new app template 12 | CreateAppTemplate(appTemplate *models.AppTemplate) (*models.AppTemplate, error) 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/auth_code.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // AuthCodeRepository represents the set of queries on the AuthCode model 8 | type AuthCodeRepository interface { 9 | CreateAuthCode(a *models.AuthCode) (*models.AuthCode, error) 10 | ReadAuthCode(code string) (*models.AuthCode, error) 11 | } 12 | -------------------------------------------------------------------------------- /internal/repository/build_config.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "github.com/porter-dev/porter/internal/models" 4 | 5 | // BuildConfigRepository represents the set of queries on the BuildConfig model 6 | type BuildConfigRepository interface { 7 | CreateBuildConfig(*models.BuildConfig) (*models.BuildConfig, error) 8 | UpdateBuildConfig(*models.BuildConfig) (*models.BuildConfig, error) 9 | GetBuildConfig(uint) (*models.BuildConfig, error) 10 | } 11 | -------------------------------------------------------------------------------- /internal/repository/cred_exchange_token.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "github.com/porter-dev/porter/internal/models" 4 | 5 | type CredentialsExchangeTokenRepository interface { 6 | CreateCredentialsExchangeToken(ceToken *models.CredentialsExchangeToken) (*models.CredentialsExchangeToken, error) 7 | ReadCredentialsExchangeToken(id uint) (*models.CredentialsExchangeToken, error) 8 | } 9 | -------------------------------------------------------------------------------- /internal/repository/database.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | type DatabaseRepository interface { 8 | CreateDatabase(database *models.Database) (*models.Database, error) 9 | ReadDatabase(projectID, clusterID, databaseID uint) (*models.Database, error) 10 | ReadDatabaseByInfraID(projectID, infraID uint) (*models.Database, error) 11 | ListDatabases(projectID, clusterID uint) ([]*models.Database, error) 12 | UpdateDatabase(database *models.Database) (*models.Database, error) 13 | DeleteDatabase(projectID, clusterID, databaseID uint) error 14 | } 15 | -------------------------------------------------------------------------------- /internal/repository/dns_record.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // DNSRecordRepository represents the set of queries on the 8 | // DNSRecord model 9 | type DNSRecordRepository interface { 10 | CreateDNSRecord(record *models.DNSRecord) (*models.DNSRecord, error) 11 | } 12 | -------------------------------------------------------------------------------- /internal/repository/git_action_config.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "github.com/porter-dev/porter/internal/models" 4 | 5 | // GitActionConfigRepository represents the set of queries on the 6 | // GitActionConfig model 7 | type GitActionConfigRepository interface { 8 | CreateGitActionConfig(gr *models.GitActionConfig) (*models.GitActionConfig, error) 9 | ReadGitActionConfig(id uint) (*models.GitActionConfig, error) 10 | UpdateGitActionConfig(gr *models.GitActionConfig) error 11 | } 12 | -------------------------------------------------------------------------------- /internal/repository/github_webhook.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/google/uuid" 7 | "github.com/porter-dev/porter/internal/models" 8 | ) 9 | 10 | // GithubWebhookRepository represents the set of queries on the GithubWebhook model 11 | type GithubWebhookRepository interface { 12 | Insert(ctx context.Context, webhook *models.GithubWebhook) (*models.GithubWebhook, error) 13 | Get(ctx context.Context, id uuid.UUID) (*models.GithubWebhook, error) 14 | GetByClusterAndAppID(ctx context.Context, clusterID, appID uint) (*models.GithubWebhook, error) 15 | } 16 | -------------------------------------------------------------------------------- /internal/repository/gitrepo.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "github.com/porter-dev/porter/internal/models" 4 | 5 | // GitRepoRepository represents the set of queries on the 6 | // GitRepo model 7 | type GitRepoRepository interface { 8 | CreateGitRepo(gr *models.GitRepo) (*models.GitRepo, error) 9 | ReadGitRepo(id uint) (*models.GitRepo, error) 10 | ListGitReposByProjectID(projectID uint) ([]*models.GitRepo, error) 11 | UpdateGitRepo(gr *models.GitRepo) (*models.GitRepo, error) 12 | DeleteGitRepo(gr *models.GitRepo) error 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/gorm/helpers/query.go: -------------------------------------------------------------------------------- 1 | package helpers 2 | 3 | type Query struct { 4 | PageSize int 5 | Page int 6 | } 7 | 8 | type QueryOption func(*Query) 9 | 10 | func WithPage(page int) func(q *Query) { 11 | if page == 0 { 12 | page = 1 13 | } 14 | return func(q *Query) { 15 | q.Page = page 16 | } 17 | } 18 | 19 | func WithPageSize(pageSize int) func(q *Query) { 20 | return func(q *Query) { 21 | q.PageSize = pageSize 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /internal/repository/gorm/ipam.go: -------------------------------------------------------------------------------- 1 | package gorm 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/repository" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | // Ipam uses gorm.DB for querying the database 9 | type Ipam struct { 10 | db *gorm.DB 11 | } 12 | 13 | // NewIpamRepository creates an IPAM connection 14 | func NewIpamRepository(db *gorm.DB) repository.IpamRepository { 15 | return &Ipam{db} 16 | } 17 | -------------------------------------------------------------------------------- /internal/repository/invite.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // InviteRepository represents the set of queries on the Invite model 8 | type InviteRepository interface { 9 | CreateInvite(invite *models.Invite) (*models.Invite, error) 10 | ReadInvite(projectID, inviteID uint) (*models.Invite, error) 11 | ReadInviteByToken(token string) (*models.Invite, error) 12 | ListInvitesByProjectID(projectID uint) ([]*models.Invite, error) 13 | UpdateInvite(invite *models.Invite) (*models.Invite, error) 14 | DeleteInvite(invite *models.Invite) error 15 | } 16 | -------------------------------------------------------------------------------- /internal/repository/ipam.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | // IpamRepository represents the set of queries on the Ipam model 4 | type IpamRepository interface{} 5 | -------------------------------------------------------------------------------- /internal/repository/monitor.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "github.com/porter-dev/porter/internal/models" 4 | 5 | type MonitorTestResultRepository interface { 6 | CreateMonitorTestResult(monitor *models.MonitorTestResult) (*models.MonitorTestResult, error) 7 | ReadMonitorTestResult(projectID, clusterID uint, operationID string) (*models.MonitorTestResult, error) 8 | UpdateMonitorTestResult(monitor *models.MonitorTestResult) (*models.MonitorTestResult, error) 9 | 10 | ArchiveMonitorTestResults(projectID, clusterID uint, recommenderID string) error 11 | DeleteOldMonitorTestResults(projectID, clusterID uint, recommenderID string) error 12 | } 13 | -------------------------------------------------------------------------------- /internal/repository/neon.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | 6 | ints "github.com/porter-dev/porter/internal/models/integrations" 7 | ) 8 | 9 | // NeonIntegrationRepository represents the set of queries on an Neon integration 10 | type NeonIntegrationRepository interface { 11 | // Insert creates a new neon integration 12 | Insert(ctx context.Context, neonInt ints.NeonIntegration) (ints.NeonIntegration, error) 13 | // Integrations returns all neon integrations for a given project 14 | Integrations(ctx context.Context, projectID uint) ([]ints.NeonIntegration, error) 15 | } 16 | -------------------------------------------------------------------------------- /internal/repository/onboarding.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import "github.com/porter-dev/porter/internal/models" 4 | 5 | // ProjectOnboardingRepository represents the set of queries on the Onboarding model 6 | type ProjectOnboardingRepository interface { 7 | CreateProjectOnboarding(onboarding *models.Onboarding) (*models.Onboarding, error) 8 | ReadProjectOnboarding(projID uint) (*models.Onboarding, error) 9 | UpdateProjectOnboarding(cache *models.Onboarding) (*models.Onboarding, error) 10 | } 11 | -------------------------------------------------------------------------------- /internal/repository/policy.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // PolicyRepository represents the set of queries on the Policy model 8 | type PolicyRepository interface { 9 | CreatePolicy(policy *models.Policy) (*models.Policy, error) 10 | ListPoliciesByProjectID(projectID uint) ([]*models.Policy, error) 11 | ReadPolicy(projectID uint, uid string) (*models.Policy, error) 12 | UpdatePolicy(token *models.Policy) (*models.Policy, error) 13 | DeletePolicy(policy *models.Policy) (*models.Policy, error) 14 | } 15 | -------------------------------------------------------------------------------- /internal/repository/pw_reset_token.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // PWResetTokenRepository represents the set of queries on the PWResetToken model 8 | type PWResetTokenRepository interface { 9 | CreatePWResetToken(pwToken *models.PWResetToken) (*models.PWResetToken, error) 10 | ReadPWResetToken(id uint) (*models.PWResetToken, error) 11 | UpdatePWResetToken(pwToken *models.PWResetToken) (*models.PWResetToken, error) 12 | } 13 | -------------------------------------------------------------------------------- /internal/repository/referral.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // ReferralRepository represents the set of queries on the Referral model 8 | type ReferralRepository interface { 9 | CreateReferral(referral *models.Referral) (*models.Referral, error) 10 | GetReferralByReferredID(referredID uint) (*models.Referral, error) 11 | CountReferralsByProjectID(projectID uint, status string) (int64, error) 12 | UpdateReferral(referral *models.Referral) (*models.Referral, error) 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/session.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "github.com/porter-dev/porter/internal/models" 5 | ) 6 | 7 | // SessionRepository represents the set of queries on the Session model 8 | type SessionRepository interface { 9 | CreateSession(session *models.Session) (*models.Session, error) 10 | UpdateSession(session *models.Session) (*models.Session, error) 11 | DeleteSession(session *models.Session) (*models.Session, error) 12 | SelectSession(session *models.Session) (*models.Session, error) 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/system_service_status.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/google/uuid" 7 | "github.com/porter-dev/porter/internal/models" 8 | ) 9 | 10 | // SystemServiceStatusRepository represents the set of queries on the SystemServiceStatus model 11 | type SystemServiceStatusRepository interface { 12 | ReadSystemServiceStatus(ctx context.Context, id uuid.UUID) (models.SystemServiceStatus, error) 13 | } 14 | -------------------------------------------------------------------------------- /internal/repository/upstash.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | 6 | ints "github.com/porter-dev/porter/internal/models/integrations" 7 | ) 8 | 9 | // UpstashIntegrationRepository represents the set of queries on an Upstash integration 10 | type UpstashIntegrationRepository interface { 11 | // Insert creates a new upstash integration 12 | Insert(ctx context.Context, upstashInt ints.UpstashIntegration) (ints.UpstashIntegration, error) 13 | // Integrations returns all upstash integrations belonging to a project 14 | Integrations(ctx context.Context, projectID uint) ([]ints.UpstashIntegration, error) 15 | } 16 | -------------------------------------------------------------------------------- /internal/usage/limit_ce.go: -------------------------------------------------------------------------------- 1 | //go:build !ee 2 | // +build !ee 3 | 4 | package usage 5 | 6 | import ( 7 | "github.com/porter-dev/porter/api/types" 8 | "github.com/porter-dev/porter/internal/models" 9 | "github.com/porter-dev/porter/internal/repository" 10 | ) 11 | 12 | func GetLimit(repo repository.Repository, proj *models.Project) (limit *types.ProjectUsage, err error) { 13 | copyLimit := types.BasicPlan 14 | 15 | return ©Limit, nil 16 | } 17 | -------------------------------------------------------------------------------- /internal/usage/limit_ee.go: -------------------------------------------------------------------------------- 1 | //go:build ee 2 | // +build ee 3 | 4 | package usage 5 | 6 | import ( 7 | "github.com/porter-dev/porter/api/types" 8 | "github.com/porter-dev/porter/ee/usage" 9 | "github.com/porter-dev/porter/internal/models" 10 | "github.com/porter-dev/porter/internal/repository" 11 | ) 12 | 13 | var GetLimit func(repo repository.Repository, proj *models.Project) (limit *types.ProjectUsage, err error) 14 | 15 | func init() { 16 | GetLimit = usage.GetLimit 17 | } 18 | -------------------------------------------------------------------------------- /internal/validator/validator.go: -------------------------------------------------------------------------------- 1 | package validator 2 | 3 | import ( 4 | "github.com/go-playground/validator/v10" 5 | "k8s.io/apimachinery/pkg/util/validation" 6 | ) 7 | 8 | // New creates a new instance of validator and sets the tag name 9 | // to "form", instead of "validate" 10 | func New() *validator.Validate { 11 | validate := validator.New() 12 | validate.SetTagName("form") 13 | validate.RegisterValidation("dns1123", func(fl validator.FieldLevel) bool { 14 | return len(validation.IsDNS1123Label(fl.Field().String())) == 0 15 | }) 16 | return validate 17 | } 18 | -------------------------------------------------------------------------------- /internal/worker/dispatcher_test.go: -------------------------------------------------------------------------------- 1 | package worker 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "go.uber.org/goleak" 8 | ) 9 | 10 | func TestDispatcher(t *testing.T) { 11 | defer goleak.VerifyNone(t) 12 | ctx := context.Background() 13 | jobChan := make(chan Job) 14 | 15 | d := NewDispatcher(10) 16 | err := d.Run(ctx, jobChan) 17 | if err != nil { 18 | panic(err) 19 | } 20 | 21 | d.Exit() 22 | } 23 | -------------------------------------------------------------------------------- /internal/worker/worker_test.go: -------------------------------------------------------------------------------- 1 | package worker 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/google/uuid" 8 | "go.uber.org/goleak" 9 | ) 10 | 11 | func TestWorker(t *testing.T) { 12 | defer goleak.VerifyNone(t) 13 | ctx := context.Background() 14 | 15 | uuid, err := uuid.NewUUID() 16 | if err != nil { 17 | panic(err) 18 | } 19 | 20 | workerPool := make(chan chan Job, 10) 21 | 22 | w := NewWorker(uuid, workerPool) 23 | 24 | w.Start(ctx) 25 | w.Stop() 26 | } 27 | -------------------------------------------------------------------------------- /provisioner/client/apply.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/porter-dev/porter/api/types" 8 | ptypes "github.com/porter-dev/porter/provisioner/types" 9 | ) 10 | 11 | // Apply initiates a new apply operation for infra 12 | func (c *Client) Apply( 13 | ctx context.Context, 14 | projID, infraID uint, 15 | req *ptypes.ApplyBaseRequest, 16 | ) (*types.Operation, error) { 17 | resp := &types.Operation{} 18 | 19 | err := c.postRequest( 20 | fmt.Sprintf( 21 | "/projects/%d/infras/%d/apply", 22 | projID, 23 | infraID, 24 | ), 25 | req, 26 | resp, 27 | ) 28 | 29 | return resp, err 30 | } 31 | -------------------------------------------------------------------------------- /provisioner/client/create_resource.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | ptypes "github.com/porter-dev/porter/provisioner/types" 8 | ) 9 | 10 | // CreateResource posts Terraform output to the provisioner service and creates the backing 11 | // resource in the database 12 | func (c *Client) CreateResource( 13 | ctx context.Context, 14 | workspaceID string, 15 | req *ptypes.CreateResourceRequest, 16 | ) error { 17 | err := c.postRequest( 18 | fmt.Sprintf( 19 | "/%s/resource", 20 | workspaceID, 21 | ), 22 | req, 23 | nil, 24 | ) 25 | 26 | return err 27 | } 28 | -------------------------------------------------------------------------------- /provisioner/client/delete.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | "github.com/porter-dev/porter/api/types" 8 | ptypes "github.com/porter-dev/porter/provisioner/types" 9 | ) 10 | 11 | // Apply initiates a new apply operation for infra 12 | func (c *Client) Delete( 13 | ctx context.Context, 14 | projID, infraID uint, 15 | req *ptypes.DeleteBaseRequest, 16 | ) (*types.Operation, error) { 17 | resp := &types.Operation{} 18 | 19 | err := c.deleteRequest( 20 | fmt.Sprintf( 21 | "/projects/%d/infras/%d", 22 | projID, 23 | infraID, 24 | ), 25 | req, 26 | resp, 27 | ) 28 | 29 | return resp, err 30 | } 31 | -------------------------------------------------------------------------------- /provisioner/client/delete_resource.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | // DeleteResource notifies the provisioner service that the backing infrastructure has been 9 | // destroyed 10 | func (c *Client) DeleteResource( 11 | ctx context.Context, 12 | workspaceID string, 13 | ) error { 14 | err := c.deleteRequest( 15 | fmt.Sprintf( 16 | "/%s/resource", 17 | workspaceID, 18 | ), 19 | nil, 20 | nil, 21 | ) 22 | 23 | return err 24 | } 25 | -------------------------------------------------------------------------------- /provisioner/client/get_logs.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | ptypes "github.com/porter-dev/porter/provisioner/types" 8 | ) 9 | 10 | // GetLogs returns logs from the operation, after the operation has completed 11 | func (c *Client) GetLogs( 12 | ctx context.Context, 13 | workspaceID string, 14 | ) (*ptypes.GetLogsResponse, error) { 15 | resp := &ptypes.GetLogsResponse{} 16 | 17 | err := c.getRequest( 18 | fmt.Sprintf( 19 | "/%s/logs", 20 | workspaceID, 21 | ), 22 | nil, 23 | resp, 24 | ) 25 | 26 | return resp, err 27 | } 28 | -------------------------------------------------------------------------------- /provisioner/client/get_raw_state.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | ptypes "github.com/porter-dev/porter/provisioner/types" 8 | ) 9 | 10 | // GetRawState gets the state stored for that infrastructure 11 | func (c *Client) GetRawState( 12 | ctx context.Context, 13 | workspaceID string, 14 | ) (*ptypes.ParseableRawTFState, error) { 15 | resp := &ptypes.ParseableRawTFState{} 16 | 17 | err := c.getRequest( 18 | fmt.Sprintf( 19 | "/%s/tfstate/raw", 20 | workspaceID, 21 | ), 22 | nil, 23 | resp, 24 | ) 25 | 26 | return resp, err 27 | } 28 | -------------------------------------------------------------------------------- /provisioner/client/report_error.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | 7 | ptypes "github.com/porter-dev/porter/provisioner/types" 8 | ) 9 | 10 | // ReportError reports a provisioning error to the provisioner service 11 | func (c *Client) ReportError( 12 | ctx context.Context, 13 | workspaceID string, 14 | req *ptypes.ReportErrorRequest, 15 | ) error { 16 | err := c.postRequest( 17 | fmt.Sprintf( 18 | "/%s/error", 19 | workspaceID, 20 | ), 21 | req, 22 | nil, 23 | ) 24 | 25 | return err 26 | } 27 | -------------------------------------------------------------------------------- /provisioner/integrations/storage/storage.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/porter-dev/porter/internal/models" 7 | ) 8 | 9 | var FileDoesNotExist error = fmt.Errorf("the specified file does not exist") 10 | 11 | type StorageManager interface { 12 | WriteFile(infra *models.Infra, name string, bytes []byte, shouldEncrypt bool) error 13 | ReadFile(infra *models.Infra, name string, shouldDecrypt bool) ([]byte, error) 14 | DeleteFile(infra *models.Infra, name string) error 15 | } 16 | -------------------------------------------------------------------------------- /provisioner/server/config/init_ce.go: -------------------------------------------------------------------------------- 1 | //go:build !ee 2 | // +build !ee 3 | 4 | package config 5 | 6 | func init() { 7 | sharedInit() 8 | } 9 | -------------------------------------------------------------------------------- /provisioner/server/handlers/healthcheck/livez.go: -------------------------------------------------------------------------------- 1 | package healthcheck 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/porter-dev/porter/provisioner/server/config" 7 | ) 8 | 9 | type LivezHandler struct { 10 | Config *config.Config 11 | } 12 | 13 | func NewLivezHandler( 14 | config *config.Config, 15 | ) *LivezHandler { 16 | return &LivezHandler{ 17 | Config: config, 18 | } 19 | } 20 | 21 | func (c *LivezHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 22 | writeHealthy(w) 23 | } 24 | -------------------------------------------------------------------------------- /provisioner/types/provision.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type ApplyBaseRequest struct { 4 | Kind string `json:"kind"` 5 | Values map[string]interface{} `json:"values"` 6 | OperationKind string `json:"operation_kind" form:"oneof=create retry_create update"` 7 | } 8 | 9 | type DeleteBaseRequest struct { 10 | OperationKind string `json:"operation_kind" form:"oneof=delete retry_delete"` 11 | } 12 | type CreateResourceRequest struct { 13 | Kind string `json:"kind"` 14 | Output map[string]interface{} `json:"output"` 15 | } 16 | 17 | type ReportErrorRequest struct { 18 | Error string `json:"error"` 19 | } 20 | -------------------------------------------------------------------------------- /provisioner/types/transformers.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // transforms PB types -> API types and API types -> PB types 4 | -------------------------------------------------------------------------------- /scripts/build/generate-spec.sh: -------------------------------------------------------------------------------- 1 | swagger generate spec --scan-models --include github.com/porter-dev/porter --work-dir ./cmd/app/ --output openapi.yaml -------------------------------------------------------------------------------- /scripts/build/proto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Builds auto-generated protobuf files 4 | 5 | protoc --go_out=. --go_opt=paths=source_relative \ 6 | --go-grpc_out=. --go-grpc_opt=paths=source_relative \ 7 | provisioner/pb/provisioner.proto 8 | -------------------------------------------------------------------------------- /scripts/dev-environment/RunMigrateDev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Load env variables for backend 4 | if [[ -e ./docker/.env ]] 5 | then 6 | set -a # automatically export all variables 7 | source ./docker/.env 8 | set +a 9 | else 10 | echo "Couldn't find any backend env variables, exiting process" 11 | exit 12 | fi 13 | 14 | go run -tags ee ./cmd/migrate -------------------------------------------------------------------------------- /scripts/dev-environment/StartDevServer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | printf "\033c" 4 | 5 | startFrontend() { 6 | cd ./dashboard && npm start; 7 | } 8 | 9 | startBackend() { 10 | # Load env variables for backend 11 | if [[ -e ./docker/.env ]] 12 | then 13 | set -a # automatically export all variables 14 | source ./docker/.env 15 | set +a 16 | else 17 | echo "Couldn't find any backend env variables, exiting process" 18 | exit 19 | fi 20 | air -c .air.toml 21 | } 22 | 23 | startBackend & 24 | startFrontend & 25 | wait 26 | 27 | cleanup() { 28 | rv=$? 29 | clear 30 | exit $rv 31 | } 32 | 33 | trap "cleanup" EXIT -------------------------------------------------------------------------------- /scripts/dev-environment/StartProvisionerServer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Load env variables for backend 4 | if [[ -e ./docker/.env ]] 5 | then 6 | set -a # automatically export all variables 7 | source ./docker/.env 8 | set +a 9 | else 10 | echo "Couldn't find any backend env variables, exiting process" 11 | exit 12 | fi 13 | 14 | air -c .air.provisioner.toml -------------------------------------------------------------------------------- /scripts/dev-environment/StartWorkerServer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Load env variables for backend 4 | if [[ -e ./docker/.env ]] 5 | then 6 | set -a # automatically export all variables 7 | source ./docker/.env 8 | set +a 9 | else 10 | echo "Couldn't find any backend env variables, exiting process" 11 | exit 12 | fi 13 | 14 | air -c .air.worker.toml -------------------------------------------------------------------------------- /services/cli_install_script_container/Dockerfile: -------------------------------------------------------------------------------- 1 | # pinned because of https://github.com/moby/moby/issues/45935 2 | FROM golang:1.20.5-alpine 3 | 4 | WORKDIR /app 5 | COPY . . 6 | 7 | RUN go mod download 8 | RUN go build -o serve main.go 9 | 10 | ENTRYPOINT [ "./serve" ] 11 | -------------------------------------------------------------------------------- /services/cli_install_script_container/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/porter-dev/porter/services/cli_install_script_container 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/golang/protobuf v1.3.2 // indirect 7 | github.com/google/go-github/v50 v50.0.0 // indirect 8 | github.com/google/go-querystring v1.1.0 // indirect 9 | golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect 10 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect 11 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be // indirect 12 | google.golang.org/appengine v1.6.7 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /services/deploy_init_container/Dockerfile: -------------------------------------------------------------------------------- 1 | # pinned because of https://github.com/moby/moby/issues/45935 2 | FROM golang:1.20.5-alpine as builder 3 | 4 | WORKDIR /init-backend 5 | COPY main.go . 6 | 7 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o main main.go 8 | 9 | FROM alpine 10 | 11 | COPY --from=builder /init-backend/main / 12 | COPY assets/init.html /assets/ 13 | COPY assets/porter.png /assets/ 14 | ADD start.sh / 15 | CMD ["sh", "/start.sh"] -------------------------------------------------------------------------------- /services/deploy_init_container/assets/porter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/porter-dev/porter-archive/ed607ee7d3ca765c65eda23987eed6a41502f09f/services/deploy_init_container/assets/porter.png -------------------------------------------------------------------------------- /services/deploy_init_container/default-backend-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-errors 5 | spec: 6 | replicas: 1 7 | template: 8 | metadata: 9 | labels: 10 | app: nginx-errors 11 | spec: 12 | containers: 13 | - name: nginx-errors 14 | image: gcr.io/porter-dev-273614/error-backend:latest 15 | imagePullPolicy: Always 16 | resources: 17 | limits: 18 | cpu: 20m 19 | memory: 40Mi 20 | requests: 21 | cpu: 10m 22 | memory: 20Mi -------------------------------------------------------------------------------- /services/deploy_init_container/default-backend-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx-errors 5 | spec: 6 | selector: 7 | app: nginx-errors 8 | ports: 9 | - protocol: TCP 10 | port: 80 11 | targetPort: 9090 -------------------------------------------------------------------------------- /services/deploy_job_init_container/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ADD start.sh / 3 | CMD ["sh", "/start.sh"] -------------------------------------------------------------------------------- /services/job_sidecar_container/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye-slim 2 | 3 | # fetch procps for ps command, coreutils for tail with -pid flag 4 | RUN apt-get update && apt-get install procps coreutils -y 5 | 6 | COPY *.sh . 7 | 8 | RUN ["chmod", "+x", "./job_killer.sh", "./signal.sh", "./sidecar_killer.sh", "./wait_for_job.sh"] 9 | 10 | ENTRYPOINT ["./job_killer.sh"] 11 | -------------------------------------------------------------------------------- /services/job_sidecar_container/signal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Sends termination signal to job_killer.sh, which triggers the job shutdown process. 4 | 5 | pid=$(ps x | grep "[.]/job_killer.sh" | awk '{ printf "%d ", $1 }'); 6 | kill -TERM $pid -------------------------------------------------------------------------------- /services/job_sidecar_container/wait_for_job.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Usage: wait_for_job.sh [process_pattern] 4 | # 5 | # This script waits for a job to be ready before exiting. 6 | 7 | pattern=$1 8 | 9 | target_pid=$(pgrep -f $pattern -l | grep -v 'job_killer.sh' | grep -v 'wait_for_job.sh' | grep -v 'grep' | awk '{ printf "%d ", $1 }' | sort) 10 | 11 | while [ ! "$target_pid" ]; do 12 | sleep 0.1 13 | target_pid=$(pgrep -f $pattern -l | grep -v 'job_killer.sh' | grep -v 'wait_for_job.sh' | grep -v 'grep' | awk '{ printf "%d ", $1 }' | sort) 14 | done -------------------------------------------------------------------------------- /services/preview_env_setup_job/Dockerfile: -------------------------------------------------------------------------------- 1 | # Build 2 | # pinned because of https://github.com/moby/moby/issues/45935 3 | FROM golang:1.20.5-alpine as base 4 | 5 | WORKDIR /app 6 | COPY . . 7 | 8 | RUN apk update && apk add --no-cache gcc musl-dev git protoc 9 | ARG CGO_ENABLED=0 10 | 11 | RUN go mod download 12 | RUN go build -ldflags '-w -s' -a -o setup_preview_env main.go 13 | 14 | # Deploy 15 | FROM alpine 16 | RUN apk update 17 | 18 | COPY --from=base /app/setup_preview_env /app/ 19 | 20 | ENTRYPOINT [ "/app/setup_preview_env" ] 21 | -------------------------------------------------------------------------------- /zarf/docker/Dockerfile.production: -------------------------------------------------------------------------------- 1 | # All build artifacts are built in github actions, and copied in 2 | # Ubuntu is used to match Github action, and use github action caching instead of docker caching 3 | FROM ubuntu as runner 4 | RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates tzdata 5 | 6 | WORKDIR /porter 7 | COPY bin/app /porter/ 8 | COPY bin/migrate /porter/ 9 | COPY build/ /porter/static 10 | RUN chmod +x /porter/app /porter/migrate 11 | -------------------------------------------------------------------------------- /zarf/docker/Dockerfile.server.tilt: -------------------------------------------------------------------------------- 1 | FROM golang:1.20.1 as installer 2 | RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates 3 | RUN go install github.com/go-delve/delve/cmd/dlv@latest 4 | RUN chmod +x /go/bin/dlv 5 | 6 | FROM debian:bullseye-slim as runner 7 | WORKDIR /app 8 | COPY --from=installer /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 9 | COPY --from=installer /go/bin/dlv / 10 | COPY ./bin/porter /app 11 | COPY ./bin/migrate /app --------------------------------------------------------------------------------