mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 05:49:40 +02:00
* feat: airgapped draft * feat: enhance airgapped installation script and build process - Added installation checks for Docker and Docker Compose versions. - Implemented yq for dynamic updates to docker-compose.yml, including setting environment variables and handling service volumes. - Improved build.sh to install yq if not present and manage Docker images for airgapped setups. - Updated install.sh to streamline the installation process and ensure necessary files are in place before proceeding. * feat: enhance airgapped install script with domain input and OS compatibility - Added prompts for user input of installation directory and application domain/IP address. - Implemented OS-specific handling for `sed` commands to ensure compatibility across macOS and Linux. - Improved user experience with additional confirmation messages during installation. * feat: update installation script and versioning for airgapped deployment - Enhanced the installation script to prompt for confirmation when the setup directory is not empty, allowing users to proceed with caution. - Updated application version to v1.9.2 in both the docker-compose configuration and environment variables for consistency. - Improved final confirmation message for clarity during installation. * chore: airgapped upload license endpoint * feat: added endpoint for uploading file in airgapped mode * chore: file upload to handle formdata * feat: license activation using file upload * feat: add GitHub Actions workflow for building airgapped images - Introduced a new workflow to build airgapped images with customizable platform options. - Implemented steps for dependency installation, Docker setup, AWS credentials configuration, and environment preparation. - Enhanced docker-compose.yml processing to include airgapped-specific configurations and manage service volumes. - Added functionality to pull and save Docker images, and create a distribution tarball for S3 upload. * feat: enhance build script for airgapped deployment - Added support for customizable build platform and application release version through command-line flags. - Implemented usage instructions for the build script to guide users on required and optional parameters. - Improved handling of environment variable updates in docker-compose.yml and plane.env for different operating systems. - Included cleanup steps to remove temporary data and logs after the build process. * checking build * refactor: simplify Docker setup in GitHub Actions workflow - Removed redundant volume configuration for buildx cache in the build-branch-ee.yml workflow. * feat: enhance build process by installing yq if missing - Added a check in the GitHub Actions workflow to install yq if it is not already present, ensuring the build script can dynamically update docker-compose.yml. - Removed redundant directory creation in the build script, streamlining the volume mapping process. - Adjusted sed command handling for macOS and Linux to improve compatibility. * feat: update airgapped artifact packaging in GitHub Actions workflow - Modified the condition for packaging airgapped artifacts to include 'Release' build type. - Streamlined the setup of yq by using an action instead of manual installation. - Enhanced the build script to dynamically set the release version based on the build type, improving flexibility for different deployment scenarios. - Updated S3 upload path to include the artifact suffix for better organization. * feat: add AWS credentials to GitHub Actions workflow - Introduced environment variables for AWS access key and secret key in the build-branch-ee.yml workflow, enabling secure access to AWS resources during the build process. * fix: correct syntax for environment variable assignment in GitHub Actions workflow - Updated the assignment of environment variables in the build-branch-ee.yml workflow to use the correct syntax for string interpolation. - Ensured consistency in setting the AIRGAPPED_RELEASE_VERSION based on the build type condition. * feat: add AWS CLI installation step to GitHub Actions workflow - Introduced a step to install the AWS CLI in the build-branch-ee.yml workflow, ensuring necessary tools are available for AWS interactions. - Updated environment variable assignments for consistency and clarity in the packaging process of airgapped artifacts. * fix: streamline S3 upload command in GitHub Actions workflow - Simplified the S3 upload command in the build-branch-ee.yml workflow by removing unnecessary directory navigation, directly referencing the airgapped tarball for upload. - Improved clarity and efficiency in the artifact deployment process. * chore: comment out S3 upload command in GitHub Actions workflow - Commented out the S3 upload command in the build-branch-ee.yml workflow to prevent execution during the build process. - This change allows for easier testing and debugging of the artifact packaging without uploading to S3. * fix: correct syntax in GitHub Actions workflow for airgapped release version - Fixed the conditional syntax in the build-branch-ee.yml workflow to properly close the if statement. - Ensured the S3 upload command is correctly referenced, maintaining clarity in the artifact deployment process. * fix: install yq if not present in GitHub Actions workflow - Added a conditional check to install yq in the build-branch-ee.yml workflow if it is not already installed, ensuring the build process can proceed without errors related to missing dependencies. - This change enhances the reliability of the workflow by automating the installation of necessary tools. * fix: optimize Docker cleanup and S3 upload command in GitHub Actions workflow - Added Docker cleanup commands to remove unused images and prune the system, improving resource management during the build process. - Streamlined the S3 upload command to directly pipe the tarball, enhancing efficiency in artifact deployment. * fix: improve confirmation prompt in installation script - Added README.md contents - Updated the confirmation prompt in install.sh for clarity, changing "YES" to "Yes" to enhance user understanding during the installation process. * fix: update runner configuration for airgapped artifacts packaging in GitHub Actions workflow - Changed the runner from 'ubuntu-22.04' to 'ubuntu-22.04-4-cores' to optimize resource allocation during the packaging process of airgapped artifacts. - This adjustment aims to enhance performance and efficiency in the build workflow. * fix: update runner configuration for airgapped artifacts packaging in GitHub Actions workflow - Changed the runner from 'ubuntu-22.04-4-cores' to 'ubuntu-latest-4-cores' to ensure the use of the latest stable environment for improved compatibility and performance during the packaging process of airgapped artifacts. * fix: update runner configuration for airgapped artifacts packaging in GitHub Actions workflow - Changed the runner from 'ubuntu-latest-4-cores' back to 'ubuntu-22.04' to align with the previous configuration, ensuring compatibility and stability during the packaging process of airgapped artifacts. * fix: simplify yq installation in GitHub Actions workflow - Removed the conditional check for yq installation in the build-branch-ee.yml workflow, ensuring yq is always installed during the setup process. This change enhances the reliability of the workflow by eliminating potential errors related to missing dependencies. * refactor: reorganize build steps in GitHub Actions workflow - Restored and structured the build-push steps for various Docker images (admin, web, space, live, silo, apiserver, proxy, monitor, email) in the build-branch-ee.yml workflow. - Updated the dependencies for the packaging of airgapped artifacts to ensure all build steps are executed in the correct order. - Enhanced clarity and maintainability of the workflow by explicitly defining each build-push job. * fix: comment out hardcoded airgapped release version in GitHub Actions workflow - Commented out the hardcoded AIRGAPPED_RELEASE_VERSION in the build-branch-ee.yml workflow to allow for dynamic versioning based on the branch name, enhancing flexibility in the build process. * refactor: update image handling in airgapped build and install scripts - Modified build.sh to save each Docker image individually to a tar file and remove the image after saving, improving image management. - Updated install.sh to load multiple tar files instead of a single hardcoded tarball, enhancing flexibility in image loading during setup. * test build * enhance: add build summary and usage instructions for airgapped artifacts in GitHub Actions workflow - Introduced a build summary section in the build-branch-ee.yml workflow to provide details about the airgapped artifacts, including release version and S3 path. - Added usage instructions for downloading and installing the airgapped artifacts, improving user guidance and accessibility. * chore: remove deprecated build-airgapped workflow - Deleted the build-airgapped.yml workflow file as it is no longer needed. - Updated build-branch-ee.yml to streamline the packaging process for airgapped artifacts and improve S3 upload commands. * fix: update file handling for license activation to support JSON format - Changed file validation to accept only .json files in the frontend and backend. - Updated the API to read and forward the activation file correctly. - Enhanced error handling for unsupported file types and server responses. * enhance: improve build summary and usage instructions in GitHub Actions workflow - Added Git commit hash and branch information to the build summary in build-branch-ee.yml for better traceability. - Updated usage instructions formatting to enhance clarity and user experience when downloading and installing airgapped artifacts. * enhance: add presigned URL generation for airgapped artifacts in GitHub Actions workflow - Implemented the creation of a presigned URL for airgapped artifacts, allowing for secure access for 30 days. - Updated the build summary to include the presigned URL, improving user guidance for downloading artifacts. * style: improve formatting of usage instructions in GitHub Actions workflow - Updated the usage instructions in build-branch-ee.yml to use inline code formatting for better readability and clarity. - Enhanced user guidance for downloading and installing airgapped artifacts. * refactor: enhance build summary and usage instructions in GitHub Actions workflow - Improved the formatting of the build summary in build-branch-ee.yml for better readability. - Updated usage instructions to include code blocks, enhancing clarity for users downloading and installing airgapped artifacts. * fix: time format issue with RFC, added custom marshaller * feat: integrate crane for optimized image handling in airgapped build process - Added installation of crane in the GitHub Actions workflow to enhance image pulling and saving efficiency. - Updated build.sh to utilize crane for pulling images when available, providing a fallback to Docker if not. - Improved user feedback during image handling, ensuring clarity on the process and success of operations. * fix: update crane installation method in GitHub Actions workflow - Changed the crane installation command to download the tarball to a file before extraction, improving reliability and error handling during the installation process. * fix: streamline crane installation in GitHub Actions workflow - Updated the crane installation command to directly pipe the download into extraction, simplifying the process and reducing the need for intermediate files. * feat: add airgapped mode support for license file handling - Introduced a new setting to enable airgapped mode. - Added LicenseFileFetchEndpoint to fetch license files for workspaces in airgapped mode. - Enhanced LicenseDeActivateEndpoint to delete license files when in airgapped mode. - Updated LicenseActivateUploadEndpoint to restrict access based on airgapped mode. - Implemented S3Storage method for deleting files from S3. * fix: update environment variable formatting in GitHub Actions workflow - Changed the format of environment variable assignments in build-branch-ee.yml to use `key=value` syntax, improving clarity and consistency in the workflow. * fix: update airgapped artifact packaging in GitHub Actions workflow - Refactored the packaging step in build-branch-ee.yml to utilize environment variables for better clarity and maintainability. - Enhanced the presigned URL generation to extend the expiry to 90 days, improving access security for airgapped artifacts. * fix: refine AIRGAPPED_RELEASE_VERSION handling in GitHub Actions workflow - Updated the assignment of AIRGAPPED_RELEASE_VERSION to improve clarity and consistency in the build process. - Enhanced the build summary to reflect the changes in variable usage, ensuring accurate information is presented to users. - Streamlined the presigned URL handling for better integration within the workflow. * fix: update airgapped artifact workflow with environment variable enhancements - Refactored the build process in build-branch-ee.yml to utilize environment variables for AIRGAPPED_RELEASE_VERSION, S3_PATH, COMMIT_HASH, and PRESIGNED_URL, improving clarity and maintainability. - Enhanced the build summary to reflect the updated variable usage, ensuring accurate information is presented to users. - Streamlined the presigned URL handling and extended its expiry to 90 days for improved access security. * improvement: upload license file form UI * fix: enhance airgapped build summary in GitHub Actions workflow - Updated the build summary in build-branch-ee.yml to include a temporary file for the presigned URL, improving security and clarity. - Added the Git commit hash to the summary for better traceability of builds. - Streamlined the summary formatting for improved readability and user guidance. * fix: update airgapped artifact workflow to include presigned URL upload - Commented out the previous artifact packaging steps for airgapped builds to streamline the process. - Added functionality to create a temporary file for the presigned URL and upload it as an artifact, enhancing accessibility and security. - Improved clarity in the workflow by ensuring the presigned URL is logged and stored appropriately. * fix: reduce presigned URL expiry in airgapped artifact workflow - Updated the PRESIGNED_URL_EXPIRY from 90 days to 7 days to enhance security and limit access duration. - Commented out the previous expiry setting for clarity and future reference. * fix: enhance airgapped artifact workflow with S3 region support - Added S3_REGION environment variable to specify the AWS region for presigned URL generation, improving flexibility and accuracy in artifact handling. - Updated the presigned URL command to include the region parameter, ensuring correct URL generation for S3 access. - Modified the build summary to replace the presigned URL placeholder with a generic "<presigned-url>" for clarity in usage instructions. * fix: streamline airgapped artifact workflow by enabling packaging steps - Re-enabled the packaging steps for airgapped artifacts in the workflow, ensuring that the build process includes the creation and upload of artifacts to S3. - Clarified the presigned URL expiry comment to indicate it is set to the maximum allowed by AWS for improved understanding of security settings. * fix: enhance airgapped artifact workflow with multi-platform support - Added support for building and uploading airgapped artifacts for both amd64 and arm64 architectures in the GitHub Actions workflow. - Updated the S3 paths and presigned URL handling to accommodate the new architecture-specific artifacts. - Improved user guidance in the installation script by providing clearer instructions for starting services and checking logs. * fix: update airgapped artifact workflow to use consistent build platform flag - Changed the build platform flag from `--build-platform` to `--platform` in the airgapped artifact workflow for both amd64 and arm64 builds, ensuring consistency across the build commands. * chore: license activation changes * feat: added mock implemation of airgapped api * fix: enhance airgapped artifact workflow with detailed service images - Added specific Docker image references for various services in the airgapped installation README, improving clarity on required files for offline deployment. - Updated the workflow to ensure all necessary images are included for a comprehensive airgapped setup. * fix: cases for workspace replace and seats * fix: improve airgapped artifact workflow with conditional arm64 build support - Added conditional logic to build and package arm64 artifacts based on the AIRGAPPED_ARM64_BUILD environment variable, enhancing flexibility in the workflow. - Updated the presigned URL handling for arm64 artifacts to ensure proper access management. - Improved the build summary to include arm64 S3 path only when applicable, streamlining output clarity. * fix: update airgapped README to include email service Docker image - Added reference to the Docker image for the email service in the airgapped installation README, enhancing clarity on required files for offline deployment. * fix: add arm64 build support to airgapped artifact workflow - Introduced ARM64_BUILD environment variable to manage conditional logic for arm64 builds in the workflow. - Updated the build steps to set ARM64_BUILD based on the target branch, enhancing flexibility for multi-architecture support. * fix: refactored logic for license management * fix: ensure members_list is properly formatted as JSON in license activation * fix: verification threshold * feat: enhance airgapped license handling with versioning and improved error logging - Added `Version` field to `AirgappedLicensePayload` for better tracking. - Updated database population logic to use the new `Version` field. - Improved error handling in `GetManualSyncHandler` with additional logging for license and feature flag refresh failures. - Refined license deactivation logic for airgapped licenses based on current period end date. * chore: update workspace activation check * feat: improve airgapped handling in API views and tasks - Added checks for airgapped settings in `CheckUpdateEndpoint`, `version_check`, and `register_instance_ee` to return early if the environment is airgapped. - Enhanced code readability and maintainability by centralizing airgapped logic. * improvement: remove seat management and subscription management for airgapped workspaces * fix: update airgapped artifact workflow to extract tarball into specific directory - Modified the extraction command in the airgapped installation instructions to specify the target directory, improving organization and clarity for users during the installation process. * fix: update application version to v1.10.0 in deployment configurations - Updated the APP_VERSION in coolify-compose.yml, docker-compose-caddy.yml, portainer-compose.yml, and variables.env to reflect the new version v1.10.0, ensuring consistency across deployment files. * feat: enhance license activation response with workspace member details - Updated the LicenseFileFetchEndpoint to include a list of active workspace members in the response. - Converted user IDs to strings for consistency in the returned data structure. * feat: added sync endpoint for download file * feat: added logic for manual sync handler * feat: added private key to prime airgapped api * feat: implement job registration for instance license resync in airgapped mode - Added a new job to the worker for resyncing instance licenses using a context-aware handler. - Updated the HTTP handler port to "8090" for consistency. - Changed the airgapped check to always return true in the workspace product handler. * fix: update license activation response to return workspace members directly - Modified the LicenseFileFetchEndpoint to return the workspace members list directly instead of converting it to a list, ensuring the response structure is consistent with the expected data format. * feat: add command configuration for monitor service in airgapped build script - Updated the build script to include a command for the monitor service, setting it to ["prime-monitor", "start-airgapped"] when the service is detected. * docs: update airgapped README with installation instructions and prerequisites - Enhanced the prerequisites section for clarity on Docker and Docker Compose requirements. - Added a detailed installation process, including steps for running the installation script and the resulting directory structure. - Updated post-installation steps to guide users on starting services and monitoring logs. * improvement: handle error message for license activation * feat: enhance airgapped cron job scheduling - Introduced a new cron handler for scheduling airgapped cron jobs, including a License Refresh Job. - Updated the worker to register the new cron job for instance license resync. * minor fixes as sugged by reviewer * fix: update HTTP handler port to use dynamic PORT variable in airgapped command * fix: added version and api environment variables * chore: update handlers to use isAirgapped method * fix: converted db open calls to transactions in product handler * fix: ensure UUIDs are only generated for unset IDs in License, UserLicense, and Flags models * chore: update error message * fix: add API_HOSTNAME environment variable to deployment configurations - Introduced API_HOSTNAME variable in coolify-compose.yml, docker-compose-caddy.yml, portainer-compose.yml, and variables.env to standardize API endpoint configuration across deployment files. * fix: update API_HOSTNAME format in deployment configurations - Changed the API_HOSTNAME variable in coolify-compose.yml, docker-compose-caddy.yml, portainer-compose.yml, and variables.env to include the protocol (http://), ensuring consistent and correct API endpoint formatting across deployment files. * feat: enhance airgapped installation and configuration - Updated build.sh to insert "name: Plane-airgapped" into the docker-compose.yml file. - Modified install.sh to set a default installation directory, improve user prompts, and handle upgrades more gracefully. - Added checks for existing installations and running instances to prevent conflicts during upgrades. - Enhanced the configuration display for better user clarity during setup. * feat: improve environment variable handling in airgapped installation script - Added a new function to update environment variables in the plane.env file. - Enhanced the logic for reading and processing key-value pairs from the backup file, ensuring proper trimming and handling of empty values. - Streamlined the update process for environment variables during installation and upgrades. * feat: add Docker and docker-compose version checks in airgapped installation script - Implemented checks for Docker version to ensure it meets the minimum requirement. - Added validation to confirm that Docker is running before proceeding with installation. - Included checks for the presence of either docker-compose or the new docker compose command. - Enhanced error handling for version checks to improve user feedback during installation. --------- Co-authored-by: Thomas Taylor <twtaylor7@gmail.com> Co-authored-by: Manish Gupta <manish@plane.so> Co-authored-by: Henit Chobisa <chobisa.henit@gmail.com> Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com> Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com> Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com> Co-authored-by: akshat5302 <akshatjain9782@gmail.com>
542 lines
16 KiB
Go
542 lines
16 KiB
Go
package prime_api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
type IPrimeMonitorApi interface {
|
|
// Getters for the api
|
|
IsAirgapped() bool
|
|
AppVersion() string
|
|
ApiHostname() string
|
|
|
|
PostServiceStatus(StatusPayload) ErrorCode
|
|
GetFeatureFlags(licenseKey string) (*FlagDataResponse, *APIError)
|
|
ActivateInstance() *APIError
|
|
DeactivateInstance() *APIError
|
|
RetrievePlans(string) (*[]Product, *APIError)
|
|
RetrievePaymentLink(RetrievePaymentLinkPayload) (*RetrievePaymentLinkResponse, *APIError)
|
|
UpdateSubcription(SeatUpdatePayload) (*SeatUpdateResponse, *APIError)
|
|
SyncWorkspace(WorkspaceSyncPayload) (*WorkspaceActivationResponse, *APIError)
|
|
DeactivateLicense(LicenseDeactivatePayload) (*WorkspaceActivationResponse, *APIError)
|
|
ActivateWorkspace(WorkspaceActivationPayload) (*WorkspaceActivationResponse, *APIError)
|
|
ActivateFreeWorkspace(WorkspaceActivationPayload) (*WorkspaceActivationResponse, *APIError)
|
|
InitializeInstance(CredentialsPayload) (SetupResponse, *APIError)
|
|
GetSubscriptionDetails(WorkspaceSubscriptionPayload) (*WorkspaceSubscriptionResponse, *APIError)
|
|
GetProrationPreview(ProrationPreviewPayload) (*ProrationPreviewResponse, *APIError)
|
|
}
|
|
|
|
type LicenseDeactivatePayload struct {
|
|
WorkspaceSlug string `json:"workspace_slug"`
|
|
WorkspaceID string `json:"workspace_id"`
|
|
LicenseKey string `json:"license_key"`
|
|
}
|
|
|
|
type PrimeMonitorApi struct {
|
|
host string
|
|
instanceId string
|
|
appVersion string
|
|
client string
|
|
version string
|
|
machineSignature string
|
|
}
|
|
|
|
type CredentialsPayload struct {
|
|
ServerId string
|
|
Domain string
|
|
AppVersion string
|
|
}
|
|
|
|
type WorkspaceSubscriptionPayload struct {
|
|
WorkspaceId string `json:"workspace_id"`
|
|
LicenseKey string `json:"license_key"`
|
|
}
|
|
|
|
type WorkspaceSubscriptionResponse struct {
|
|
Product string `json:"product"`
|
|
CurrentPeriodEnd string `json:"current_period_end_date"`
|
|
SubscriptionExists bool `json:"subscription_exists"`
|
|
Url string `json:"url"`
|
|
}
|
|
|
|
type ProrationPreviewPayload struct {
|
|
WorkspaceId string `json:"workspace_id"`
|
|
Quantity int `json:"quantity"`
|
|
WorkspaceSlug string `json:"workspace_slug"`
|
|
LicenseKey string `json:"license_key"`
|
|
}
|
|
|
|
type ProrationPreviewResponse struct {
|
|
QuantityDifference int `json:"quantity_difference"`
|
|
PerSeatProrationAmount float64 `json:"per_seat_prorated_amount"`
|
|
NewQuantity int `json:"new_quantity"`
|
|
TotalProratedAmount float64 `json:"total_prorated_amount"`
|
|
CurrentQuantity int `json:"current_quantity"`
|
|
CurrentPriceAmount float64 `json:"current_price_amount"`
|
|
CurrentPriceInterval string `json:"current_price_interval"`
|
|
}
|
|
|
|
type SetupResponse struct {
|
|
Domain string `json:"domain"`
|
|
InstanceId string `json:"instance_id"`
|
|
Host string `json:"prime_host"`
|
|
Version string `json:"version"`
|
|
}
|
|
|
|
type FlagsPayload struct {
|
|
EncryptedData string `json:"encrypted_data"`
|
|
}
|
|
|
|
// Add this struct to handle the error response from the server
|
|
type ErrorResponse struct {
|
|
Message string `json:"message"`
|
|
Error string `json:"error"`
|
|
}
|
|
|
|
func NewMonitorApi(host, machineSignature, instanceId, appVersion string) IPrimeMonitorApi {
|
|
return &PrimeMonitorApi{
|
|
host: host,
|
|
instanceId: instanceId,
|
|
appVersion: appVersion,
|
|
client: "Prime-Monitor",
|
|
version: appVersion,
|
|
machineSignature: machineSignature,
|
|
}
|
|
}
|
|
|
|
// We don't need this for the normal api, but we need it for the airgapped api
|
|
func (api *PrimeMonitorApi) ApiHostname() string {
|
|
return ""
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) AppVersion() string {
|
|
return api.appVersion
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) IsAirgapped() bool {
|
|
return false
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) SetClient(client string) {
|
|
api.client = client
|
|
}
|
|
|
|
var (
|
|
API_PREFIX = "/api/v2"
|
|
MONITOR_ENDPOINT = API_PREFIX + "/monitor/"
|
|
FEATURE_FLAGS = API_PREFIX + "/flags/"
|
|
INSTANCE_PREFIX = API_PREFIX + "/instances"
|
|
ACTIVATE_INSTANCE = INSTANCE_PREFIX + "/activate/"
|
|
DEACTIVATE_INSTANCE = INSTANCE_PREFIX + "/deactivate/"
|
|
UPGRADE_INSTANCE = INSTANCE_PREFIX + "/upgrade/"
|
|
FREE_WORKSPACE_ACTIVATE = API_PREFIX + "/licenses/initialize/"
|
|
WORKSPACE_ACTIVATE = API_PREFIX + "/licenses/activate/"
|
|
SYNC_WORKSPACE = API_PREFIX + "/licenses/sync/"
|
|
UPDATE_SUBSCRIPTION = API_PREFIX + "/modify-subscriptions/"
|
|
SETUP_ENDPOINT = API_PREFIX + "/instances/initialize/"
|
|
SUBSCRIPTION_PORTAL = API_PREFIX + "/subscription-portal/"
|
|
RETRIEVE_PLANS = API_PREFIX + "/instances/products/"
|
|
RETRIEVE_PAYMENT_LINK = API_PREFIX + "/instances/payment-link/"
|
|
DEACTIVATE_LICENSE_ENDPOINT = API_PREFIX + "/licenses/deactivate/"
|
|
PRORATION_PREVIEW = API_PREFIX + "/subscriptions/proration-preview/"
|
|
)
|
|
|
|
/* ----------------------- Controller Methods ------------------------------ */
|
|
// Posts the status of the services given, to the prime server, returns error if
|
|
// hinderer, else doesn't return anything
|
|
func (api *PrimeMonitorApi) PostServiceStatus(payload StatusPayload) ErrorCode {
|
|
_, err := api.post(api.host+MONITOR_ENDPOINT, payload)
|
|
if err != nil {
|
|
return UNABLE_TO_POST_SERVICE_STATUS
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) DeactivateLicense(payload LicenseDeactivatePayload) (*WorkspaceActivationResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+DEACTIVATE_LICENSE_ENDPOINT, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := WorkspaceActivationResponse{}
|
|
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) ActivateFreeWorkspace(payload WorkspaceActivationPayload) (*WorkspaceActivationResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+FREE_WORKSPACE_ACTIVATE, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := WorkspaceActivationResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
// Activating a paid licensed workspace
|
|
func (api *PrimeMonitorApi) ActivateWorkspace(payload WorkspaceActivationPayload) (*WorkspaceActivationResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+WORKSPACE_ACTIVATE, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := WorkspaceActivationResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) GetFeatureFlags(licenseKey string) (*FlagDataResponse, *APIError) {
|
|
flagData, apiError := api.post(api.host+FEATURE_FLAGS, map[string]string{
|
|
"license_key": licenseKey,
|
|
"version": api.version,
|
|
})
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := FlagDataResponse{}
|
|
if err := json.Unmarshal(flagData, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) RetrievePlans(quantity string) (*[]Product, *APIError) {
|
|
resp, apiError := api.get(api.host+RETRIEVE_PLANS, map[string]string{
|
|
"quantity": quantity,
|
|
})
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := []Product{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) RetrievePaymentLink(payload RetrievePaymentLinkPayload) (*RetrievePaymentLinkResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+RETRIEVE_PAYMENT_LINK, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := RetrievePaymentLinkResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) SyncWorkspace(payload WorkspaceSyncPayload) (*WorkspaceActivationResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+SYNC_WORKSPACE, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
data := WorkspaceActivationResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) ActivateInstance() *APIError {
|
|
_, apiError := api.post(api.host+ACTIVATE_INSTANCE, nil)
|
|
if apiError != nil {
|
|
return apiError
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) DeactivateInstance() *APIError {
|
|
_, apiError := api.post(api.host+DEACTIVATE_INSTANCE, nil)
|
|
if apiError != nil {
|
|
return apiError
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) UpgradeInstance() *APIError {
|
|
_, apiError := api.post(api.host+UPGRADE_INSTANCE, nil)
|
|
if apiError != nil {
|
|
return apiError
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) UpdateSubcription(payload SeatUpdatePayload) (*SeatUpdateResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+UPDATE_SUBSCRIPTION, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
|
|
data := SeatUpdateResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) InitializeInstance(payload CredentialsPayload) (SetupResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+SETUP_ENDPOINT, map[string]string{
|
|
"machine_signature": payload.ServerId,
|
|
"domain": payload.Domain,
|
|
"app_version": payload.AppVersion,
|
|
"deploy_platform": "KUBERNETES",
|
|
})
|
|
|
|
if apiError != nil {
|
|
return SetupResponse{}, apiError
|
|
}
|
|
|
|
setupResponse := SetupResponse{}
|
|
if err := json.Unmarshal(resp, &setupResponse); err != nil {
|
|
return SetupResponse{}, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return setupResponse, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) GetSubscriptionDetails(payload WorkspaceSubscriptionPayload) (*WorkspaceSubscriptionResponse, *APIError) {
|
|
resp, apiError := api.post(api.host+SUBSCRIPTION_PORTAL, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
|
|
data := WorkspaceSubscriptionResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func (api *PrimeMonitorApi) GetProrationPreview(payload ProrationPreviewPayload) (*ProrationPreviewResponse, *APIError) {
|
|
// Make the request
|
|
resp, apiError := api.post(api.host+PRORATION_PREVIEW, payload)
|
|
if apiError != nil {
|
|
return nil, apiError
|
|
}
|
|
|
|
// Unmarshal the response
|
|
data := ProrationPreviewResponse{}
|
|
if err := json.Unmarshal(resp, &data); err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("Error unmarshaling response: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
// Return the response
|
|
return &data, nil
|
|
}
|
|
|
|
// ------------------------ Helper Methods ----------------------------------
|
|
/*
|
|
prepareRequest prepares an HTTP request with the necessary headers and parameters.
|
|
|
|
Parameters:
|
|
- method: string specifying the HTTP method (e.g., "GET", "POST").
|
|
- urlStr: string specifying the URL for the request.
|
|
- body: io.Reader containing the request body.
|
|
- params: map[string]string containing the query parameters.
|
|
|
|
Returns:
|
|
- *http.Request: The prepared HTTP request.
|
|
- error: An error if any occurs during the preparation.
|
|
*/
|
|
func (api *PrimeMonitorApi) prepareRequest(method, urlStr string, body io.Reader, params map[string]string) (*http.Request, error) {
|
|
if method == "GET" && params != nil {
|
|
parsedURL, err := url.Parse(urlStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error parsing URL: %v", err)
|
|
}
|
|
query := parsedURL.Query()
|
|
for key, value := range params {
|
|
query.Set(key, value)
|
|
}
|
|
parsedURL.RawQuery = query.Encode()
|
|
urlStr = parsedURL.String()
|
|
}
|
|
|
|
req, err := http.NewRequest(method, urlStr, body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error creating request: %v", err)
|
|
}
|
|
|
|
headers := map[string]string{
|
|
"X-Instance-Id": api.instanceId,
|
|
"X-Machine-Signature": api.machineSignature,
|
|
"X-Client": api.client,
|
|
"X-License-Version": api.version,
|
|
"Content-Type": "application/json",
|
|
}
|
|
|
|
for key, value := range headers {
|
|
req.Header.Add(key, value)
|
|
}
|
|
|
|
return req, nil
|
|
}
|
|
|
|
/*
|
|
doRequest executes the HTTP request and handles common response scenarios.
|
|
|
|
Parameters:
|
|
- req: *http.Request specifying the HTTP request to execute.
|
|
|
|
Returns:
|
|
- []byte: The response body.
|
|
- error: An error if any occurs during the request execution.
|
|
*/
|
|
func (api *PrimeMonitorApi) doRequest(req *http.Request) ([]byte, *APIError) {
|
|
client := &http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error making request: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
switch {
|
|
case resp.StatusCode >= 200 && resp.StatusCode <= 227:
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error reading response body: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return body, nil
|
|
case resp.StatusCode >= 300 && resp.StatusCode <= 308:
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error reading response body: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
return body, nil
|
|
case resp.StatusCode >= 400 && resp.StatusCode <= 451:
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error reading response body: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
|
|
// Try to parse the error response
|
|
var errorResp ErrorResponse
|
|
if err := json.Unmarshal(body, &errorResp); err != nil {
|
|
// If we can't parse the error, return the status code
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("unexpected status code %d", resp.StatusCode),
|
|
Success: false,
|
|
}
|
|
}
|
|
|
|
return nil, &APIError{
|
|
Error: errorResp.Error,
|
|
Success: false,
|
|
}
|
|
default:
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("unexpected status code: %v", resp.StatusCode),
|
|
Success: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
get performs a GET request.
|
|
|
|
Parameters:
|
|
- baseURL: string specifying the base URL for the request.
|
|
- params: map[string]string containing the query parameters.
|
|
|
|
Returns:
|
|
- []byte: The response body.
|
|
- error: An error if any occurs during the request.
|
|
*/
|
|
func (api *PrimeMonitorApi) get(baseURL string, params map[string]string) ([]byte, *APIError) {
|
|
req, err := api.prepareRequest("GET", baseURL, nil, params)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error preparing request: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
|
|
return api.doRequest(req)
|
|
}
|
|
|
|
/*
|
|
post performs a POST request with JSON body.
|
|
|
|
Parameters:
|
|
- baseURL: string specifying the base URL for the request.
|
|
- data: interface{} containing the data to be sent in the request body.
|
|
|
|
Returns:
|
|
- []byte: The response body.
|
|
- error: An error if any occurs during the request.
|
|
*/
|
|
func (api *PrimeMonitorApi) post(baseURL string, data interface{}) ([]byte, *APIError) {
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error marshaling data: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
|
|
req, err := api.prepareRequest("POST", baseURL, bytes.NewBuffer(jsonData), nil)
|
|
if err != nil {
|
|
return nil, &APIError{
|
|
Error: fmt.Sprintf("error preparing request: %v", err),
|
|
Success: false,
|
|
}
|
|
}
|
|
|
|
return api.doRequest(req)
|
|
}
|