Create handles POST /hosts/create.
(w http.ResponseWriter, r *http.Request)
| 129 | |
| 130 | // Create handles POST /hosts/create. |
| 131 | func (h *HostsHandler) Create(w http.ResponseWriter, r *http.Request) { |
| 132 | var req struct { |
| 133 | FriendlyName string `json:"friendly_name"` |
| 134 | HostGroupIds []string `json:"hostGroupIds"` |
| 135 | DockerEnabled *bool `json:"docker_enabled"` |
| 136 | ComplianceEnabled *bool `json:"compliance_enabled"` |
| 137 | ExpectedPlatform *string `json:"expected_platform"` |
| 138 | } |
| 139 | if err := decodeJSON(r, &req); err != nil { |
| 140 | Error(w, http.StatusBadRequest, "Invalid request body") |
| 141 | return |
| 142 | } |
| 143 | if req.FriendlyName == "" { |
| 144 | Error(w, http.StatusBadRequest, "Friendly name is required") |
| 145 | return |
| 146 | } |
| 147 | |
| 148 | apiID, apiKey, apiKeyHash, err := generateApiCredentials() |
| 149 | if err != nil { |
| 150 | Error(w, http.StatusInternalServerError, "Failed to generate credentials") |
| 151 | return |
| 152 | } |
| 153 | |
| 154 | complianceEnabled := false |
| 155 | complianceOnDemandOnly := true |
| 156 | if req.ComplianceEnabled != nil { |
| 157 | complianceEnabled = *req.ComplianceEnabled |
| 158 | complianceOnDemandOnly = !complianceEnabled |
| 159 | } |
| 160 | s, _ := h.settings.GetFirst(r.Context()) |
| 161 | if s != nil && s.DefaultComplianceMode == "enabled" { |
| 162 | complianceOnDemandOnly = false |
| 163 | } |
| 164 | |
| 165 | // Enforce host limit if a package is applied. |
| 166 | if entry := hostctx.EntryFromContext(r.Context()); entry != nil && entry.MaxHosts != nil { |
| 167 | count, countErr := h.hosts.Count(r.Context()) |
| 168 | if countErr == nil && count >= *entry.MaxHosts { |
| 169 | Error(w, http.StatusForbidden, "Host limit reached for this host's package") |
| 170 | return |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | machineID := "pending-" + uuid.New().String() |
| 175 | host := &models.Host{ |
| 176 | MachineID: &machineID, |
| 177 | FriendlyName: req.FriendlyName, |
| 178 | OSType: "unknown", |
| 179 | OSVersion: "unknown", |
| 180 | Status: "pending", |
| 181 | ApiID: apiID, |
| 182 | ApiKey: apiKeyHash, |
| 183 | DockerEnabled: req.DockerEnabled != nil && *req.DockerEnabled, |
| 184 | ComplianceEnabled: complianceEnabled, |
| 185 | ComplianceOnDemandOnly: complianceOnDemandOnly, |
| 186 | ExpectedPlatform: req.ExpectedPlatform, |
| 187 | } |
| 188 | if err := h.hosts.Create(r.Context(), host); err != nil { |
nothing calls this directly
no test coverage detected