MCPcopy Create free account
hub / github.com/PostHog/duckgres / patchTenantPinning

Method patchTenantPinning

controlplane/admin/api.go:923–982  ·  view source on GitHub ↗

4 KiB; the body is two strings patchTenantPinning sets the image and/or ducklake_version columns on a tenant's managed_warehouses row without touching the rest of the warehouse config. This replaces the operational shape of running `UPDATE duckgres_managed_warehouses SET image=..., ducklake_version=

(c *gin.Context)

Source from the content-addressed store, hash-verified

921
922// createOrgRequest is the POST /orgs body: the org config plus its REQUIRED
923// first team (same contract as the provisioning API — an org cannot exist
924// without a team). schema_name is optional; omitted derives the conventional
925// "team_<id>". No billing semantics — the row is a plain team.
926type createOrgRequest struct {
927 configstore.Org
928 TeamID int64 `json:"team_id"`
929 SchemaName string `json:"schema_name"`
930}
931
932func (h *apiHandler) createOrg(c *gin.Context) {
933 var req createOrgRequest
934 if err := c.ShouldBindJSON(&req); err != nil {
935 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
936 return
937 }
938 org := req.Org
939 if err := validateOrgMutationPayload(&org); err != nil {
940 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
941 return
942 }
943 if org.Name == "" {
944 c.JSON(http.StatusBadRequest, gin.H{"error": "name is required"})
945 return
946 }
947 // database_name becomes the org's managed hostname label, so it must be a
948 // routable single DNS label at birth (same rule as the provisioning API).
949 // Trim the operator's value first so " acme" fails with the real problem
950 // instead of storing leading whitespace.
951 org.DatabaseName = strings.TrimSpace(org.DatabaseName)
952 if err := configstore.ValidateDatabaseName(org.DatabaseName); err != nil {
953 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
954 return
955 }
956 if req.TeamID <= 0 {
957 c.JSON(http.StatusBadRequest, gin.H{"error": "team_id is required (a positive PostHog team id — every org must have at least one team)"})
958 return
959 }
960 schemaName := req.SchemaName
961 if schemaName == "" {
962 schemaName = fmt.Sprintf("team_%d", req.TeamID)
963 }
964 if err := configstore.ValidateOrgTeamSchemaName(schemaName); err != nil {
965 c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
966 return
967 }
968 // Normalize empty hostname_alias to NULL on insert so the unique index
969 // doesn't reject a second org with an explicit empty string. Centralizing
970 // the rule at the handler layer keeps any future store impl from having
971 // to repeat it.
972 if org.HostnameAlias != nil && *org.HostnameAlias == "" {
973 org.HostnameAlias = nil
974 }
975 // POST /orgs has no :id param, so the audit org column is blank — record the
976 // created org's name here instead.
977 setAuditDetail(c, fmt.Sprintf("created org %s (first team %d, schema %s)", org.Name, req.TeamID, schemaName))
978 if err := h.store.CreateOrg(&org, req.TeamID, schemaName); err != nil {
979 c.JSON(http.StatusConflict, gin.H{"error": err.Error()})
980 return

Callers

nothing calls this directly

Calls 5

ErrorMethod · 0.95
orgStrFunction · 0.85
setAuditDetailFunction · 0.85

Tested by

no test coverage detected