client/project.go (132 lines of code) (raw):

package client import ( "bytes" "context" "encoding/json" "errors" "fmt" "net/http" "strconv" "terraform-provider-teamcity/models" ) func (c *Client) NewProject(p models.ProjectJson) (models.ProjectJson, error) { rb, err := json.Marshal(p) if err != nil { return models.ProjectJson{}, err } var newProject = models.ProjectJson{} endpoint := "/projects" err = c.PostRequest(endpoint, bytes.NewReader(rb), &newProject) if err != nil { return models.ProjectJson{}, err } return newProject, nil } func (c *Client) GetProject(id string) (*models.ProjectJson, error) { var actual models.ProjectJson endpoint := fmt.Sprintf("/projects/id:%s", id) err := c.GetRequest(endpoint, "", &actual) if errors.Is(err, ErrNotFound) { return nil, nil } if err != nil { return nil, err } return &actual, nil } func (c *Client) DeleteProject(id string) error { endpoint := fmt.Sprintf("/projects/id:%s", id) err := c.DeleteRequest(endpoint) if err != nil { return err } return nil } // TODO: refactor other methods in the same way as the New/Get/DeleteProject func (c *Client) NewProjectFeature(id string, feature models.ProjectFeatureJson) (models.ProjectFeatureJson, error) { rb, err := json.Marshal(feature) if err != nil { return models.ProjectFeatureJson{}, err } var actual models.ProjectFeatureJson endpoint := fmt.Sprintf("/projects/id:%s/projectFeatures", id) err = c.PostRequest(endpoint, bytes.NewReader(rb), &actual) if err != nil { return models.ProjectFeatureJson{}, err } return actual, nil } func (c *Client) GetProjectFeature(projectId, featureId string) (*models.ProjectFeatureJson, error) { var actual models.ProjectFeatureJson endpoint := fmt.Sprintf("/projects/id:%s/projectFeatures/id:%s", projectId, featureId) err := c.GetRequest(endpoint, "", &actual) if errors.Is(err, ErrNotFound) { return nil, nil } if err != nil { return nil, err } return &actual, nil } func (c *Client) DeleteProjectFeature(projectId, featureId string) error { endpoint := fmt.Sprintf("/projects/id:%s/projectFeatures/id:%s", projectId, featureId) return c.DeleteRequest(endpoint) } type ProjectLocator struct { Id string `json:"id"` } func (c *Client) GetVersionedSettings(projectId string) (*models.VersionedSettingsJson, error) { var actual models.VersionedSettingsJson endpoint := fmt.Sprintf("/projects/id:%s/versionedSettings/config", projectId) err := c.GetRequest(endpoint, "", &actual) if errors.Is(err, ErrNotFound) { return nil, nil } if err != nil { return nil, err } return &actual, nil } func (c *Client) SetVersionedSettings(projectId string, settings models.VersionedSettingsJson) (*models.VersionedSettingsJson, error) { rb, err := json.Marshal(settings) if err != nil { return nil, err } var actual models.VersionedSettingsJson endpoint := fmt.Sprintf("/projects/id:%s/versionedSettings/config", projectId) err = c.PutRequest(endpoint, bytes.NewReader(rb), &actual) if err != nil { return nil, err } //TODO TeamCIty rest api bug TW-90967, remove when fixed if settings.ShowSettingsChanges != nil && actual.ShowSettingsChanges != settings.ShowSettingsChanges { corrected, err := c.SetVersionedSettingsProperty(projectId, "showSettingsChanges", strconv.FormatBool(*settings.ShowSettingsChanges)) if err != nil { return nil, fmt.Errorf("could not correct showSettingsChanges property, potentially not enough time for VersionedSettings to be applied: %w", err) } var correctedShowSettingsChanges bool err = json.Unmarshal(corrected, &correctedShowSettingsChanges) if err != nil { return nil, fmt.Errorf("malformed showSettingsChanges property, more info: %w", err) } actual.ShowSettingsChanges = &correctedShowSettingsChanges } return &actual, nil } func (c *Client) SetVersionedSettingsProperty(projectId string, property string, value string) ([]byte, error) { paramValue := []byte(value) req, err := http.NewRequest("PUT", fmt.Sprintf("%s/projects/id:%s/versionedSettings/config/parameters/%s", c.RestURL, projectId, property), bytes.NewReader(paramValue)) if err != nil { return nil, err } resp, err := c.retryableRequestWithType(req, "text/plain", retryPolicy) if err != nil { return nil, err } return resp.Body, nil } func retryPolicy(_ context.Context, resp *http.Response, _ error) (bool, error) { if resp.StatusCode == http.StatusInternalServerError { // wait the main object/feature to be ready for a property change return true, nil } else { return false, nil } }