README
¶
admin
This directory contains the control-plane for multi-user, hosted deployments of Rill.
Running in development
- Create a
.env
file at the root of the repo containing:
RILL_ADMIN_DATABASE_DRIVER=postgres
RILL_ADMIN_DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres
RILL_ADMIN_HTTP_PORT=8080
RILL_ADMIN_GRPC_PORT=9090
RILL_ADMIN_METRICS_EXPORTER="prometheus"
RILL_ADMIN_TRACES_EXPORTER=""
RILL_ADMIN_EXTERNAL_URL=http://localhost:8080
RILL_ADMIN_FRONTEND_URL=http://localhost:3000
RILL_ADMIN_ALLOWED_ORIGINS=*
# Hex-encoded comma-separated list of key pairs. To generate, run "go run ./scripts/generate_keypairs/main.go"
# For details: https://pkg.go.dev/github.com/gorilla/sessions#NewCookieStore
RILL_ADMIN_SESSION_KEY_PAIRS=7938b8c95ac90b3731c353076daeae8a,90c22a5a6c6b442afdb46855f95eb7d6
# JWKS details for signing JWTs. The JWKS must contain *private* keys. To generate, run "go run ./scripts/generate_jwks/main.go"
RILL_ADMIN_SIGNING_JWKS=
RILL_ADMIN_SIGNING_KEY_ID=
# Get these from https://auth0.com/ (or ask a team member)
RILL_ADMIN_AUTH_DOMAIN=gorillio-stage.auth0.com
RILL_ADMIN_AUTH_CLIENT_ID=
RILL_ADMIN_AUTH_CLIENT_SECRET=
# Get these from https://github.com/ (or ask a team member)
RILL_ADMIN_GITHUB_APP_ID=302634
RILL_ADMIN_GITHUB_APP_NAME=rill-cloud-dev
RILL_ADMIN_GITHUB_APP_PRIVATE_KEY=
RILL_ADMIN_GITHUB_APP_WEBHOOK_SECRET=
RILL_ADMIN_GITHUB_CLIENT_ID=
RILL_ADMIN_GITHUB_CLIENT_SECRET=
# For email client
RILL_ADMIN_EMAIL_SMTP_HOST=
RILL_ADMIN_EMAIL_SMTP_PORT=
RILL_ADMIN_EMAIL_SMTP_USERNAME=
RILL_ADMIN_EMAIL_SMTP_PASSWORD=
RILL_ADMIN_EMAIL_SENDER_EMAIL=
RILL_ADMIN_EMAIL_SENDER_NAME=
RILL_ADMIN_EMAIL_BCC=
- In a separate terminal, run Postgres in the background:
docker-compose -f admin/docker-compose.yml up
# Data is persisted. To clear, run: docker-compose -f admin/docker-compose.yml down --volumes
- Run the server:
go run ./cli admin start
- Ping the server:
go run ./cli admin ping --url http://localhost:9090
You can now call the local admin server from the CLI by overriding the admin API URL. For example:
go run ./cli org create --api-url http://localhost:9090
Adding endpoints
We define our APIs using gRPC and use gRPC-Gateway to map the RPCs to a RESTful API. See proto/README.md
for details.
To add a new endpoint:
- Describe the endpoint in
proto/rill/admin/v1/api.proto
- Re-generate gRPC and OpenAPI interfaces by running
make proto.generate
- Copy the new handler signature from the
AdminServiceServer
interface inproto/gen/rill/admin/v1/api_grpc_pb.go
- Paste the handler signature and implement it in a relevant file in
admin/server/
Using the Github App in development
We use a Github App to listen to pushes on repositories connected to Rill to do automated deployments. The app has access to read contents
and receives webhooks on git push
.
Github relies on webhooks to deliver information about new connections, pushes, etc. In development, in order for webhooks to be received on localhost
, we use this proxy service: https://github.com/probot/smee.io.
Setup instructions:
- Install Smee
npm install --global smee-client
- Run it (get
IDENTIFIER
from the Github App info or a team member):
smee --port 8080 --path /github/webhook --url https://smee.io/IDENTIFIER
CLI login/logout
For trying out CLI login add api-url parameter to point to local admin server like this:
go run ./cli login --api-url http://localhost:9090/
For trying out CLI logout add api-url parameter to point to local admin server like this:
go run ./cli logout --api-url http://localhost:9090/
Adding a new field preferences
To add a new preference field for the user, follow these steps:
- Include a new column named
preference_<name>
in theusers
table. This can be accomplished by appending an appropriateALTER TABLE
query to a newly created.sql
file located within thepostgres/migrations
folder. - In the admin
api.proto
file, incorporate the optional preference field within themessage UserPreferences
definition. - Revise the method definition for UpdateUserPreferences to encompass the handling of the new preference in the respective service.
- Adjust the
UpdateUser
SQL query to encompass the new preference field, ensuring that it is included during the update operation. - Identify all instances where the
UpdateUser
method is called and update them to include the new preference value.
By meticulously following these steps, the new preference field can be successfully incorporated for the user. Remember to update the database schema, proto file, service method, SQL query, and method invocations to properly accommodate the new preference field.
Documentation
¶
Index ¶
- Constants
- Variables
- type AuthToken
- type Github
- type Options
- type Service
- func (s *Service) Close() error
- func (s *Service) CreateOrUpdateUser(ctx context.Context, email, name, photoURL string) (*database.User, error)
- func (s *Service) CreateOrganizationForUser(ctx context.Context, userID, orgName, description string) (*database.Organization, error)
- func (s *Service) CreateProject(ctx context.Context, org *database.Organization, userID string, ...) (*database.Project, error)
- func (s *Service) GetGithubInstallation(ctx context.Context, githubURL string) (int64, error)
- func (s *Service) HibernateDeployments(ctx context.Context) error
- func (s *Service) IssueDeviceAuthCode(ctx context.Context, clientID string) (*database.DeviceAuthCode, error)
- func (s *Service) IssueServiceAuthToken(ctx context.Context, serviceID string, ttl *time.Duration) (AuthToken, error)
- func (s *Service) IssueUserAuthToken(ctx context.Context, userID, clientID, displayName string, ...) (AuthToken, error)
- func (s *Service) LookupGithubRepoForUser(ctx context.Context, installationID int64, githubURL, gitUsername string) (*github.Repository, error)
- func (s *Service) OrganizationPermissionsForService(ctx context.Context, orgID, serviceID string) (*adminv1.OrganizationPermissions, error)
- func (s *Service) OrganizationPermissionsForUser(ctx context.Context, orgID, userID string) (*adminv1.OrganizationPermissions, error)
- func (s *Service) ProcessGithubEvent(ctx context.Context, rawEvent any) error
- func (s *Service) ProjectPermissionsForService(ctx context.Context, projectID, serviceID string, ...) (*adminv1.ProjectPermissions, error)
- func (s *Service) ProjectPermissionsForUser(ctx context.Context, projectID, userID string, ...) (*adminv1.ProjectPermissions, error)
- func (s *Service) RevokeAuthToken(ctx context.Context, token string) error
- func (s *Service) TeardownProject(ctx context.Context, p *database.Project) error
- func (s *Service) TriggerReconcile(ctx context.Context, depl *database.Deployment) error
- func (s *Service) TriggerRedeploy(ctx context.Context, proj *database.Project, prevDepl *database.Deployment) error
- func (s *Service) TriggerRefreshSources(ctx context.Context, depl *database.Deployment, sources []string) error
- func (s *Service) UnsafeWaitForReconciles()
- func (s *Service) UpdateDeploymentAnnotations(ctx context.Context, projID string, annotations deploymentAnnotations) error
- func (s *Service) UpdateOrgDeploymentAnnotations(ctx context.Context, orgID, orgNewName string) error
- func (s *Service) UpdateProject(ctx context.Context, proj *database.Project, ...) (*database.Project, error)
- func (s *Service) UpdateProjectVariables(ctx context.Context, proj *database.Project, variables map[string]string) (*database.Project, error)
- func (s *Service) ValidateAuthToken(ctx context.Context, token string) (AuthToken, error)
Constants ¶
const DeviceAuthCodeTTL = 10 * time.Minute
Variables ¶
var ( ErrUserIsNotCollaborator = fmt.Errorf("user is not a collaborator for the repository") ErrGithubInstallationNotFound = fmt.Errorf("github installation not found") )
Functions ¶
This section is empty.
Types ¶
type AuthToken ¶ added in v0.23.0
AuthToken is the interface package admin uses to provide a consolidated view of a token string and its DB model.
type Github ¶ added in v0.25.0
type Github interface { AppClient() *github.Client InstallationClient(installationID int64) (*github.Client, error) InstallationToken(ctx context.Context, installationID int64) (string, error) }
Github exposes the features we require from the Github API.
type Service ¶
type Service struct { DB database.DB Provisioner *provisioner.StaticProvisioner Email *email.Client Used *usedFlusher Github Github // contains filtered or unexported fields }
func (*Service) CreateOrUpdateUser ¶ added in v0.23.0
func (*Service) CreateOrganizationForUser ¶ added in v0.24.0
func (*Service) CreateProject ¶ added in v0.23.0
func (s *Service) CreateProject(ctx context.Context, org *database.Organization, userID string, opts *database.InsertProjectOptions) (*database.Project, error)
CreateProject creates a new project and provisions and reconciles a prod deployment for it.
func (*Service) GetGithubInstallation ¶ added in v0.24.0
GetGithubInstallation returns a non zero Github installation ID if the Github App is installed on the repository and is not in suspended state The githubURL should be a HTTPS URL for a Github repository without the .git suffix.
func (*Service) HibernateDeployments ¶ added in v0.29.1
HibernateDeployments tears down unused deployments
func (*Service) IssueDeviceAuthCode ¶ added in v0.24.0
func (*Service) IssueServiceAuthToken ¶ added in v0.31.0
func (s *Service) IssueServiceAuthToken(ctx context.Context, serviceID string, ttl *time.Duration) (AuthToken, error)
IssueServiceAuthToken generates and persists a new auth token for a service.
func (*Service) IssueUserAuthToken ¶ added in v0.23.0
func (s *Service) IssueUserAuthToken(ctx context.Context, userID, clientID, displayName string, representingUserID *string, ttl *time.Duration) (AuthToken, error)
IssueUserAuthToken generates and persists a new auth token for a user.
func (*Service) LookupGithubRepoForUser ¶ added in v0.24.0
func (s *Service) LookupGithubRepoForUser(ctx context.Context, installationID int64, githubURL, gitUsername string) (*github.Repository, error)
LookupGithubRepoForUser returns a Github repository iff the Github App is installed on the repository and user is a collaborator of the project. The githubURL should be a HTTPS URL for a Github repository without the .git suffix.
func (*Service) OrganizationPermissionsForService ¶ added in v0.33.2
func (s *Service) OrganizationPermissionsForService(ctx context.Context, orgID, serviceID string) (*adminv1.OrganizationPermissions, error)
OrganizationPermissionsForService resolves organization permissions for a service. A service currently gets full permissions on the org they belong to.
func (*Service) OrganizationPermissionsForUser ¶ added in v0.33.2
func (s *Service) OrganizationPermissionsForUser(ctx context.Context, orgID, userID string) (*adminv1.OrganizationPermissions, error)
OrganizationPermissionsForUser resolves organization permissions for a user.
func (*Service) ProcessGithubEvent ¶ added in v0.23.0
ProcessGithubEvent processes a Github event (usually received over webhooks). After validating that the event is a valid Github event, it moves further processing to the background and returns a nil error.
func (*Service) ProjectPermissionsForService ¶ added in v0.33.2
func (s *Service) ProjectPermissionsForService(ctx context.Context, projectID, serviceID string, orgPerms *adminv1.OrganizationPermissions) (*adminv1.ProjectPermissions, error)
ProjectPermissionsService resolves project permissions for a service. A service currently gets full permissions on all projects in the org they belong to.
func (*Service) ProjectPermissionsForUser ¶ added in v0.33.2
func (s *Service) ProjectPermissionsForUser(ctx context.Context, projectID, userID string, orgPerms *adminv1.OrganizationPermissions) (*adminv1.ProjectPermissions, error)
ProjectPermissionsForUser resolves project permissions for a user.
func (*Service) RevokeAuthToken ¶ added in v0.23.0
RevokeAuthToken removes an auth token from persistent storage.
func (*Service) TeardownProject ¶ added in v0.23.0
TeardownProject tears down a project and all its deployments.
func (*Service) TriggerReconcile ¶ added in v0.23.0
TriggerReconcile triggers a reconcile for a deployment.
func (*Service) TriggerRedeploy ¶ added in v0.24.3
func (s *Service) TriggerRedeploy(ctx context.Context, proj *database.Project, prevDepl *database.Deployment) error
TriggerRedeploy de-provisions and re-provisions a project's prod deployment.
func (*Service) TriggerRefreshSources ¶ added in v0.24.3
func (s *Service) TriggerRefreshSources(ctx context.Context, depl *database.Deployment, sources []string) error
TriggerRefreshSource triggers refresh of a deployment's sources. If the sources slice is nil, it will refresh all sources.f
func (*Service) UnsafeWaitForReconciles ¶ added in v0.27.0
func (s *Service) UnsafeWaitForReconciles()
UnsafeWaitForReconciles waits for all background reconciles to finish. It is unsafe because while it is running, no new reconciles should be started. It's a temporary solution until the runtime is able to reconcile asynchronously. Unlike s.Close(), it does not cancel currently running reconciles, it just waits for them to finish.
func (*Service) UpdateDeploymentAnnotations ¶ added in v0.32.0
func (s *Service) UpdateDeploymentAnnotations(ctx context.Context, projID string, annotations deploymentAnnotations) error
UpdateDeploymentAnnotations pushes the updated annotations to deployments. NOTE : this does not trigger reconcile.
func (*Service) UpdateOrgDeploymentAnnotations ¶ added in v0.32.0
func (s *Service) UpdateOrgDeploymentAnnotations(ctx context.Context, orgID, orgNewName string) error
UpdateOrgDeploymentAnnotations iterates over projects of the given org and updates annotations of corresponding deployments with the new organization name NOTE : this does not trigger reconcile.
func (*Service) UpdateProject ¶ added in v0.23.0
func (s *Service) UpdateProject(ctx context.Context, proj *database.Project, opts *database.UpdateProjectOptions) (*database.Project, error)
UpdateProject updates a project and any impacted deployments. It runs a reconcile if deployment parameters (like branch or variables) have been changed and reconcileDeployment is set.
func (*Service) UpdateProjectVariables ¶ added in v0.28.0
func (s *Service) UpdateProjectVariables(ctx context.Context, proj *database.Project, variables map[string]string) (*database.Project, error)
UpdateProjectVariables updates project's variables and pushes the updated variables to deployments. NOTE : this does not trigger reconcile.