From 60641390e998cf824911f992d282b5ccccdd2ea1 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 10 Apr 2024 10:09:05 +0200 Subject: [PATCH 01/11] first dataart api implementation --- openstack/dataarts/v1.1/cluster/Create.go | 109 +++++--- openstack/dataarts/v1.1/cluster/Delete.go | 30 ++- openstack/dataarts/v1.1/cluster/Get.go | 25 +- openstack/dataarts/v1.1/cluster/List.go | 20 ++ openstack/dataarts/v1.1/cluster/Restart.go | 54 +++- openstack/dataarts/v1.1/cluster/Start.go | 37 ++- openstack/dataarts/v1.1/cluster/Stop.go | 49 ++-- openstack/dataarts/v1.1/cluster/common.go | 28 ++ .../dataarts/v1.1/{job => factory}/Get.go | 2 +- .../v1.1/factory/connection/Create.go | 244 ++++++++++++++++++ .../dataarts/v1.1/factory/connection/Get.go | 25 ++ .../dataarts/v1.1/factory/connection/List.go | 26 ++ 12 files changed, 535 insertions(+), 114 deletions(-) create mode 100644 openstack/dataarts/v1.1/cluster/List.go create mode 100644 openstack/dataarts/v1.1/cluster/common.go rename openstack/dataarts/v1.1/{job => factory}/Get.go (98%) create mode 100644 openstack/dataarts/v1.1/factory/connection/Create.go create mode 100644 openstack/dataarts/v1.1/factory/connection/Get.go create mode 100644 openstack/dataarts/v1.1/factory/connection/List.go diff --git a/openstack/dataarts/v1.1/cluster/Create.go b/openstack/dataarts/v1.1/cluster/Create.go index 5bc6b6cb4..d18b05ade 100644 --- a/openstack/dataarts/v1.1/cluster/Create.go +++ b/openstack/dataarts/v1.1/cluster/Create.go @@ -1,8 +1,6 @@ package cluster import ( - "net/http" - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/build" "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" @@ -10,62 +8,97 @@ import ( ) type CreateOpts struct { - Cluster Cluster `json:"cluster" required:"true"` - AutoRemind *bool `json:"auto_remind,omitempty"` - PhoneNum string `json:"phone_num,omitempty"` - Email string `json:"email,omitempty"` + Cluster Cluster `json:"cluster" required:"true"` + // AutoRemind Whether to enable message notification. + // If you enable this function, you can configure a maximum of five mobile numbers or email addresses. + // You will be notified of table/file migration job failures and EIP exceptions by SMS message or email. + AutoRemind bool `json:"auto_remind,omitempty"` + // PhoneNum Mobile number for receiving notifications. + PhoneNum string `json:"phone_num,omitempty"` + // Email address for receiving notifications. + Email string `json:"email,omitempty"` } type Cluster struct { - ScheduleBootTime string `json:"scheduleBootTime,omitempty"` - IsScheduleBootOff *bool `json:"isScheduleBootOff,omitempty"` - Instances []Instance `json:"instances,omitempty"` - DataStore *Datastore `json:"datastore,omitempty"` - ExtendedProperties *ExtendedProp `json:"extended_properties,omitempty"` - ScheduleOffTime string `json:"scheduleOffTime,omitempty"` - VpcId string `json:"vpcId,omitempty"` - Name string `json:"name,omitempty"` - SysTags []tag.ResourceTag `json:"sys_tags,omitempty"` - IsAutoOff *bool `json:"isAutoOff"` + // ScheduleBootTime Time for scheduled startup of a CDM cluster. The CDM cluster starts at this time every day. + ScheduleBootTime string `json:"scheduleBootTime,omitempty"` + // IsScheduleBootOff Whether to enable scheduled startup/shutdown. The scheduled startup/shutdown and auto shutdown functions cannot be enabled at the same time. + IsScheduleBootOff *bool `json:"isScheduleBootOff,omitempty"` + // Instances Node list. + Instances []Instance `json:"instances,omitempty"` + // DataStore Cluster information. + DataStore *Datastore `json:"datastore,omitempty"` + // ExtendedProperties Extended attribute. + ExtendedProperties *ExtendedProp `json:"extended_properties,omitempty"` + // ScheduleOffTime Time for scheduled shutdown of a CDM cluster. The CDM cluster shuts down directly at this time every day without waiting for unfinished jobs to complete. + ScheduleOffTime string `json:"scheduleOffTime,omitempty"` + // VpcId VPC ID, which is used for configuring a network for the cluster. + VpcId string `json:"vpcId,omitempty"` + // Name Cluster name. + Name string `json:"name,omitempty"` + // SysTags Enterprise project information. For details, see the descriptions of sys_tags parameters. + SysTags []tag.ResourceTag `json:"sys_tags,omitempty"` + // IsAutoOff Whether to enable auto shutdown. The auto shutdown and scheduled startup/shutdown functions cannot be enabled at the same time. + // When auto shutdown is enabled, if no job is running in the cluster and no scheduled job is available, a cluster will be automatically shut down 15 minutes after it starts running, which reduces costs for you. + IsAutoOff bool `json:"isAutoOff,omitempty"` } type Instance struct { - AZ string `json:"availability_zone" required:"true"` - Nics []Nic `json:"nics" required:"true"` + // AZ availability zone where a cluster is located. + AZ string `json:"availability_zone" required:"true"` + // Nics NIC list. A maximum of two NICs are supported. For details, see the descriptions of nics parameters. + Nics []Nic `json:"nics" required:"true"` + // FlavorRef Instance flavor. FlavorRef string `json:"flavorRef" required:"true"` - Type string `json:"type" required:"true"` + // Type Node type. Currently, only cdm is available. + Type string `json:"type" required:"true"` +} + +type Nic struct { + // SecurityGroupId Security group ID. + SecurityGroupId string `json:"securityGroupId" required:"true"` + // NetId Subnet ID. + NetId string `json:"net-id" required:"true"` } type Datastore struct { - Type string `json:"type,omitempty"` + // Type Generally, the value is cdm. + Type string `json:"type,omitempty"` + // Version Cluster version. Version string `json:"version,omitempty"` } type ExtendedProp struct { + // WorkSpaceId Workspace ID. WorkSpaceId string `json:"workSpaceId,omitempty"` - ResourceId string `json:"resourceId,omitempty"` - Trial string `json:"trial,omitempty"` + // ResourceId Resource ID. + ResourceId string `json:"resourceId,omitempty"` + // Trial Whether the cluster is a trial cluster. + Trial string `json:"trial,omitempty"` } -type Nic struct { - SecurityGroupId string `json:"securityGroupId" required:"true"` - NetId string `json:"net-id" required:"true"` -} - -func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*ClusterResponse, error) { +// Create is used to create a cluster. +// Send request POST /v1.1/{project_id}/clusters +func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*ClusterResp, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - // POST /v1.1/{project_id}/clusters raw, err := client.Post(client.ServiceURL("clusters"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, }) - return extra(err, raw) + + if err != nil { + return nil, err + } + + var res *ClusterResp + err = extract.Into(raw.Body, res) + return res, err } -type ClusterResponse struct { +type ClusterResp struct { Name string `json:"name"` Id string `json:"id"` Task Task `json:"task"` @@ -79,18 +112,8 @@ type Task struct { } type InstanceResp struct { - Name string `json:"name"` Id string `json:"id"` + Name string `json:"name"` Type string `json:"type"` ShardId string `json:"shard_id"` } - -func extra(err error, raw *http.Response) (*ClusterResponse, error) { - if err != nil { - return nil, err - } - - var res ClusterResponse - err = extract.Into(raw.Body, &res) - return &res, err -} diff --git a/openstack/dataarts/v1.1/cluster/Delete.go b/openstack/dataarts/v1.1/cluster/Delete.go index b1925a8d0..8a61c27cc 100644 --- a/openstack/dataarts/v1.1/cluster/Delete.go +++ b/openstack/dataarts/v1.1/cluster/Delete.go @@ -1,12 +1,28 @@ package cluster -import "github.com/opentelekomcloud/gophertelekomcloud" +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) -func Delete(client *golangsdk.ServiceClient, id string) (err error) { - // DELETE /v1.1/{project_id}/clusters/{cluster_id} - type KeepBackup struct { - KeepBackup int `json:"keep_last_manual_backup"` +type DeleteOpts struct { + // KeepBackup Number of backup log files. Retain the default value 0. + KeepBackup int `json:"keep_last_manual_backup"` +} + +// Delete is used to create a cluster. +// Send request DELETE /v1.1/{project_id}/clusters/{cluster_id} +func Delete(client *golangsdk.ServiceClient, id string, jsonOpts DeleteOpts) (*JobId, error) { + b, err := build.RequestBody(jsonOpts, "") + if err != nil { + return nil, err } - _, err = client.DeleteWithBody(client.ServiceURL("clusters", id), KeepBackup{KeepBackup: 0}, nil) - return + + r, err := client.DeleteWithBody(client.ServiceURL("clusters", id), b, nil) + + var resp *JobId + err = extract.Into(r.Body, resp) + + return resp, err } diff --git a/openstack/dataarts/v1.1/cluster/Get.go b/openstack/dataarts/v1.1/cluster/Get.go index ad33eb6ae..3565ba845 100644 --- a/openstack/dataarts/v1.1/cluster/Get.go +++ b/openstack/dataarts/v1.1/cluster/Get.go @@ -1,30 +1,25 @@ package cluster import ( - "net/http" - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" ) +// Get is used to query cluster details. +// Send request GET /v1.1/{project_id}/clusters/{cluster_id} func Get(client *golangsdk.ServiceClient, clusterId string) (*ClusterQuery, error) { - // GET /v1.1/{project_id}/clusters/{cluster_id} raw, err := client.Get(client.ServiceURL("clusters", clusterId), nil, nil) - return extraResp(err, raw) -} - -func extraResp(err error, raw *http.Response) (*ClusterQuery, error) { if err != nil { return nil, err } - var res ClusterQuery - err = extract.Into(raw.Body, &res) - return &res, err + var res *ClusterQuery + err = extract.Into(raw.Body, res) + return res, err } type ClusterQuery struct { - PublicEndpoint string `json:"public_endpoint"` + PublicEndpoint string `json:"publicEndpoint"` Instances []DetailedInstances `json:"instances"` SecurityGroupId string `json:"security_group_id"` SubnetId string `json:"subnet_id"` @@ -66,9 +61,9 @@ type DetailedInstances struct { Volume Volume `json:"volume"` Status string `json:"status"` Actions []string `json:"actions"` - Type string `json:"string"` - Name string `json:"name"` + Type string `json:"type"` Id string `json:"id"` + Name string `json:"name"` IsFrozen string `json:"isFrozen"` Components string `json:"components"` ConfigStatus string `json:"config_status"` @@ -115,7 +110,7 @@ type CustomerConfig struct { } type MaintainWindow struct { - Dat string `json:"day"` + Day string `json:"day"` StartTime string `json:"startTime"` EndTime string `json:"endTime"` } @@ -130,8 +125,8 @@ type FailedReasons struct { } type CreateFailed struct { - ErrorMsg string `json:"errorMsg"` ErrorCode string `json:"errorCode"` + ErrorMsg string `json:"errorMsg"` } type ClusterLinks struct { diff --git a/openstack/dataarts/v1.1/cluster/List.go b/openstack/dataarts/v1.1/cluster/List.go new file mode 100644 index 000000000..684d6ee70 --- /dev/null +++ b/openstack/dataarts/v1.1/cluster/List.go @@ -0,0 +1,20 @@ +package cluster + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// List Querying the Cluster List. +// Send request GET /v1.1/{project_id}/clusters +func List(client *golangsdk.ServiceClient) ([]*ClusterQuery, error) { + + raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) + if err != nil { + return nil, err + } + + var res []*ClusterQuery + err = extract.IntoSlicePtr(raw.Body, &res, "clusters") + return res, err +} diff --git a/openstack/dataarts/v1.1/cluster/Restart.go b/openstack/dataarts/v1.1/cluster/Restart.go index 47fc3e593..4454e404c 100644 --- a/openstack/dataarts/v1.1/cluster/Restart.go +++ b/openstack/dataarts/v1.1/cluster/Restart.go @@ -5,28 +5,58 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud/internal/build" ) +const ( + RestartImmediately = "IMMEDIATELY" + RestartForcely = "FORCELY" + RestartSoftly = "SOFTLY" +) + type RestartOpts struct { - Id string `json:"-"` + // Restart Cluster restart. For details about how to define the cluster to restart, see RestartStruct. Restart RestartStruct `json:"restart" required:"true"` } type RestartStruct struct { - StopMode int `json:"restartDelayTime,omitempty"` - RestartMode string `json:"restartMode,omitempty"` + // RestartDelayTime Restart delay, in seconds. + RestartDelayTime int `json:"restartDelayTime,omitempty"` + // Restart mode + // IMMEDIATELY: immediate restart + // FORCELY: forcible restart + // SOFTLY: common restart + // The default value is IMMEDIATELY. Forcibly restarting the service process will interrupt the service process and restart the VMs in the cluster. + RestartMode string `json:"restartMode,omitempty"` + // RestartLevel Restart level + // SERVICE: service restart + // VM: VM restart + // The default value is SERVICE. RestartLevel string `json:"restartLevel,omitempty"` - Type string `json:"type,omitempty"` - Instance string `json:"instance,omitempty"` - Group string `json:"group,omitempty"` + // Type Type of the cluster to be restarted. The value can be set to cdm only. + Type string `json:"type,omitempty"` + // Instance Reserved field. When restartLevel is set to SERVICE, this parameter is mandatory and an empty string should be entered. + Instance string `json:"instance,omitempty"` + // Reserved field. When restartLevel is set to SERVICE, this parameter is mandatory and an empty string should be entered. + Group string `json:"group,omitempty"` } -func Restart(client *golangsdk.ServiceClient, opts RestartOpts) (*JobId, error) { +// Restart is used to restart a cluster. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/action +func Restart(client *golangsdk.ServiceClient, clusterId string, opts RestartOpts) (*JobId, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - // POST /v1.1/{project_id}/clusters/{cluster_id}/action - raw, err := client.Post(client.ServiceURL("clusters", opts.Id, "action"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, - }) - return extraJob(err, raw) + + resp, err := client.Post( + client.ServiceURL("clusters", clusterId, "action"), + b, + nil, + &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + }, + ) + if err != nil { + return nil, err + } + + return respToJobId(resp) } diff --git a/openstack/dataarts/v1.1/cluster/Start.go b/openstack/dataarts/v1.1/cluster/Start.go index 3088d1082..d5db22590 100644 --- a/openstack/dataarts/v1.1/cluster/Start.go +++ b/openstack/dataarts/v1.1/cluster/Start.go @@ -2,20 +2,35 @@ package cluster import ( golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" ) -func Start(client *golangsdk.ServiceClient, id string) (*JobId, error) { - type Start struct { - Start *EmptyObj `json:"start"` +type StartOpts struct { + // Start Starting a cluster. This parameter is an empty object. + Start *EmptyStruct `json:"start"` +} + +type EmptyStruct struct{} + +// Start is used to start a cluster. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/action +func Start(client *golangsdk.ServiceClient, clusterId string, startOpts *StartOpts) (*JobId, error) { + b, err := build.RequestBody(startOpts, "") + if err != nil { + return nil, err } - // POST /v1.1/{project_id}/clusters/{cluster_id}/action - raw, err := client.Post(client.ServiceURL("clusters", id, "action"), Start{}, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, - }) - return extraJob(err, raw) -} + resp, err := client.Post( + client.ServiceURL("clusters", clusterId, "action"), + b, + nil, + &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + }, + ) + if err != nil { + return nil, err + } -type EmptyObj struct { - Obj *string `json:"-"` + return respToJobId(resp) } diff --git a/openstack/dataarts/v1.1/cluster/Stop.go b/openstack/dataarts/v1.1/cluster/Stop.go index 14d889add..420c674e6 100644 --- a/openstack/dataarts/v1.1/cluster/Stop.go +++ b/openstack/dataarts/v1.1/cluster/Stop.go @@ -1,45 +1,44 @@ package cluster import ( - "net/http" - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/build" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + StopImmediately = "IMMEDIATELY" + StopGracefully = "GRACEFULLY" ) type StopOpts struct { - Id string `json:"-"` + // Stop Cluster stop operation, which defines the parameters for stopping a cluster. Stop StopStruct `json:"stop" required:"true"` } type StopStruct struct { - StopMode string `json:"stopMode,omitempty"` - DelayTime string `json:"delayTime,omitempty"` + // StopMode should be StopImmediately or StopGracefully + StopMode string `json:"stopMode,omitempty"` + // DelayTime Stop delay, in seconds. + // This parameter is valid only when stopMode is set to GRACEFULLY. + // If the value of this parameter is set to -1, the system waits for all jobs to complete and stops accepting new jobs. + // If the value of this parameter is greater than 0, the system stops the cluster after the specified time and stops accepting new jobs. + DelayTime int `json:"delayTime,omitempty"` } -func Stop(client *golangsdk.ServiceClient, opts StopOpts) (*JobId, error) { +// Stop is used to stop a cluster. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/action +func Stop(client *golangsdk.ServiceClient, clusterId string, opts StopOpts) (*JobId, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - // POST /v1.1/{project_id}/clusters/{cluster_id}/action - raw, err := client.Post(client.ServiceURL("clusters", opts.Id, "action"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, - }) - return extraJob(err, raw) -} - -type JobId struct { - JobId []string `json:"jobId"` -} - -func extraJob(err error, raw *http.Response) (*JobId, error) { - if err != nil { - return nil, err - } - var res JobId - err = extract.Into(raw.Body, &res) - return &res, err + raw, err := client.Post( + client.ServiceURL("clusters", clusterId, "action"), + b, + nil, + &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + }) + return respToJobId(raw) } diff --git a/openstack/dataarts/v1.1/cluster/common.go b/openstack/dataarts/v1.1/cluster/common.go new file mode 100644 index 000000000..e71320562 --- /dev/null +++ b/openstack/dataarts/v1.1/cluster/common.go @@ -0,0 +1,28 @@ +package cluster + +import ( + "net/http" + + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + HeaderXLanguage = "X-Language" + RequestedLang = "en" +) + +type JobId struct { + JobId string `json:"jobId"` +} + +func respToJobId(r *http.Response) (*JobId, error) { + var res *JobId + err := extract.Into(r.Body, res) + return res, err +} + +func respToJobIdSlice(r *http.Response) (*JobId, error) { + var res *JobId + err := extract.Into(r.Body, res) + return res, err +} diff --git a/openstack/dataarts/v1.1/job/Get.go b/openstack/dataarts/v1.1/factory/Get.go similarity index 98% rename from openstack/dataarts/v1.1/job/Get.go rename to openstack/dataarts/v1.1/factory/Get.go index a4daa1d53..ff09f6368 100644 --- a/openstack/dataarts/v1.1/job/Get.go +++ b/openstack/dataarts/v1.1/factory/Get.go @@ -1,4 +1,4 @@ -package job +package factory import ( "github.com/opentelekomcloud/gophertelekomcloud" diff --git a/openstack/dataarts/v1.1/factory/connection/Create.go b/openstack/dataarts/v1.1/factory/connection/Create.go new file mode 100644 index 000000000..dbc281142 --- /dev/null +++ b/openstack/dataarts/v1.1/factory/connection/Create.go @@ -0,0 +1,244 @@ +package connection + +import ( + "encoding/json" + "fmt" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + TypeDWS = "DWS" + TypeDLI = "DLI" + TypeSparkSQL = "SparkSQL" + TypeHive = "HIVE" + TypeRDS = "RDS" + TypeCloudTable = "CloudTable" + TypeHOST = "HOST" +) + +const ( + MethodAgent = "agent" + MethodDirect = "direct" +) + +const HeaderWorkspace = "workspace" + +type Config struct { + // Connection name. The name contains a maximum of 100 characters, including only letters, numbers, hyphens (-), and underscores (_). + // The connection name must be unique. + Name string `json:"name" required:"true"` + // Connection type. Should be one of: DWS, DLI, SparkSQL, HIVE, RDS, CloudTable, HOST. + Type string `json:"type" required:"true"` + // Connection configuration item. The configuration item varies with the connection type. + // You do not need to set the config parameter for DLI connections. + // For other types of connections, see the description of connection configuration items. + Config interface{} `json:"config,omitempty"` + // Description of the connection. The description contains a maximum of 255 characters. + Description string `json:"description,omitempty"` +} + +func (c *Config) UnmarshalJSON(data []byte) error { + var obj map[string]json.RawMessage + + if err := json.Unmarshal(data, &obj); err != nil { + return err + } + + n, ok := obj["name"] + if !ok { + return fmt.Errorf("missed field in json, field: name") + } + + if err := json.Unmarshal(n, &c.Name); err != nil { + return err + } + + t, ok := obj["type"] + if !ok { + return fmt.Errorf("missed field in json, field: type") + } + + if err := json.Unmarshal(t, &c.Type); err != nil { + return err + } + + if d, ok := obj["description"]; ok { + if err := json.Unmarshal(d, &c.Description); err != nil { + return err + } + } + + switch c.Type { + case TypeDWS: + d := &DWSConfig{} + if err := json.Unmarshal(obj["config"], d); err != nil { + return err + } + c.Config = *d + case TypeDLI: + // There aren't any configurations for DLI type. + return nil + case TypeSparkSQL: + s := &SparkConfig{} + if err := json.Unmarshal(obj["config"], s); err != nil { + return err + } + c.Config = *s + case TypeHive: + h := &HiveConfig{} + if err := json.Unmarshal(obj["config"], h); err != nil { + return err + } + c.Config = *h + case TypeRDS: + r := &RDSConfig{} + if err := json.Unmarshal(obj["config"], r); err != nil { + return err + } + c.Config = *r + case TypeCloudTable: + ct := &CloudTableConfig{} + if err := json.Unmarshal(obj["config"], ct); err != nil { + return err + } + c.Config = *ct + case TypeHOST: + h := &HOSTConfig{} + if err := json.Unmarshal(obj["config"], h); err != nil { + return err + } + c.Config = *h + default: + return fmt.Errorf("connection type is not supported") + } + + return nil +} + +type DWSConfig struct { + // Name of a DWS cluster. + ClusterName string `json:"clusterName,omitempty"` + // IP address for accessing the DWS cluster. + IP string `json:"ip,omitempty"` + // Port for accessing the DWS cluster. + Port string `json:"port,omitempty"` + // Username of the database. This username is the username entered during the creation of the DWS cluster. + Username string `json:"userName" required:"true"` + // Password for accessing the database. This password is the password entered during the creation of the DWS cluster. + Password string `json:"password" required:"true"` + // Specifies whether to enable the SSL connection. + SSLEnable bool `json:"sslEnable" required:"true"` + // Name of a KMS key. + KMSKey string `json:"kmsKey" required:"true"` + // Name of a CDM cluster. + AgentName string `json:"agentName" required:"true"` +} + +type SparkConfig struct { + // Name of an MRS cluster. + ClusterName string `json:"clusterName" required:"true"` + // Method to connect. + // agent: connected through an agent. + // direct: connected directly. + ConnectionMethod string `json:"connectionMethod" required:"true"` + // Username of the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Username string `json:"userName,omitempty"` + // Password for accessing the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Password string `json:"password,omitempty"` + // Name of a CDM cluster. This parameter is mandatory when connectionMethod is set to agent. + AgentName string `json:"agentName,omitempty"` + // Name of a KMS key. This parameter is mandatory when connectionMethod is set to agent. + KMSKey string `json:"kmsKey,omitempty"` +} + +type HiveConfig struct { + // Name of an MRS cluster. + ClusterName string `json:"clusterName" required:"true"` + // Method to connect. + // agent: connected through an agent. + // direct: connected directly. + ConnectionMethod string `json:"connectionMethod" required:"true"` + // Username of the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Username string `json:"userName,omitempty"` + // Password for accessing the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Password string `json:"password,omitempty"` + // Name of a CDM cluster. This parameter is mandatory when connectionMethod is set to agent. + AgentName string `json:"agentName,omitempty"` + // Name of a KMS key. This parameter is mandatory when connectionMethod is set to agent. + KMSKey string `json:"kmsKey,omitempty"` +} + +type RDSConfig struct { + // Address for accessing RDS. + IP string `json:"ip" required:"true"` + // Port for accessing RDS. + Port string `json:"port" required:"true"` + // Username of the database. This username is the username entered during the creation of the cluster. + Username string `json:"userName" required:"true"` + // Password for accessing the database. This password is the password entered during the creation of the cluster. + Password string `json:"password" required:"true"` + // Name of a CDM cluster. + AgentName string `json:"agentName" required:"true"` + // Name of a KMS key. + KMSKey string `json:"kmsKey" required:"true"` + // Name of the driver. + DriverName string `json:"driverName" required:"true"` + // Path of the driver on OBS. + DriverPath string `json:"driverPath" required:"true"` +} + +type CloudTableConfig struct { + // Name of a CloudTable cluster. + ClusterName string `json:"clusterName" required:"true"` +} + +type HOSTConfig struct { + // IP address of the host. + IP string `json:"ip" required:"true"` + // SSH port number of the host. + Port string `json:"port" required:"true"` + // Username for logging in to the host. + Username string `json:"userName" required:"true"` + // Password for logging in to the host. + Password string `json:"password" required:"true"` + // Name of a CDM cluster. + AgentName string `json:"agentName" required:"true"` + // Name of a KMS key. + KMSKey string `json:"kmsKey" required:"true"` +} + +// Create is used to create a connection. The supported connection types include DWS, DLI, Spark SQL, RDS, CloudTable, and Hive. +// Send request /v1/{project_id}/connections +func Create(client *golangsdk.ServiceClient, opts Config, workspace string) (*CreateResp, error) { + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + var reqOpts *golangsdk.RequestOpts + if workspace != "" { + reqOpts = &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderWorkspace: workspace}, + } + } + + raw, err := client.Post(client.ServiceURL("connections"), b, nil, reqOpts) + + if err != nil { + return nil, err + } + + var res *CreateResp + err = extract.Into(raw.Body, res) + return res, err +} + +type CreateResp struct { + // Error code + ErrorCode string `json:"error_code,omitempty"` + // Error message + ErrorMsg string `json:"error_msg,omitempty"` +} diff --git a/openstack/dataarts/v1.1/factory/connection/Get.go b/openstack/dataarts/v1.1/factory/connection/Get.go new file mode 100644 index 000000000..6428d49fc --- /dev/null +++ b/openstack/dataarts/v1.1/factory/connection/Get.go @@ -0,0 +1,25 @@ +package connection + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// Get is used to query configuration details of a specific connection. +// Send request GET /v1/{project_id}/connections/{connection_name} +func Get(client *golangsdk.ServiceClient, connectionName string, workspace string) (*Config, error) { + var opts *golangsdk.RequestOpts + if workspace != "" { + opts = &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderWorkspace: workspace}, + } + } + raw, err := client.Get(client.ServiceURL("clusters", connectionName), nil, opts) + if err != nil { + return nil, err + } + + var res *Config + err = extract.Into(raw.Body, res) + return res, err +} diff --git a/openstack/dataarts/v1.1/factory/connection/List.go b/openstack/dataarts/v1.1/factory/connection/List.go new file mode 100644 index 000000000..d02fa4fa6 --- /dev/null +++ b/openstack/dataarts/v1.1/factory/connection/List.go @@ -0,0 +1,26 @@ +package connection + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + URLParamOffset = "offset" + URLParamLimit = "limit" + URLParamConnectionName = "connectionName" +) + +// List is used to query a connection list. +// Send request GET /v1/{project_id}/connections?offset={offset}&limit={limit}&connectionName={connectionName} +func List(client *golangsdk.ServiceClient, urlParams map[string]string) ([]*Config, error) { + + raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) + if err != nil { + return nil, err + } + + var res []*Config + err = extract.IntoSlicePtr(raw.Body, &res, "clusters") + return res, err +} From 34d0b5ca1faccb49b636b1e811f6424a7702e469 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 10 Apr 2024 14:26:39 +0200 Subject: [PATCH 02/11] small refactoring --- openstack/evs/v1/snapshots/list.go | 4 +- params.go | 55 ++++++++++++++ params_test.go | 118 +++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 params_test.go diff --git a/openstack/evs/v1/snapshots/list.go b/openstack/evs/v1/snapshots/list.go index eee3903df..7819e54bc 100644 --- a/openstack/evs/v1/snapshots/list.go +++ b/openstack/evs/v1/snapshots/list.go @@ -12,12 +12,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Snapshot, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("snapshots").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("snapshots")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/params.go b/params.go index ac8bee257..93fa2b0ce 100644 --- a/params.go +++ b/params.go @@ -376,6 +376,61 @@ func BuildQueryString(opts interface{}) (*url.URL, error) { return nil, fmt.Errorf("options type is not a struct") } +type URL struct { + u *url.URL +} + +func (u *URL) String() string { + return u.u.String() +} + +type URLBuilder struct { + endpoints []string + params interface{} +} + +func (ub *URLBuilder) WithEndpoints(endpoints ...string) *URLBuilder { + ub.endpoints = endpoints + return ub +} + +func (ub *URLBuilder) WithQueryParams(params interface{}) *URLBuilder { + ub.params = params + return ub +} + +func (ub *URLBuilder) Build() (*URL, error) { + var u url.URL + + if ub.params != nil { + u1, err := BuildQueryString(ub.params) + + if err != nil { + return nil, err + } + + u = *u1 + } + + for _, e := range ub.endpoints { + if strings.ContainsAny(e, "/!?$#=&+_") { + return nil, fmt.Errorf("characters '/!?$#=&+_\"' are not possible in endpoints") + } + } + + u.Path = strings.Join(ub.endpoints, "/") + + if _, err := url.Parse(u.String()); err != nil { + return nil, err + } + + return &URL{u: &u}, nil +} + +func NewURLBuilder() *URLBuilder { + return &URLBuilder{} +} + /* BuildHeaders is an internal function to be used by request methods in individual resource packages. diff --git a/params_test.go b/params_test.go new file mode 100644 index 000000000..8d4ae0374 --- /dev/null +++ b/params_test.go @@ -0,0 +1,118 @@ +package golangsdk + +import ( + "net/url" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBuildURL(t *testing.T) { + type testCase struct { + Name string + isFail bool + Endpoints []string + QueryParams interface{} + } + + type network struct { + Name string `q:"display_name"` + Status string `q:"status"` + NetworkID string `q:"network_id"` + } + + type empty struct{} + + type withoutTags struct { + Name string + } + + cases := []testCase{ + { + Name: "positive case without query parameters", + Endpoints: []string{"servers"}, + QueryParams: nil, + }, + { + Name: "positive case with query parameters", + Endpoints: []string{"servers", "network"}, + QueryParams: &network{ + Name: "network_name", + Status: "active", + NetworkID: "7bf9e4a9-fab1-4415-a6f7-ff7284ee1870", + }, + }, + { + Name: "positive case with empty struct, without query parameters", + Endpoints: []string{"servers", "network"}, + QueryParams: &empty{}, + }, + { + Name: "positive case with struct without query tags", + Endpoints: []string{"servers", "network"}, + QueryParams: &withoutTags{Name: "anyname"}, + }, + { + Name: "negative case with slash '/' in the endpoint name", + isFail: true, + Endpoints: []string{"servers/"}, + }, + { + Name: "negative case with slash '/' in the second endpoint name", + isFail: true, + Endpoints: []string{"servers", "/asdf/"}, + QueryParams: nil, + }, + { + Name: "negative case with characters ' /!?$#=&+_\"' ' in the second endpoint name", + isFail: true, + Endpoints: []string{"servers", "/!?$#=&+_\"'"}, + QueryParams: nil, + }, + { + Name: "negative case then query params is not a struct", + isFail: true, + Endpoints: []string{"servers", "network"}, + QueryParams: "anystring", + }, + } + + for _, c := range cases { + t.Log("starting test case:", c.Name) + u, err := NewURLBuilder().WithEndpoints(c.Endpoints...).WithQueryParams(c.QueryParams).Build() + + if c.isFail { + assert.Error(t, err) + continue + } + + assert.NoError(t, err) + + uObj, err := url.Parse(u.String()) + assert.NoError(t, err) + + assert.Equal(t, strings.Join(c.Endpoints, "/"), uObj.Path) + + if c.QueryParams == nil { + continue + } + + if c.Name == "positive case with struct without query tags" || + c.Name == "positive case with empty struct, without query parameters" { + q := uObj.Query() + assert.Equal(t, 0, len(q)) + continue + } + + assert.Equal(t, true, uObj.Query().Has("display_name")) + assert.Equal(t, "network_name", uObj.Query().Get("display_name")) + + assert.Equal(t, true, uObj.Query().Has("status")) + assert.Equal(t, "active", uObj.Query().Get("status")) + + assert.Equal(t, true, uObj.Query().Has("network_id")) + assert.Equal(t, "7bf9e4a9-fab1-4415-a6f7-ff7284ee1870", uObj.Query().Get("network_id")) + } + +} From 1acb1b976a735b31b9df03ea1660330b1b959f9f Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 10 Apr 2024 19:09:37 +0200 Subject: [PATCH 03/11] codebase refactoring --- acceptance/openstack/cts/v3/trackers_test.go | 2 +- openstack/autoscaling/v1/configurations/list.go | 4 ++-- openstack/autoscaling/v1/groups/delete.go | 4 ++-- openstack/autoscaling/v1/groups/list.go | 4 ++-- openstack/autoscaling/v1/instances/delete.go | 4 ++-- openstack/autoscaling/v1/instances/list.go | 4 ++-- .../v1/policies/ListScalingPolicyExecuteLogs.go | 4 ++-- openstack/autoscaling/v1/policies/list.go | 4 ++-- .../autoscaling/v2/logs/ListScalingActivityLogs.go | 4 ++-- openstack/bms/v2/flavors/list.go | 4 ++-- openstack/bms/v2/servers/list.go | 5 +++-- openstack/cbr/v3/backups/list.go | 4 ++-- openstack/cbr/v3/policies/list.go | 4 ++-- openstack/cbr/v3/tasks/list.go | 4 ++-- openstack/ces/v1/alarms/list_alarms.go | 4 ++-- openstack/ces/v1/events/ListEventDetail.go | 4 ++-- openstack/ces/v1/events/ListEvents.go | 4 ++-- openstack/ces/v1/metricdata/list_metric_data.go | 4 ++-- openstack/ces/v1/metricdata/show_event_data.go | 4 ++-- openstack/csbs/v1/backup/CountBackups.go | 4 ++-- openstack/csbs/v1/backup/List.go | 4 ++-- openstack/csbs/v1/policies/List.go | 4 ++-- openstack/cts/v1/tracker/Delete.go | 7 ++++++- openstack/cts/v1/tracker/Get.go | 11 ++++++++++- openstack/cts/v2/traces/List.go | 4 ++-- openstack/cts/v3/tracker/Delete.go | 7 ++++++- openstack/cts/v3/tracker/List.go | 10 +++++++++- openstack/dataarts/v1.1/job/Get.go | 5 ++--- openstack/dcaas/v2/virtual-gateway/List.go | 4 ++-- openstack/dcaas/v2/virtual-interface/List.go | 4 ++-- openstack/dcs/v1/backups/ListBackupRecords.go | 4 ++-- openstack/dcs/v1/backups/ListRestoreRecords.go | 4 ++-- openstack/dcs/v1/instance/ListDCSStatus.go | 4 ++-- openstack/dcs/v1/lifecycle/BatchDelete.go | 4 ++-- openstack/dcs/v1/lifecycle/List.go | 4 ++-- openstack/dds/v3/connection/ListConnections.go | 4 ++-- openstack/dds/v3/connection/ListSessions.go | 4 ++-- openstack/dds/v3/flavors/List.go | 4 ++-- openstack/dds/v3/instances/List.go | 4 ++-- openstack/dis/v2/apps/GetAppStatus.go | 4 ++-- openstack/dis/v2/apps/ListApp.go | 4 ++-- openstack/dis/v2/checkpoints/DeleteCheckpoint.go | 4 ++-- openstack/dis/v2/checkpoints/GetCheckpoint.go | 4 ++-- openstack/dis/v2/data/GetCursor.go | 4 ++-- openstack/dis/v2/data/GetRecords.go | 4 ++-- openstack/dis/v2/monitors/GetPartitionMonitor.go | 4 ++-- openstack/dis/v2/monitors/GetStreamMonitor.go | 4 ++-- openstack/dis/v2/streams/GetStream.go | 4 ++-- openstack/dis/v2/streams/ListStreams.go | 4 ++-- openstack/dms/v2/instances/requests.go | 4 ++-- openstack/elb/v3/ipgroups/List.go | 4 ++-- openstack/elb/v3/security_policy/List.go | 4 ++-- openstack/evs/extensions/schedulerstats/list.go | 4 ++-- openstack/evs/extensions/services/list.go | 4 ++-- openstack/evs/v1/volumes/list.go | 4 ++-- openstack/fgs/v2/function/List.go | 4 ++-- openstack/gaussdb/v3/ListConfigurations.go | 4 ++-- openstack/gaussdb/v3/ShowFlavors.go | 4 ++-- openstack/gaussdb/v3/ShowJobInfo.go | 11 ++++++++++- openstack/gaussdb/v3/backup/ListBackups.go | 4 ++-- openstack/gaussdb/v3/instance/ListInstances.go | 4 ++-- openstack/identity/v3/credentials/requests.go | 5 +++-- openstack/image/v2/images/List.go | 4 ++-- openstack/ims/v1/tags/ListTags.go | 4 ++-- openstack/ims/v2/images/ListImages.go | 4 ++-- openstack/lts/v2/transfers/DeleteTransfer.go | 11 ++++++++++- openstack/lts/v2/transfers/ListTransfers.go | 4 ++-- openstack/mrs/v1/cluster/List.go | 4 ++-- openstack/mrs/v1/cluster/ListHosts.go | 4 ++-- openstack/rds/v3/backups/List.go | 4 ++-- openstack/rds/v3/backups/ListRestoreTimes.go | 4 ++-- openstack/rds/v3/flavors/ListFlavors.go | 4 ++-- openstack/rds/v3/flavors/ListStorageTypes.go | 4 ++-- openstack/rds/v3/instances/List.go | 4 ++-- openstack/swr/v2/domains/ListSharedReposDetails.go | 4 ++-- openstack/swr/v2/organizations/List.go | 4 ++-- openstack/waf-premium/v1/hosts/Delete.go | 7 ++++--- 77 files changed, 196 insertions(+), 149 deletions(-) diff --git a/acceptance/openstack/cts/v3/trackers_test.go b/acceptance/openstack/cts/v3/trackers_test.go index 1a629ad14..957974389 100644 --- a/acceptance/openstack/cts/v3/trackers_test.go +++ b/acceptance/openstack/cts/v3/trackers_test.go @@ -62,8 +62,8 @@ func TestTrackersLifecycle(t *testing.T) { t.Logf("Updated CTSv1 Tracker: %s", ctsTracker.TrackerName) trackerList, err := tracker.List(client, ctsTracker.TrackerName) - trackerGet := trackerList[0] th.AssertNoErr(t, err) + trackerGet := trackerList[0] th.AssertEquals(t, trackerGet.TrackerType, "system") th.AssertEquals(t, trackerGet.TrackerName, "system") th.AssertEquals(t, trackerGet.Status, "enabled") diff --git a/openstack/autoscaling/v1/configurations/list.go b/openstack/autoscaling/v1/configurations/list.go index 62f75f6d9..ac6d752f4 100644 --- a/openstack/autoscaling/v1/configurations/list.go +++ b/openstack/autoscaling/v1/configurations/list.go @@ -18,12 +18,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListScalingConfigsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_configuration").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("scaling_configuration")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/autoscaling/v1/groups/delete.go b/openstack/autoscaling/v1/groups/delete.go index 9acc56290..94ea3e07d 100644 --- a/openstack/autoscaling/v1/groups/delete.go +++ b/openstack/autoscaling/v1/groups/delete.go @@ -8,11 +8,11 @@ type DeleteOpts struct { } func Delete(client *golangsdk.ServiceClient, opts DeleteOpts) (err error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_group", opts.ScalingGroupId).WithQueryParams(&opts).Build() if err != nil { return } - _, err = client.Delete(client.ServiceURL("scaling_group", opts.ScalingGroupId)+q.String(), nil) + _, err = client.Delete(client.ServiceURL(url.String()), nil) return } diff --git a/openstack/autoscaling/v1/groups/list.go b/openstack/autoscaling/v1/groups/list.go index 6670168c6..83d614d5a 100644 --- a/openstack/autoscaling/v1/groups/list.go +++ b/openstack/autoscaling/v1/groups/list.go @@ -27,12 +27,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListScalingGroupsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_group").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("scaling_group")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/autoscaling/v1/instances/delete.go b/openstack/autoscaling/v1/instances/delete.go index 644e57708..5a7ad065e 100644 --- a/openstack/autoscaling/v1/instances/delete.go +++ b/openstack/autoscaling/v1/instances/delete.go @@ -12,11 +12,11 @@ type DeleteOpts struct { } func Delete(client *golangsdk.ServiceClient, opts DeleteOpts) error { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_group_instance", opts.InstanceId).WithQueryParams(&opts).Build() if err != nil { return err } - _, err = client.Delete(client.ServiceURL("scaling_group_instance", opts.InstanceId)+q.String(), nil) + _, err = client.Delete(client.ServiceURL(url.String()), nil) return err } diff --git a/openstack/autoscaling/v1/instances/list.go b/openstack/autoscaling/v1/instances/list.go index 4cc9e278e..83acf0862 100644 --- a/openstack/autoscaling/v1/instances/list.go +++ b/openstack/autoscaling/v1/instances/list.go @@ -29,13 +29,13 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListScalingInstancesResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_group_instance", opts.ScalingGroupId, "list").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /autoscaling-api/v1/{project_id}/scaling_group_instance/{scaling_group_id}/list - raw, err := client.Get(client.ServiceURL("scaling_group_instance", opts.ScalingGroupId, "list")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/autoscaling/v1/policies/ListScalingPolicyExecuteLogs.go b/openstack/autoscaling/v1/policies/ListScalingPolicyExecuteLogs.go index 1554b07e8..4d540a8d2 100644 --- a/openstack/autoscaling/v1/policies/ListScalingPolicyExecuteLogs.go +++ b/openstack/autoscaling/v1/policies/ListScalingPolicyExecuteLogs.go @@ -35,13 +35,13 @@ type ListLogsOpts struct { } func ListScalingPolicyExecuteLogs(client *golangsdk.ServiceClient, opts ListLogsOpts) (*ListScalingPolicyExecuteLogsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_policy_execute_log", opts.ScalingPolicyId).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /autoscaling-api/v1/{project_id}/scaling_policy_execute_log/{scaling_policy_id} - raw, err := client.Get(client.ServiceURL("scaling_policy_execute_log", opts.ScalingPolicyId)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/autoscaling/v1/policies/list.go b/openstack/autoscaling/v1/policies/list.go index 0c5b61774..a87e380fb 100644 --- a/openstack/autoscaling/v1/policies/list.go +++ b/openstack/autoscaling/v1/policies/list.go @@ -25,13 +25,13 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListScalingInstancesResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_policy", opts.ScalingGroupId, "list").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /autoscaling-api/v1/{project_id}/scaling_policy/{scaling_group_id}/list - raw, err := client.Get(client.ServiceURL("scaling_policy", opts.ScalingGroupId, "list")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/autoscaling/v2/logs/ListScalingActivityLogs.go b/openstack/autoscaling/v2/logs/ListScalingActivityLogs.go index 39e501326..6878f9a83 100644 --- a/openstack/autoscaling/v2/logs/ListScalingActivityLogs.go +++ b/openstack/autoscaling/v2/logs/ListScalingActivityLogs.go @@ -40,13 +40,13 @@ type ListScalingActivityLogsOpts struct { } func ListScalingActivityLogs(client *golangsdk.ServiceClient, opts ListScalingActivityLogsOpts) (*ListScalingActivityLogsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scaling_activity_log", opts.ScalingGroupId).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /autoscaling-api/v2/{project_id}/scaling_activity_log/{scaling_group_id} - raw, err := client.Get(client.ServiceURL("scaling_activity_log", opts.ScalingGroupId)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/bms/v2/flavors/list.go b/openstack/bms/v2/flavors/list.go index faf91e98d..52e085c7a 100644 --- a/openstack/bms/v2/flavors/list.go +++ b/openstack/bms/v2/flavors/list.go @@ -42,12 +42,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Flavor, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("flavors", "detail").WithQueryParams(&opts).Build() if err != nil { return nil, err } - pages, err := pagination.NewPager(client, client.ServiceURL("flavors", "detail")+q.String(), func(r pagination.PageResult) pagination.Page { + pages, err := pagination.NewPager(client, client.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return FlavorPage{pagination.LinkedPageBase{PageResult: r}} }).AllPages() if err != nil { diff --git a/openstack/bms/v2/servers/list.go b/openstack/bms/v2/servers/list.go index d42b93c42..91ad6ae13 100644 --- a/openstack/bms/v2/servers/list.go +++ b/openstack/bms/v2/servers/list.go @@ -86,12 +86,13 @@ type ListOpts struct { // filter the returned collection for greater efficiency. func List(c *golangsdk.ServiceClient, opts ListOpts) ([]Server, error) { c.Microversion = "2.26" - q, err := golangsdk.BuildQueryString(&opts) + + url, err := golangsdk.NewURLBuilder().WithEndpoints("servers", "detail").WithQueryParams(&opts).Build() if err != nil { return nil, err } - pages, err := pagination.NewPager(c, c.ServiceURL("servers", "detail")+q.String(), + pages, err := pagination.NewPager(c, c.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return ServerPage{pagination.LinkedPageBase{PageResult: r}} }).AllPages() diff --git a/openstack/cbr/v3/backups/list.go b/openstack/cbr/v3/backups/list.go index 38816b4a0..fadad499a 100644 --- a/openstack/cbr/v3/backups/list.go +++ b/openstack/cbr/v3/backups/list.go @@ -29,12 +29,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Backup, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("backups").WithQueryParams(&opts).Build() if err != nil { return nil, err } - pages, err := pagination.NewPager(client, client.ServiceURL("backups")+q.String(), + pages, err := pagination.NewPager(client, client.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return BackupPage{pagination.LinkedPageBase{PageResult: r}} }).AllPages() diff --git a/openstack/cbr/v3/policies/list.go b/openstack/cbr/v3/policies/list.go index a84505a37..7b52826b5 100644 --- a/openstack/cbr/v3/policies/list.go +++ b/openstack/cbr/v3/policies/list.go @@ -15,12 +15,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Policy, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("policies").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("policies")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/cbr/v3/tasks/list.go b/openstack/cbr/v3/tasks/list.go index 45121b220..2ee3f7fca 100644 --- a/openstack/cbr/v3/tasks/list.go +++ b/openstack/cbr/v3/tasks/list.go @@ -21,12 +21,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]OperationLog, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("operation-logs").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("operation-logs")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/ces/v1/alarms/list_alarms.go b/openstack/ces/v1/alarms/list_alarms.go index 69c1f5cdf..7b903cda4 100644 --- a/openstack/ces/v1/alarms/list_alarms.go +++ b/openstack/ces/v1/alarms/list_alarms.go @@ -19,13 +19,13 @@ type ListAlarmsOpts struct { } func ListAlarms(client *golangsdk.ServiceClient, opts ListAlarmsOpts) (*ListAlarmsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("alarms").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /V1.0/{project_id}/alarms - raw, err := client.Get(client.ServiceURL("alarms")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/ces/v1/events/ListEventDetail.go b/openstack/ces/v1/events/ListEventDetail.go index 0639050b0..890b7a090 100644 --- a/openstack/ces/v1/events/ListEventDetail.go +++ b/openstack/ces/v1/events/ListEventDetail.go @@ -30,13 +30,13 @@ type ListEventDetailOpts struct { } func ListEventDetail(client *golangsdk.ServiceClient, opts ListEventDetailOpts) (*ListEventDetailResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("event", opts.EventName).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /V1.0/{project_id}/event/{event_name} - raw, err := client.Get(client.ServiceURL("event", opts.EventName)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/ces/v1/events/ListEvents.go b/openstack/ces/v1/events/ListEvents.go index d707fdb0d..5cea9f7a8 100644 --- a/openstack/ces/v1/events/ListEvents.go +++ b/openstack/ces/v1/events/ListEvents.go @@ -22,13 +22,13 @@ type ListEventsOpts struct { } func ListEvents(client *golangsdk.ServiceClient, opts ListEventsOpts) (*ListEventsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("events").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /V1.0/{project_id}/events - raw, err := client.Get(client.ServiceURL("events")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/ces/v1/metricdata/list_metric_data.go b/openstack/ces/v1/metricdata/list_metric_data.go index 7d7c42995..eedd75c04 100644 --- a/openstack/ces/v1/metricdata/list_metric_data.go +++ b/openstack/ces/v1/metricdata/list_metric_data.go @@ -55,13 +55,13 @@ type ShowMetricDataOpts struct { } func ShowMetricData(client *golangsdk.ServiceClient, opts ShowMetricDataOpts) (*MetricData, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("metric-data").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /V1.0/{project_id}/metric-data - raw, err := client.Get(client.ServiceURL("metric-data")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/ces/v1/metricdata/show_event_data.go b/openstack/ces/v1/metricdata/show_event_data.go index 6eb5258ed..5fd61c87a 100644 --- a/openstack/ces/v1/metricdata/show_event_data.go +++ b/openstack/ces/v1/metricdata/show_event_data.go @@ -27,13 +27,13 @@ type ShowEventDataOpts struct { } func ListEventData(client *golangsdk.ServiceClient, opts ShowEventDataOpts) ([]EventDataInfo, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("event-data").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /V1.0/{project_id}/event-data - raw, err := client.Get(client.ServiceURL("event-data")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/csbs/v1/backup/CountBackups.go b/openstack/csbs/v1/backup/CountBackups.go index 7136d0b47..23ae1a95b 100644 --- a/openstack/csbs/v1/backup/CountBackups.go +++ b/openstack/csbs/v1/backup/CountBackups.go @@ -37,13 +37,13 @@ type CountOpts struct { } func CountBackups(client *golangsdk.ServiceClient, opts CountOpts) (*int, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("checkpoint_items", "count").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{endpoint}/v1/{project_id}/checkpoint_items/count - raw, err := client.Get(client.ServiceURL("checkpoint_items", "count")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/csbs/v1/backup/List.go b/openstack/csbs/v1/backup/List.go index ef1041652..634b05dd9 100644 --- a/openstack/csbs/v1/backup/List.go +++ b/openstack/csbs/v1/backup/List.go @@ -57,13 +57,13 @@ type ListOpts struct { // backups. It accepts a ListOpts struct, which allows you to filter and sort // the returned collection for greater efficiency. func List(c *golangsdk.ServiceClient, opts ListOpts) ([]Backup, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("checkpoint_items").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{endpoint}/v1/{project_id}/checkpoint_items - pages, err := pagination.NewPager(c, c.ServiceURL("checkpoint_items")+q.String(), + pages, err := pagination.NewPager(c, c.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return СsbsBackupPage{pagination.LinkedPageBase{PageResult: r}} }).AllPages() diff --git a/openstack/csbs/v1/policies/List.go b/openstack/csbs/v1/policies/List.go index 7e0e52584..06796e343 100644 --- a/openstack/csbs/v1/policies/List.go +++ b/openstack/csbs/v1/policies/List.go @@ -29,13 +29,13 @@ type ListOpts struct { // backup policies. It accepts a ListOpts struct, which allows you to // filter the returned collection for greater efficiency. func List(client *golangsdk.ServiceClient, opts ListOpts) ([]BackupPolicy, error) { - query, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("policies").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{endpoint}/v1/{project_id}/policies - pages, err := pagination.NewPager(client, client.ServiceURL("policies")+query.String(), + pages, err := pagination.NewPager(client, client.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return BackupPolicyPage{pagination.LinkedPageBase{PageResult: r}} }).AllPages() diff --git a/openstack/cts/v1/tracker/Delete.go b/openstack/cts/v1/tracker/Delete.go index f25dfd2ca..13c338baa 100644 --- a/openstack/cts/v1/tracker/Delete.go +++ b/openstack/cts/v1/tracker/Delete.go @@ -4,7 +4,12 @@ import "github.com/opentelekomcloud/gophertelekomcloud" // Delete will permanently delete a particular tracker. func Delete(client *golangsdk.ServiceClient, trackerName string) (err error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints("tracker").WithQueryParams(&tracker{Tracker: trackerName}).Build() + if err != nil { + return err + } + // DELETE /v1.0/{project_id}/tracker?tracker_name={tracker_name} - _, err = client.Delete(client.ServiceURL("tracker")+"?tracker_name="+trackerName, nil) + _, err = client.Delete(client.ServiceURL(url.String()), nil) return } diff --git a/openstack/cts/v1/tracker/Get.go b/openstack/cts/v1/tracker/Get.go index f98471023..926012f60 100644 --- a/openstack/cts/v1/tracker/Get.go +++ b/openstack/cts/v1/tracker/Get.go @@ -4,8 +4,17 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud" ) +type tracker struct { + Tracker string `q:"tracker_name"` +} + func Get(client *golangsdk.ServiceClient, trackerName string) (*Tracker, error) { + + url, err := golangsdk.NewURLBuilder().WithEndpoints("tracker").WithQueryParams(&tracker{Tracker: trackerName}).Build() + if err != nil { + return nil, err + } // GET /v1.0/{project_id}/tracker?tracker_name={tracker_name} - raw, err := client.Get(client.ServiceURL("tracker")+"?tracker_name="+trackerName, nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) return extra(err, raw) } diff --git a/openstack/cts/v2/traces/List.go b/openstack/cts/v2/traces/List.go index 029f6cfe0..24e75e15a 100644 --- a/openstack/cts/v2/traces/List.go +++ b/openstack/cts/v2/traces/List.go @@ -47,13 +47,13 @@ type ListTracesOpts struct { } func List(client *golangsdk.ServiceClient, trackerName string, opts ListTracesOpts) (*ListTracesResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints(trackerName, "trace").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2.0/{project_id}/{tracker_name}/trace - raw, err := client.Get(client.ServiceURL(trackerName, "trace")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/cts/v3/tracker/Delete.go b/openstack/cts/v3/tracker/Delete.go index 806f11d63..07d323c89 100644 --- a/openstack/cts/v3/tracker/Delete.go +++ b/openstack/cts/v3/tracker/Delete.go @@ -4,7 +4,12 @@ import "github.com/opentelekomcloud/gophertelekomcloud" // Delete will permanently delete a particular tracker. func Delete(client *golangsdk.ServiceClient, trackerName string) (err error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints("trackers").WithQueryParams(&tracker{Tracker: trackerName}).Build() + if err != nil { + return err + } + // DELETE /v3/{project_id}/trackers?tracker_name=system - _, err = client.Delete(client.ServiceURL("trackers")+"?tracker_name="+trackerName, nil) + _, err = client.Delete(client.ServiceURL(url.String()), nil) return } diff --git a/openstack/cts/v3/tracker/List.go b/openstack/cts/v3/tracker/List.go index c9b42402d..21ac745ba 100644 --- a/openstack/cts/v3/tracker/List.go +++ b/openstack/cts/v3/tracker/List.go @@ -4,8 +4,16 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud" ) +type tracker struct { + Tracker string `q:"tracker_name"` +} + func List(client *golangsdk.ServiceClient, trackerName string) ([]Tracker, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints("trackers").WithQueryParams(&tracker{Tracker: trackerName}).Build() + if err != nil { + return []Tracker{}, err + } // GET /v3/{project_id}/trackers - raw, err := client.Get(client.ServiceURL("trackers")+"?tracker_name="+trackerName, nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) return extraStruct(err, raw) } diff --git a/openstack/dataarts/v1.1/job/Get.go b/openstack/dataarts/v1.1/job/Get.go index a4daa1d53..1b234a9fb 100644 --- a/openstack/dataarts/v1.1/job/Get.go +++ b/openstack/dataarts/v1.1/job/Get.go @@ -17,13 +17,12 @@ type GetQuery struct { // Get returns 500 error, not usable func Get(client *golangsdk.ServiceClient, opts GetQuery) ([]Job, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("clusters", opts.ClusterId, "cdm", "job", opts.JobName).WithQueryParams(&opts).Build() if err != nil { return nil, err } - url := "clusters/" + opts.ClusterId + "/cdm/job/" + opts.JobName - pages, err := pagination.NewPager(client, client.ServiceURL(url)+q.String(), + pages, err := pagination.NewPager(client, client.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return JobPage{pagination.LinkedPageBase{PageResult: r}} }).AllPages() diff --git a/openstack/dcaas/v2/virtual-gateway/List.go b/openstack/dcaas/v2/virtual-gateway/List.go index 43b807d3b..1f4efd693 100644 --- a/openstack/dcaas/v2/virtual-gateway/List.go +++ b/openstack/dcaas/v2/virtual-gateway/List.go @@ -13,13 +13,13 @@ type ListOpts struct { // List is used to obtain the virtual gateway list func List(client *golangsdk.ServiceClient, opts ListOpts) ([]VirtualGateway, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("dcaas", "virtual-gateways").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v2.0/{project_id}/virtual-gateways - raw, err := client.Get(client.ServiceURL("dcaas", "virtual-gateways")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/dcaas/v2/virtual-interface/List.go b/openstack/dcaas/v2/virtual-interface/List.go index b2b19d194..608207811 100644 --- a/openstack/dcaas/v2/virtual-interface/List.go +++ b/openstack/dcaas/v2/virtual-interface/List.go @@ -47,13 +47,13 @@ type VirtualInterface struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]VirtualInterface, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("dcaas", "virtual-interfaces").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v2.0/{project_id}/virtual-interfaces?id={id} - raw, err := client.Get(client.ServiceURL("dcaas", "virtual-interfaces")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/dcs/v1/backups/ListBackupRecords.go b/openstack/dcs/v1/backups/ListBackupRecords.go index 5f7ad4317..6bc2d5328 100644 --- a/openstack/dcs/v1/backups/ListBackupRecords.go +++ b/openstack/dcs/v1/backups/ListBackupRecords.go @@ -18,12 +18,12 @@ type ListBackupOpts struct { } func ListBackupRecords(client *golangsdk.ServiceClient, instancesId string, opts ListBackupOpts) (*ListBackupRecordsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances", instancesId, "backups").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("instances", instancesId, "backups")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dcs/v1/backups/ListRestoreRecords.go b/openstack/dcs/v1/backups/ListRestoreRecords.go index b4ff3b522..f4dfcfc27 100644 --- a/openstack/dcs/v1/backups/ListRestoreRecords.go +++ b/openstack/dcs/v1/backups/ListRestoreRecords.go @@ -6,12 +6,12 @@ import ( ) func ListRestoreRecords(client *golangsdk.ServiceClient, instancesId string, opts ListBackupOpts) (*ListRestoreRecordsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances", instancesId, "restores").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("instances", instancesId, "restores")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dcs/v1/instance/ListDCSStatus.go b/openstack/dcs/v1/instance/ListDCSStatus.go index 9e51ac128..acd1d7d6b 100644 --- a/openstack/dcs/v1/instance/ListDCSStatus.go +++ b/openstack/dcs/v1/instance/ListDCSStatus.go @@ -13,12 +13,12 @@ type StatusOpts struct { } func ListDCSStatus(client *golangsdk.ServiceClient, opts StatusOpts) (*ListNumberOfInstancesInDifferentStatusResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances", "status").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("instances", "status")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dcs/v1/lifecycle/BatchDelete.go b/openstack/dcs/v1/lifecycle/BatchDelete.go index 051880d99..1d3e35f20 100644 --- a/openstack/dcs/v1/lifecycle/BatchDelete.go +++ b/openstack/dcs/v1/lifecycle/BatchDelete.go @@ -23,7 +23,7 @@ type BatchDeleteBody struct { } func BatchDelete(client *golangsdk.ServiceClient, opts BatchDeleteOpts) ([]BatchOpsResult, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances").WithQueryParams(&opts).Build() if err != nil { return nil, err } @@ -33,7 +33,7 @@ func BatchDelete(client *golangsdk.ServiceClient, opts BatchDeleteOpts) ([]Batch return nil, err } - raw, err := client.DeleteWithBody(client.ServiceURL("instances")+q.String(), b, nil) + raw, err := client.DeleteWithBody(client.ServiceURL(url.String()), b, nil) if err != nil { return nil, err } diff --git a/openstack/dcs/v1/lifecycle/List.go b/openstack/dcs/v1/lifecycle/List.go index b1d9c6864..7d6879a51 100644 --- a/openstack/dcs/v1/lifecycle/List.go +++ b/openstack/dcs/v1/lifecycle/List.go @@ -34,13 +34,13 @@ type ListDcsInstanceOpts struct { } func List(client *golangsdk.ServiceClient, opts ListDcsInstanceOpts) (*ListDcsResponse, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v1.0/{project_id}/instances - raw, err := client.Get(client.ServiceURL("instances")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dds/v3/connection/ListConnections.go b/openstack/dds/v3/connection/ListConnections.go index d08103369..c849c30c7 100644 --- a/openstack/dds/v3/connection/ListConnections.go +++ b/openstack/dds/v3/connection/ListConnections.go @@ -14,13 +14,13 @@ type ListConnectionsOpts struct { } func ListConnections(client *golangsdk.ServiceClient, opts ListConnectionsOpts) (*ListConnectionsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances", opts.InstanceId, "conn-statistics").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/instances/{instance_id}/conn-statistics - raw, err := client.Get(client.ServiceURL("instances", opts.InstanceId, "conn-statistics")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dds/v3/connection/ListSessions.go b/openstack/dds/v3/connection/ListSessions.go index 7e5cbd396..cbf3b1181 100644 --- a/openstack/dds/v3/connection/ListSessions.go +++ b/openstack/dds/v3/connection/ListSessions.go @@ -23,13 +23,13 @@ type ListSessionOpts struct { } func ListSessions(client *golangsdk.ServiceClient, opts ListSessionOpts) (*ListSessionsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("nodes", opts.NodeId, "sessions").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/nodes/{node_id}/sessions - raw, err := client.Get(client.ServiceURL("nodes", opts.NodeId, "sessions")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dds/v3/flavors/List.go b/openstack/dds/v3/flavors/List.go index aefc85600..25d5e82da 100644 --- a/openstack/dds/v3/flavors/List.go +++ b/openstack/dds/v3/flavors/List.go @@ -21,13 +21,13 @@ type ListFlavorOpts struct { } func List(client *golangsdk.ServiceClient, opts ListFlavorOpts) (*ListResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("flavors").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3.1/{project_id}/flavors - raw, err := client.Get(client.ServiceURL("flavors")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dds/v3/instances/List.go b/openstack/dds/v3/instances/List.go index 462b65f72..fd039caaf 100644 --- a/openstack/dds/v3/instances/List.go +++ b/openstack/dds/v3/instances/List.go @@ -46,13 +46,13 @@ type ListInstanceOpts struct { } func List(client *golangsdk.ServiceClient, opts ListInstanceOpts) (*ListResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/instances - raw, err := client.Get(client.ServiceURL("instances")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/apps/GetAppStatus.go b/openstack/dis/v2/apps/GetAppStatus.go index dd3fd143d..31968569c 100644 --- a/openstack/dis/v2/apps/GetAppStatus.go +++ b/openstack/dis/v2/apps/GetAppStatus.go @@ -29,13 +29,13 @@ type GetAppStatusOpts struct { } func GetAppStatus(client *golangsdk.ServiceClient, opts GetAppStatusOpts) (*GetAppStatusResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("apps", opts.AppName, "streams", opts.StreamName).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/apps/{app_name}/streams/{stream_name} - raw, err := client.Get(client.ServiceURL("apps", opts.AppName, "streams", opts.StreamName)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/apps/ListApp.go b/openstack/dis/v2/apps/ListApp.go index ec8fbf0e5..7f09241da 100644 --- a/openstack/dis/v2/apps/ListApp.go +++ b/openstack/dis/v2/apps/ListApp.go @@ -18,13 +18,13 @@ type ListAppOpts struct { } func ListApps(client *golangsdk.ServiceClient, opts ListAppOpts) (*ListAppResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("apps").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/apps - raw, err := client.Get(client.ServiceURL("apps")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/checkpoints/DeleteCheckpoint.go b/openstack/dis/v2/checkpoints/DeleteCheckpoint.go index 2e074d79d..4c01fd199 100644 --- a/openstack/dis/v2/checkpoints/DeleteCheckpoint.go +++ b/openstack/dis/v2/checkpoints/DeleteCheckpoint.go @@ -21,12 +21,12 @@ type DeleteCheckpointOpts struct { } func DeleteCheckpoint(client *golangsdk.ServiceClient, opts DeleteCheckpointOpts) (err error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("checkpoints").WithQueryParams(&opts).Build() if err != nil { return err } // DELETE /v2/{project_id}/checkpoints - _, err = client.Delete(client.ServiceURL("checkpoints")+q.String(), nil) + _, err = client.Delete(client.ServiceURL(url.String()), nil) return } diff --git a/openstack/dis/v2/checkpoints/GetCheckpoint.go b/openstack/dis/v2/checkpoints/GetCheckpoint.go index 10353dc51..3912809eb 100644 --- a/openstack/dis/v2/checkpoints/GetCheckpoint.go +++ b/openstack/dis/v2/checkpoints/GetCheckpoint.go @@ -25,13 +25,13 @@ type GetCheckpointOpts struct { } func GetCheckpoint(client *golangsdk.ServiceClient, opts GetCheckpointOpts) (*GetCheckpointResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("checkpoints").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/checkpoints - raw, err := client.Get(client.ServiceURL("checkpoints")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/data/GetCursor.go b/openstack/dis/v2/data/GetCursor.go index 6ab9661ab..460b27449 100644 --- a/openstack/dis/v2/data/GetCursor.go +++ b/openstack/dis/v2/data/GetCursor.go @@ -50,13 +50,13 @@ type GetCursorOpts struct { } func GetCursor(client *golangsdk.ServiceClient, opts GetCursorOpts) (*GetCursorResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("cursors").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/cursors - raw, err := client.Get(client.ServiceURL("cursors")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/data/GetRecords.go b/openstack/dis/v2/data/GetRecords.go index f80602994..a51c9a921 100644 --- a/openstack/dis/v2/data/GetRecords.go +++ b/openstack/dis/v2/data/GetRecords.go @@ -18,13 +18,13 @@ type GetRecordsOpts struct { } func GetRecords(client *golangsdk.ServiceClient, opts GetRecordsOpts) (*GetRecordsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("records").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/records - raw, err := client.Get(client.ServiceURL("records")+q.String(), nil, &golangsdk.RequestOpts{ + raw, err := client.Get(client.ServiceURL(url.String()), nil, &golangsdk.RequestOpts{ MoreHeaders: map[string]string{"Content-Type": "application/json"}, }) if err != nil { diff --git a/openstack/dis/v2/monitors/GetPartitionMonitor.go b/openstack/dis/v2/monitors/GetPartitionMonitor.go index 372af713c..70f321b77 100644 --- a/openstack/dis/v2/monitors/GetPartitionMonitor.go +++ b/openstack/dis/v2/monitors/GetPartitionMonitor.go @@ -43,13 +43,13 @@ type GetPartitionMonitorOpts struct { } func GetPartitionMonitor(client *golangsdk.ServiceClient, opts GetPartitionMonitorOpts) (*GetPartitionMonitorResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("streams", opts.StreamName, "partitions", opts.PartitionId, "metrics").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/streams/{stream_name}/partitions/{partition_id}/metrics - raw, err := client.Get(client.ServiceURL("streams", opts.StreamName, "partitions", opts.PartitionId, "metrics")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/monitors/GetStreamMonitor.go b/openstack/dis/v2/monitors/GetStreamMonitor.go index 7924875bd..59ba7c898 100644 --- a/openstack/dis/v2/monitors/GetStreamMonitor.go +++ b/openstack/dis/v2/monitors/GetStreamMonitor.go @@ -45,13 +45,13 @@ type GetStreamMonitorOpts struct { } func GetStreamMonitor(client *golangsdk.ServiceClient, opts GetStreamMonitorOpts) (*GetStreamMonitorResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("streams", opts.StreamName, "metrics").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/streams/{stream_name}/metrics - raw, err := client.Get(client.ServiceURL("streams", opts.StreamName, "metrics")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dis/v2/streams/GetStream.go b/openstack/dis/v2/streams/GetStream.go index 6005ff6b7..3b41f5a9f 100644 --- a/openstack/dis/v2/streams/GetStream.go +++ b/openstack/dis/v2/streams/GetStream.go @@ -20,13 +20,13 @@ type GetStreamOpts struct { } func GetStream(client *golangsdk.ServiceClient, opts GetStreamOpts) (*DescribeStreamResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("streams", opts.StreamName).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/streams/{stream_name} - raw, err := client.Get(client.ServiceURL("streams", opts.StreamName)+q.String(), nil, + raw, err := client.Get(client.ServiceURL(url.String()), nil, &golangsdk.RequestOpts{ MoreHeaders: map[string]string{"Content-Type": "application/json"}, JSONBody: nil, }) diff --git a/openstack/dis/v2/streams/ListStreams.go b/openstack/dis/v2/streams/ListStreams.go index e65b6f7dd..8da91afa4 100644 --- a/openstack/dis/v2/streams/ListStreams.go +++ b/openstack/dis/v2/streams/ListStreams.go @@ -21,13 +21,13 @@ type ListStreamsOpts struct { } func ListStreams(client *golangsdk.ServiceClient, opts ListStreamsOpts) (*ListStreamsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("streams").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/streams - raw, err := client.Get(client.ServiceURL("streams")+q.String(), nil, &golangsdk.RequestOpts{ + raw, err := client.Get(client.ServiceURL(url.String()), nil, &golangsdk.RequestOpts{ MoreHeaders: map[string]string{"Content-Type": "application/json"}, JSONBody: nil, }) if err != nil { diff --git a/openstack/dms/v2/instances/requests.go b/openstack/dms/v2/instances/requests.go index 15afc0871..1b28244ee 100644 --- a/openstack/dms/v2/instances/requests.go +++ b/openstack/dms/v2/instances/requests.go @@ -205,12 +205,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints(listURL(client)).WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(listURL(client)+q.String(), nil, nil) + raw, err := client.Get(url.String(), nil, nil) if err != nil { return nil, err } diff --git a/openstack/elb/v3/ipgroups/List.go b/openstack/elb/v3/ipgroups/List.go index ea17aec1c..2f3d277da 100644 --- a/openstack/elb/v3/ipgroups/List.go +++ b/openstack/elb/v3/ipgroups/List.go @@ -20,13 +20,13 @@ type ListOpts struct { // List is used to obtain the parameter ipGroup list func List(client *golangsdk.ServiceClient, opts ListOpts) ([]IpGroup, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("ipgroups").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/backups - raw, err := client.Get(client.ServiceURL("ipgroups")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/elb/v3/security_policy/List.go b/openstack/elb/v3/security_policy/List.go index 2491a8bb9..841863a68 100644 --- a/openstack/elb/v3/security_policy/List.go +++ b/openstack/elb/v3/security_policy/List.go @@ -17,12 +17,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]PolicyRef, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("security-policies").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("security-policies")+q.String(), nil, &golangsdk.RequestOpts{OkCodes: []int{200}}) + raw, err := client.Get(client.ServiceURL(url.String()), nil, &golangsdk.RequestOpts{OkCodes: []int{200}}) if err != nil { return nil, err } diff --git a/openstack/evs/extensions/schedulerstats/list.go b/openstack/evs/extensions/schedulerstats/list.go index 0e661bb4c..a695ebdea 100644 --- a/openstack/evs/extensions/schedulerstats/list.go +++ b/openstack/evs/extensions/schedulerstats/list.go @@ -16,12 +16,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]StoragePool, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("scheduler-stats", "get_pools").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("scheduler-stats", "get_pools")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/evs/extensions/services/list.go b/openstack/evs/extensions/services/list.go index ef2755f21..5645f9538 100644 --- a/openstack/evs/extensions/services/list.go +++ b/openstack/evs/extensions/services/list.go @@ -16,12 +16,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Service, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("os-services").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("os-services")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/evs/v1/volumes/list.go b/openstack/evs/v1/volumes/list.go index fa6f4d74c..7f640ec42 100644 --- a/openstack/evs/v1/volumes/list.go +++ b/openstack/evs/v1/volumes/list.go @@ -17,12 +17,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Volume, error) { - query, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("volumes").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("volumes")+query.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/fgs/v2/function/List.go b/openstack/fgs/v2/function/List.go index 927aa237c..fbabd121d 100644 --- a/openstack/fgs/v2/function/List.go +++ b/openstack/fgs/v2/function/List.go @@ -12,12 +12,12 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListFuncResponse, error) { - q, err := golangsdk.BuildQueryString(&opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("fgs", "functions").WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("fgs", "functions")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/gaussdb/v3/ListConfigurations.go b/openstack/gaussdb/v3/ListConfigurations.go index b16937ef4..e05f065ab 100644 --- a/openstack/gaussdb/v3/ListConfigurations.go +++ b/openstack/gaussdb/v3/ListConfigurations.go @@ -17,13 +17,13 @@ type ListConfigOpts struct { } func ListConfigurations(client *golangsdk.ServiceClient, opts ListConfigOpts) (*ListConfigResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("configurations").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/mysql/v3/{project_id}/configurations - raw, err := client.Get(client.ServiceURL("configurations")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/gaussdb/v3/ShowFlavors.go b/openstack/gaussdb/v3/ShowFlavors.go index 37309da3f..081785750 100644 --- a/openstack/gaussdb/v3/ShowFlavors.go +++ b/openstack/gaussdb/v3/ShowFlavors.go @@ -17,13 +17,13 @@ type ShowFlavorsOpts struct { } func ShowGaussMySqlFlavors(client *golangsdk.ServiceClient, opts ShowFlavorsOpts) ([]MysqlFlavorsInfo, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("flavors", opts.DatabaseName).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/mysql/v3/{project_id}/flavors/{database_name} - raw, err := client.Get(client.ServiceURL("flavors", opts.DatabaseName)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/gaussdb/v3/ShowJobInfo.go b/openstack/gaussdb/v3/ShowJobInfo.go index 971679b4c..84f78577c 100644 --- a/openstack/gaussdb/v3/ShowJobInfo.go +++ b/openstack/gaussdb/v3/ShowJobInfo.go @@ -5,9 +5,18 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" ) +type taskIdStr struct { + Id string `q:"id"` +} + func ShowJobInfo(client *golangsdk.ServiceClient, taskId string) (*GetJobInfoDetail, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints("jobs").WithQueryParams(&taskIdStr{Id: taskId}).Build() + if err != nil { + return nil, err + } + // GET https://{Endpoint}/mysql/v3/{project_id}/jobs?id={id} - raw, err := client.Get(client.ServiceURL("jobs")+"?id="+taskId, nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/gaussdb/v3/backup/ListBackups.go b/openstack/gaussdb/v3/backup/ListBackups.go index 8897122b3..b4aad1ded 100644 --- a/openstack/gaussdb/v3/backup/ListBackups.go +++ b/openstack/gaussdb/v3/backup/ListBackups.go @@ -27,13 +27,13 @@ type BackupListOpts struct { } func ListBackups(client *golangsdk.ServiceClient, opts BackupListOpts) (*BackupListResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("backups").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/mysql/v3/{project_id}/backups - raw, err := client.Get(client.ServiceURL("backups")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/gaussdb/v3/instance/ListInstances.go b/openstack/gaussdb/v3/instance/ListInstances.go index 357de4c00..690b92e1d 100644 --- a/openstack/gaussdb/v3/instance/ListInstances.go +++ b/openstack/gaussdb/v3/instance/ListInstances.go @@ -41,13 +41,13 @@ type ListInstancesOpts struct { } func ListInstances(client *golangsdk.ServiceClient, opts ListInstancesOpts) (*ListInstancesResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/mysql/v3/{project_id}/instances - raw, err := client.Get(client.ServiceURL("instances")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/identity/v3/credentials/requests.go b/openstack/identity/v3/credentials/requests.go index 72884d1d4..40f6b5ac2 100644 --- a/openstack/identity/v3/credentials/requests.go +++ b/openstack/identity/v3/credentials/requests.go @@ -27,12 +27,13 @@ func (opts ListOpts) ToCredentialListQuery() (string, error) { } func List(client *golangsdk.ServiceClient, opts ListOptsBuilder) (l ListResult) { - q, err := opts.ToCredentialListQuery() + url, err := golangsdk.NewURLBuilder().WithEndpoints(listURL(client)).WithQueryParams(&opts).Build() if err != nil { l.Err = err return } - _, l.Err = client.Get(listURL(client)+q, &l.Body, nil) + + _, l.Err = client.Get(url.String(), &l.Body, nil) return } diff --git a/openstack/image/v2/images/List.go b/openstack/image/v2/images/List.go index 4377708c7..a4607f8fb 100644 --- a/openstack/image/v2/images/List.go +++ b/openstack/image/v2/images/List.go @@ -13,13 +13,13 @@ import ( // List implements image list request. func List(c *golangsdk.ServiceClient, opts images.ListImagesOpts) pagination.Pager { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("images").WithQueryParams(&opts).Build() if err != nil { return pagination.Pager{Err: err} } // GET /v2/images - return pagination.NewPager(c, c.ServiceURL("images")+q.String(), func(r pagination.PageResult) pagination.Page { + return pagination.NewPager(c, c.ServiceURL(url.String()), func(r pagination.PageResult) pagination.Page { return ImagePage{ serviceURL: c.ServiceURL(), LinkedPageBase: pagination.LinkedPageBase{PageResult: r}, diff --git a/openstack/ims/v1/tags/ListTags.go b/openstack/ims/v1/tags/ListTags.go index 0ab9b2704..88421dded 100644 --- a/openstack/ims/v1/tags/ListTags.go +++ b/openstack/ims/v1/tags/ListTags.go @@ -167,13 +167,13 @@ type ListTagsOpts struct { } func ListTags(client *golangsdk.ServiceClient, opts ListTagsOpts) ([]string, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("cloudimages", "tags").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v1/cloudimages/tags - raw, err := client.Get(client.ServiceURL("cloudimages", "tags")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/ims/v2/images/ListImages.go b/openstack/ims/v2/images/ListImages.go index 1867da8df..2f9dd5c4c 100644 --- a/openstack/ims/v2/images/ListImages.go +++ b/openstack/ims/v2/images/ListImages.go @@ -153,13 +153,13 @@ type ListImagesOpts struct { // ListImages This API is used to query images using search criteria and to display the images in a list. func ListImages(client *golangsdk.ServiceClient, opts ListImagesOpts) ([]ImageInfo, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("cloudimages").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/cloudimages - raw, err := client.Get(client.ServiceURL("cloudimages")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/lts/v2/transfers/DeleteTransfer.go b/openstack/lts/v2/transfers/DeleteTransfer.go index 551fed892..daaa1e417 100644 --- a/openstack/lts/v2/transfers/DeleteTransfer.go +++ b/openstack/lts/v2/transfers/DeleteTransfer.go @@ -2,9 +2,18 @@ package transfers import "github.com/opentelekomcloud/gophertelekomcloud" +type deleteOpts struct { + LogTransferId string `q:"log_transfer_id"` +} + func DeleteTransfer(client *golangsdk.ServiceClient, transferId string) (err error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints("transfers").WithQueryParams(&deleteOpts{LogTransferId: transferId}).Build() + if err != nil { + return err + } + // DELETE /v2/{project_id}/transfers - _, err = client.Delete(client.ServiceURL("transfers")+"?log_transfer_id="+transferId, &golangsdk.RequestOpts{ + _, err = client.Delete(client.ServiceURL(url.String()), &golangsdk.RequestOpts{ OkCodes: []int{200}, MoreHeaders: map[string]string{"Content-Type": "application/json"}, }) diff --git a/openstack/lts/v2/transfers/ListTransfers.go b/openstack/lts/v2/transfers/ListTransfers.go index faa47b1f8..b15443e4a 100644 --- a/openstack/lts/v2/transfers/ListTransfers.go +++ b/openstack/lts/v2/transfers/ListTransfers.go @@ -42,13 +42,13 @@ type ListTransfersOpts struct { } func ListTransfers(client *golangsdk.ServiceClient, opts ListTransfersOpts) ([]Transfer, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("transfers").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/{project_id}/transfers - raw, err := client.Get(client.ServiceURL("transfers")+q.String(), nil, &golangsdk.RequestOpts{ + raw, err := client.Get(client.ServiceURL(url.String()), nil, &golangsdk.RequestOpts{ MoreHeaders: map[string]string{"Content-Type": "application/json"}, }) if err != nil { diff --git a/openstack/mrs/v1/cluster/List.go b/openstack/mrs/v1/cluster/List.go index 92694ea47..7cb06d8f1 100644 --- a/openstack/mrs/v1/cluster/List.go +++ b/openstack/mrs/v1/cluster/List.go @@ -31,13 +31,13 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("cluster_infos").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v1.1/{project_id}/cluster_infos - raw, err := client.Get(client.ServiceURL("cluster_infos")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/mrs/v1/cluster/ListHosts.go b/openstack/mrs/v1/cluster/ListHosts.go index 14cc90885..39b465c82 100644 --- a/openstack/mrs/v1/cluster/ListHosts.go +++ b/openstack/mrs/v1/cluster/ListHosts.go @@ -19,13 +19,13 @@ type ListHostsOpts struct { } func ListHosts(client *golangsdk.ServiceClient, opts ListHostsOpts) (*ListHostsResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("clusters", opts.ClusterId, "hosts").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v1.1/{project_id}/clusters/{cluster_id}/hosts - raw, err := client.Get(client.ServiceURL("clusters", opts.ClusterId, "hosts")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/rds/v3/backups/List.go b/openstack/rds/v3/backups/List.go index ce2e12cd5..e6cbc1164 100644 --- a/openstack/rds/v3/backups/List.go +++ b/openstack/rds/v3/backups/List.go @@ -35,13 +35,13 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Backup, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("backups").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/backups - raw, err := client.Get(client.ServiceURL("backups")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/rds/v3/backups/ListRestoreTimes.go b/openstack/rds/v3/backups/ListRestoreTimes.go index 9ededb727..177ac5921 100644 --- a/openstack/rds/v3/backups/ListRestoreTimes.go +++ b/openstack/rds/v3/backups/ListRestoreTimes.go @@ -14,13 +14,13 @@ type ListRestoreTimesOpts struct { } func ListRestoreTimes(client *golangsdk.ServiceClient, opts ListRestoreTimesOpts) ([]RestoreTime, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances", opts.InstanceId, "restore-time").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/instances/{instance_id}/restore-time - raw, err := client.Get(client.ServiceURL("instances", opts.InstanceId, "restore-time")+q.String(), nil, openstack.StdRequestOpts()) + raw, err := client.Get(client.ServiceURL(url.String()), nil, openstack.StdRequestOpts()) if err != nil { return nil, err } diff --git a/openstack/rds/v3/flavors/ListFlavors.go b/openstack/rds/v3/flavors/ListFlavors.go index 227472b6b..c709226e2 100644 --- a/openstack/rds/v3/flavors/ListFlavors.go +++ b/openstack/rds/v3/flavors/ListFlavors.go @@ -24,12 +24,12 @@ type ListOpts struct { func ListFlavors(client *golangsdk.ServiceClient, opts ListOpts) ([]Flavor, error) { // GET https://{Endpoint}/v3/{project_id}/flavors/{database_name} - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("flavors", opts.DatabaseName).WithQueryParams(&opts).Build() if err != nil { return nil, err } - raw, err := client.Get(client.ServiceURL("flavors", opts.DatabaseName)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/rds/v3/flavors/ListStorageTypes.go b/openstack/rds/v3/flavors/ListStorageTypes.go index a0621df86..9d93747c2 100644 --- a/openstack/rds/v3/flavors/ListStorageTypes.go +++ b/openstack/rds/v3/flavors/ListStorageTypes.go @@ -16,13 +16,13 @@ type ListStorageTypesOpts struct { } func ListStorageTypes(client *golangsdk.ServiceClient, opts ListStorageTypesOpts) (*ListStorageTypesResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("storage-type", opts.DatabaseName).WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/storage-type/{database_name} - raw, err := client.Get(client.ServiceURL("storage-type", opts.DatabaseName)+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/rds/v3/instances/List.go b/openstack/rds/v3/instances/List.go index 98e49d427..a8ee65ed4 100644 --- a/openstack/rds/v3/instances/List.go +++ b/openstack/rds/v3/instances/List.go @@ -35,13 +35,13 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListResponse, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("instances").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET https://{Endpoint}/v3/{project_id}/instances - raw, err := client.Get(client.ServiceURL("instances")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/swr/v2/domains/ListSharedReposDetails.go b/openstack/swr/v2/domains/ListSharedReposDetails.go index df72ef5d2..2660f9984 100644 --- a/openstack/swr/v2/domains/ListSharedReposDetails.go +++ b/openstack/swr/v2/domains/ListSharedReposDetails.go @@ -18,13 +18,13 @@ type ListSharedReposOpts struct { } func ListSharedReposDetails(client *golangsdk.ServiceClient, opts ListSharedReposOpts) ([]AccessDomain, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("manage", "shared-repositories").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/manage/shared-repositories - raw, err := client.Get(client.ServiceURL("manage", "shared-repositories")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/swr/v2/organizations/List.go b/openstack/swr/v2/organizations/List.go index f2e2a02d9..aa9aee485 100644 --- a/openstack/swr/v2/organizations/List.go +++ b/openstack/swr/v2/organizations/List.go @@ -11,13 +11,13 @@ type ListOpts struct { } func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Organization, error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("manage", "namespaces").WithQueryParams(&opts).Build() if err != nil { return nil, err } // GET /v2/manage/namespaces - raw, err := client.Get(client.ServiceURL("manage", "namespaces")+q.String(), nil, nil) + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) if err != nil { return nil, err } diff --git a/openstack/waf-premium/v1/hosts/Delete.go b/openstack/waf-premium/v1/hosts/Delete.go index 14a93226b..48f43403d 100644 --- a/openstack/waf-premium/v1/hosts/Delete.go +++ b/openstack/waf-premium/v1/hosts/Delete.go @@ -9,11 +9,12 @@ type DeleteOpts struct { } func Delete(client *golangsdk.ServiceClient, id string, opts DeleteOpts) (err error) { - q, err := golangsdk.BuildQueryString(opts) + url, err := golangsdk.NewURLBuilder().WithEndpoints("premium-waf", "host", id).WithQueryParams(&opts).Build() if err != nil { - return + return err } - _, err = client.Delete(client.ServiceURL("premium-waf", "host", id)+q.String(), &golangsdk.RequestOpts{ + + _, err = client.Delete(client.ServiceURL(url.String()), &golangsdk.RequestOpts{ OkCodes: []int{200}, MoreHeaders: map[string]string{"Content-Type": "application/json;charset=utf8"}, }) From ac0c9545fc488c112c61ec4dc972317ac345d848 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Thu, 11 Apr 2024 10:42:53 +0200 Subject: [PATCH 04/11] fix url check and added documentation for the public methods --- params.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/params.go b/params.go index 93fa2b0ce..bb9f59138 100644 --- a/params.go +++ b/params.go @@ -376,6 +376,7 @@ func BuildQueryString(opts interface{}) (*url.URL, error) { return nil, fmt.Errorf("options type is not a struct") } +// URL is a representation for the url.URL from the standard library type URL struct { u *url.URL } @@ -384,21 +385,34 @@ func (u *URL) String() string { return u.u.String() } +// URLBuilder provides ability to build custom url with query parameters. type URLBuilder struct { endpoints []string params interface{} } +// WithEndpoints accept strings and build url path +// Example: WithEndpoints("foo", "bar") will be modified to url with path "foo/bar" +// Characters /!?$#=&+_ are not allowed in the endpoints. func (ub *URLBuilder) WithEndpoints(endpoints ...string) *URLBuilder { ub.endpoints = endpoints return ub } +// WithQueryParams accept a struct and build query parameters for url. +// Example: +// +// type exampleStruct struct { +// TaskID string `q:"task_id"` +// } +// +// WithQueryParams(&exampleStruct{TaskID: "12345"}) will be modified to query parameters "?task_id=12345" func (ub *URLBuilder) WithQueryParams(params interface{}) *URLBuilder { ub.params = params return ub } +// Build constructs and return url. func (ub *URLBuilder) Build() (*URL, error) { var u url.URL @@ -413,7 +427,7 @@ func (ub *URLBuilder) Build() (*URL, error) { } for _, e := range ub.endpoints { - if strings.ContainsAny(e, "/!?$#=&+_") { + if strings.ContainsAny(e, "/!?$#=&+") { return nil, fmt.Errorf("characters '/!?$#=&+_\"' are not possible in endpoints") } } @@ -427,6 +441,7 @@ func (ub *URLBuilder) Build() (*URL, error) { return &URL{u: &u}, nil } +// NewURLBuilder is the constructor for a struct URLBuilder func NewURLBuilder() *URLBuilder { return &URLBuilder{} } From 1d62a9f26dfa36299d5dbbf903b659b61342c666 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 10 Apr 2024 10:09:05 +0200 Subject: [PATCH 05/11] first dataart api implementation --- openstack/dataarts/v1.1/cluster/Create.go | 109 +++++--- openstack/dataarts/v1.1/cluster/Delete.go | 30 ++- openstack/dataarts/v1.1/cluster/Get.go | 25 +- openstack/dataarts/v1.1/cluster/List.go | 20 ++ openstack/dataarts/v1.1/cluster/Restart.go | 54 +++- openstack/dataarts/v1.1/cluster/Start.go | 37 ++- openstack/dataarts/v1.1/cluster/Stop.go | 49 ++-- openstack/dataarts/v1.1/cluster/common.go | 28 ++ .../dataarts/v1.1/{job => factory}/Get.go | 2 +- .../v1.1/factory/connection/Create.go | 244 ++++++++++++++++++ .../dataarts/v1.1/factory/connection/Get.go | 25 ++ .../dataarts/v1.1/factory/connection/List.go | 26 ++ 12 files changed, 535 insertions(+), 114 deletions(-) create mode 100644 openstack/dataarts/v1.1/cluster/List.go create mode 100644 openstack/dataarts/v1.1/cluster/common.go rename openstack/dataarts/v1.1/{job => factory}/Get.go (98%) create mode 100644 openstack/dataarts/v1.1/factory/connection/Create.go create mode 100644 openstack/dataarts/v1.1/factory/connection/Get.go create mode 100644 openstack/dataarts/v1.1/factory/connection/List.go diff --git a/openstack/dataarts/v1.1/cluster/Create.go b/openstack/dataarts/v1.1/cluster/Create.go index 5bc6b6cb4..d18b05ade 100644 --- a/openstack/dataarts/v1.1/cluster/Create.go +++ b/openstack/dataarts/v1.1/cluster/Create.go @@ -1,8 +1,6 @@ package cluster import ( - "net/http" - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/build" "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" @@ -10,62 +8,97 @@ import ( ) type CreateOpts struct { - Cluster Cluster `json:"cluster" required:"true"` - AutoRemind *bool `json:"auto_remind,omitempty"` - PhoneNum string `json:"phone_num,omitempty"` - Email string `json:"email,omitempty"` + Cluster Cluster `json:"cluster" required:"true"` + // AutoRemind Whether to enable message notification. + // If you enable this function, you can configure a maximum of five mobile numbers or email addresses. + // You will be notified of table/file migration job failures and EIP exceptions by SMS message or email. + AutoRemind bool `json:"auto_remind,omitempty"` + // PhoneNum Mobile number for receiving notifications. + PhoneNum string `json:"phone_num,omitempty"` + // Email address for receiving notifications. + Email string `json:"email,omitempty"` } type Cluster struct { - ScheduleBootTime string `json:"scheduleBootTime,omitempty"` - IsScheduleBootOff *bool `json:"isScheduleBootOff,omitempty"` - Instances []Instance `json:"instances,omitempty"` - DataStore *Datastore `json:"datastore,omitempty"` - ExtendedProperties *ExtendedProp `json:"extended_properties,omitempty"` - ScheduleOffTime string `json:"scheduleOffTime,omitempty"` - VpcId string `json:"vpcId,omitempty"` - Name string `json:"name,omitempty"` - SysTags []tag.ResourceTag `json:"sys_tags,omitempty"` - IsAutoOff *bool `json:"isAutoOff"` + // ScheduleBootTime Time for scheduled startup of a CDM cluster. The CDM cluster starts at this time every day. + ScheduleBootTime string `json:"scheduleBootTime,omitempty"` + // IsScheduleBootOff Whether to enable scheduled startup/shutdown. The scheduled startup/shutdown and auto shutdown functions cannot be enabled at the same time. + IsScheduleBootOff *bool `json:"isScheduleBootOff,omitempty"` + // Instances Node list. + Instances []Instance `json:"instances,omitempty"` + // DataStore Cluster information. + DataStore *Datastore `json:"datastore,omitempty"` + // ExtendedProperties Extended attribute. + ExtendedProperties *ExtendedProp `json:"extended_properties,omitempty"` + // ScheduleOffTime Time for scheduled shutdown of a CDM cluster. The CDM cluster shuts down directly at this time every day without waiting for unfinished jobs to complete. + ScheduleOffTime string `json:"scheduleOffTime,omitempty"` + // VpcId VPC ID, which is used for configuring a network for the cluster. + VpcId string `json:"vpcId,omitempty"` + // Name Cluster name. + Name string `json:"name,omitempty"` + // SysTags Enterprise project information. For details, see the descriptions of sys_tags parameters. + SysTags []tag.ResourceTag `json:"sys_tags,omitempty"` + // IsAutoOff Whether to enable auto shutdown. The auto shutdown and scheduled startup/shutdown functions cannot be enabled at the same time. + // When auto shutdown is enabled, if no job is running in the cluster and no scheduled job is available, a cluster will be automatically shut down 15 minutes after it starts running, which reduces costs for you. + IsAutoOff bool `json:"isAutoOff,omitempty"` } type Instance struct { - AZ string `json:"availability_zone" required:"true"` - Nics []Nic `json:"nics" required:"true"` + // AZ availability zone where a cluster is located. + AZ string `json:"availability_zone" required:"true"` + // Nics NIC list. A maximum of two NICs are supported. For details, see the descriptions of nics parameters. + Nics []Nic `json:"nics" required:"true"` + // FlavorRef Instance flavor. FlavorRef string `json:"flavorRef" required:"true"` - Type string `json:"type" required:"true"` + // Type Node type. Currently, only cdm is available. + Type string `json:"type" required:"true"` +} + +type Nic struct { + // SecurityGroupId Security group ID. + SecurityGroupId string `json:"securityGroupId" required:"true"` + // NetId Subnet ID. + NetId string `json:"net-id" required:"true"` } type Datastore struct { - Type string `json:"type,omitempty"` + // Type Generally, the value is cdm. + Type string `json:"type,omitempty"` + // Version Cluster version. Version string `json:"version,omitempty"` } type ExtendedProp struct { + // WorkSpaceId Workspace ID. WorkSpaceId string `json:"workSpaceId,omitempty"` - ResourceId string `json:"resourceId,omitempty"` - Trial string `json:"trial,omitempty"` + // ResourceId Resource ID. + ResourceId string `json:"resourceId,omitempty"` + // Trial Whether the cluster is a trial cluster. + Trial string `json:"trial,omitempty"` } -type Nic struct { - SecurityGroupId string `json:"securityGroupId" required:"true"` - NetId string `json:"net-id" required:"true"` -} - -func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*ClusterResponse, error) { +// Create is used to create a cluster. +// Send request POST /v1.1/{project_id}/clusters +func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*ClusterResp, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - // POST /v1.1/{project_id}/clusters raw, err := client.Post(client.ServiceURL("clusters"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, }) - return extra(err, raw) + + if err != nil { + return nil, err + } + + var res *ClusterResp + err = extract.Into(raw.Body, res) + return res, err } -type ClusterResponse struct { +type ClusterResp struct { Name string `json:"name"` Id string `json:"id"` Task Task `json:"task"` @@ -79,18 +112,8 @@ type Task struct { } type InstanceResp struct { - Name string `json:"name"` Id string `json:"id"` + Name string `json:"name"` Type string `json:"type"` ShardId string `json:"shard_id"` } - -func extra(err error, raw *http.Response) (*ClusterResponse, error) { - if err != nil { - return nil, err - } - - var res ClusterResponse - err = extract.Into(raw.Body, &res) - return &res, err -} diff --git a/openstack/dataarts/v1.1/cluster/Delete.go b/openstack/dataarts/v1.1/cluster/Delete.go index b1925a8d0..8a61c27cc 100644 --- a/openstack/dataarts/v1.1/cluster/Delete.go +++ b/openstack/dataarts/v1.1/cluster/Delete.go @@ -1,12 +1,28 @@ package cluster -import "github.com/opentelekomcloud/gophertelekomcloud" +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) -func Delete(client *golangsdk.ServiceClient, id string) (err error) { - // DELETE /v1.1/{project_id}/clusters/{cluster_id} - type KeepBackup struct { - KeepBackup int `json:"keep_last_manual_backup"` +type DeleteOpts struct { + // KeepBackup Number of backup log files. Retain the default value 0. + KeepBackup int `json:"keep_last_manual_backup"` +} + +// Delete is used to create a cluster. +// Send request DELETE /v1.1/{project_id}/clusters/{cluster_id} +func Delete(client *golangsdk.ServiceClient, id string, jsonOpts DeleteOpts) (*JobId, error) { + b, err := build.RequestBody(jsonOpts, "") + if err != nil { + return nil, err } - _, err = client.DeleteWithBody(client.ServiceURL("clusters", id), KeepBackup{KeepBackup: 0}, nil) - return + + r, err := client.DeleteWithBody(client.ServiceURL("clusters", id), b, nil) + + var resp *JobId + err = extract.Into(r.Body, resp) + + return resp, err } diff --git a/openstack/dataarts/v1.1/cluster/Get.go b/openstack/dataarts/v1.1/cluster/Get.go index ad33eb6ae..3565ba845 100644 --- a/openstack/dataarts/v1.1/cluster/Get.go +++ b/openstack/dataarts/v1.1/cluster/Get.go @@ -1,30 +1,25 @@ package cluster import ( - "net/http" - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" ) +// Get is used to query cluster details. +// Send request GET /v1.1/{project_id}/clusters/{cluster_id} func Get(client *golangsdk.ServiceClient, clusterId string) (*ClusterQuery, error) { - // GET /v1.1/{project_id}/clusters/{cluster_id} raw, err := client.Get(client.ServiceURL("clusters", clusterId), nil, nil) - return extraResp(err, raw) -} - -func extraResp(err error, raw *http.Response) (*ClusterQuery, error) { if err != nil { return nil, err } - var res ClusterQuery - err = extract.Into(raw.Body, &res) - return &res, err + var res *ClusterQuery + err = extract.Into(raw.Body, res) + return res, err } type ClusterQuery struct { - PublicEndpoint string `json:"public_endpoint"` + PublicEndpoint string `json:"publicEndpoint"` Instances []DetailedInstances `json:"instances"` SecurityGroupId string `json:"security_group_id"` SubnetId string `json:"subnet_id"` @@ -66,9 +61,9 @@ type DetailedInstances struct { Volume Volume `json:"volume"` Status string `json:"status"` Actions []string `json:"actions"` - Type string `json:"string"` - Name string `json:"name"` + Type string `json:"type"` Id string `json:"id"` + Name string `json:"name"` IsFrozen string `json:"isFrozen"` Components string `json:"components"` ConfigStatus string `json:"config_status"` @@ -115,7 +110,7 @@ type CustomerConfig struct { } type MaintainWindow struct { - Dat string `json:"day"` + Day string `json:"day"` StartTime string `json:"startTime"` EndTime string `json:"endTime"` } @@ -130,8 +125,8 @@ type FailedReasons struct { } type CreateFailed struct { - ErrorMsg string `json:"errorMsg"` ErrorCode string `json:"errorCode"` + ErrorMsg string `json:"errorMsg"` } type ClusterLinks struct { diff --git a/openstack/dataarts/v1.1/cluster/List.go b/openstack/dataarts/v1.1/cluster/List.go new file mode 100644 index 000000000..684d6ee70 --- /dev/null +++ b/openstack/dataarts/v1.1/cluster/List.go @@ -0,0 +1,20 @@ +package cluster + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// List Querying the Cluster List. +// Send request GET /v1.1/{project_id}/clusters +func List(client *golangsdk.ServiceClient) ([]*ClusterQuery, error) { + + raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) + if err != nil { + return nil, err + } + + var res []*ClusterQuery + err = extract.IntoSlicePtr(raw.Body, &res, "clusters") + return res, err +} diff --git a/openstack/dataarts/v1.1/cluster/Restart.go b/openstack/dataarts/v1.1/cluster/Restart.go index 47fc3e593..4454e404c 100644 --- a/openstack/dataarts/v1.1/cluster/Restart.go +++ b/openstack/dataarts/v1.1/cluster/Restart.go @@ -5,28 +5,58 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud/internal/build" ) +const ( + RestartImmediately = "IMMEDIATELY" + RestartForcely = "FORCELY" + RestartSoftly = "SOFTLY" +) + type RestartOpts struct { - Id string `json:"-"` + // Restart Cluster restart. For details about how to define the cluster to restart, see RestartStruct. Restart RestartStruct `json:"restart" required:"true"` } type RestartStruct struct { - StopMode int `json:"restartDelayTime,omitempty"` - RestartMode string `json:"restartMode,omitempty"` + // RestartDelayTime Restart delay, in seconds. + RestartDelayTime int `json:"restartDelayTime,omitempty"` + // Restart mode + // IMMEDIATELY: immediate restart + // FORCELY: forcible restart + // SOFTLY: common restart + // The default value is IMMEDIATELY. Forcibly restarting the service process will interrupt the service process and restart the VMs in the cluster. + RestartMode string `json:"restartMode,omitempty"` + // RestartLevel Restart level + // SERVICE: service restart + // VM: VM restart + // The default value is SERVICE. RestartLevel string `json:"restartLevel,omitempty"` - Type string `json:"type,omitempty"` - Instance string `json:"instance,omitempty"` - Group string `json:"group,omitempty"` + // Type Type of the cluster to be restarted. The value can be set to cdm only. + Type string `json:"type,omitempty"` + // Instance Reserved field. When restartLevel is set to SERVICE, this parameter is mandatory and an empty string should be entered. + Instance string `json:"instance,omitempty"` + // Reserved field. When restartLevel is set to SERVICE, this parameter is mandatory and an empty string should be entered. + Group string `json:"group,omitempty"` } -func Restart(client *golangsdk.ServiceClient, opts RestartOpts) (*JobId, error) { +// Restart is used to restart a cluster. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/action +func Restart(client *golangsdk.ServiceClient, clusterId string, opts RestartOpts) (*JobId, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - // POST /v1.1/{project_id}/clusters/{cluster_id}/action - raw, err := client.Post(client.ServiceURL("clusters", opts.Id, "action"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, - }) - return extraJob(err, raw) + + resp, err := client.Post( + client.ServiceURL("clusters", clusterId, "action"), + b, + nil, + &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + }, + ) + if err != nil { + return nil, err + } + + return respToJobId(resp) } diff --git a/openstack/dataarts/v1.1/cluster/Start.go b/openstack/dataarts/v1.1/cluster/Start.go index 3088d1082..d5db22590 100644 --- a/openstack/dataarts/v1.1/cluster/Start.go +++ b/openstack/dataarts/v1.1/cluster/Start.go @@ -2,20 +2,35 @@ package cluster import ( golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" ) -func Start(client *golangsdk.ServiceClient, id string) (*JobId, error) { - type Start struct { - Start *EmptyObj `json:"start"` +type StartOpts struct { + // Start Starting a cluster. This parameter is an empty object. + Start *EmptyStruct `json:"start"` +} + +type EmptyStruct struct{} + +// Start is used to start a cluster. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/action +func Start(client *golangsdk.ServiceClient, clusterId string, startOpts *StartOpts) (*JobId, error) { + b, err := build.RequestBody(startOpts, "") + if err != nil { + return nil, err } - // POST /v1.1/{project_id}/clusters/{cluster_id}/action - raw, err := client.Post(client.ServiceURL("clusters", id, "action"), Start{}, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, - }) - return extraJob(err, raw) -} + resp, err := client.Post( + client.ServiceURL("clusters", clusterId, "action"), + b, + nil, + &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + }, + ) + if err != nil { + return nil, err + } -type EmptyObj struct { - Obj *string `json:"-"` + return respToJobId(resp) } diff --git a/openstack/dataarts/v1.1/cluster/Stop.go b/openstack/dataarts/v1.1/cluster/Stop.go index 14d889add..420c674e6 100644 --- a/openstack/dataarts/v1.1/cluster/Stop.go +++ b/openstack/dataarts/v1.1/cluster/Stop.go @@ -1,45 +1,44 @@ package cluster import ( - "net/http" - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/build" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + StopImmediately = "IMMEDIATELY" + StopGracefully = "GRACEFULLY" ) type StopOpts struct { - Id string `json:"-"` + // Stop Cluster stop operation, which defines the parameters for stopping a cluster. Stop StopStruct `json:"stop" required:"true"` } type StopStruct struct { - StopMode string `json:"stopMode,omitempty"` - DelayTime string `json:"delayTime,omitempty"` + // StopMode should be StopImmediately or StopGracefully + StopMode string `json:"stopMode,omitempty"` + // DelayTime Stop delay, in seconds. + // This parameter is valid only when stopMode is set to GRACEFULLY. + // If the value of this parameter is set to -1, the system waits for all jobs to complete and stops accepting new jobs. + // If the value of this parameter is greater than 0, the system stops the cluster after the specified time and stops accepting new jobs. + DelayTime int `json:"delayTime,omitempty"` } -func Stop(client *golangsdk.ServiceClient, opts StopOpts) (*JobId, error) { +// Stop is used to stop a cluster. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/action +func Stop(client *golangsdk.ServiceClient, clusterId string, opts StopOpts) (*JobId, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - // POST /v1.1/{project_id}/clusters/{cluster_id}/action - raw, err := client.Post(client.ServiceURL("clusters", opts.Id, "action"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", "X-Language": "en"}, - }) - return extraJob(err, raw) -} - -type JobId struct { - JobId []string `json:"jobId"` -} - -func extraJob(err error, raw *http.Response) (*JobId, error) { - if err != nil { - return nil, err - } - var res JobId - err = extract.Into(raw.Body, &res) - return &res, err + raw, err := client.Post( + client.ServiceURL("clusters", clusterId, "action"), + b, + nil, + &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + }) + return respToJobId(raw) } diff --git a/openstack/dataarts/v1.1/cluster/common.go b/openstack/dataarts/v1.1/cluster/common.go new file mode 100644 index 000000000..e71320562 --- /dev/null +++ b/openstack/dataarts/v1.1/cluster/common.go @@ -0,0 +1,28 @@ +package cluster + +import ( + "net/http" + + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + HeaderXLanguage = "X-Language" + RequestedLang = "en" +) + +type JobId struct { + JobId string `json:"jobId"` +} + +func respToJobId(r *http.Response) (*JobId, error) { + var res *JobId + err := extract.Into(r.Body, res) + return res, err +} + +func respToJobIdSlice(r *http.Response) (*JobId, error) { + var res *JobId + err := extract.Into(r.Body, res) + return res, err +} diff --git a/openstack/dataarts/v1.1/job/Get.go b/openstack/dataarts/v1.1/factory/Get.go similarity index 98% rename from openstack/dataarts/v1.1/job/Get.go rename to openstack/dataarts/v1.1/factory/Get.go index a4daa1d53..ff09f6368 100644 --- a/openstack/dataarts/v1.1/job/Get.go +++ b/openstack/dataarts/v1.1/factory/Get.go @@ -1,4 +1,4 @@ -package job +package factory import ( "github.com/opentelekomcloud/gophertelekomcloud" diff --git a/openstack/dataarts/v1.1/factory/connection/Create.go b/openstack/dataarts/v1.1/factory/connection/Create.go new file mode 100644 index 000000000..dbc281142 --- /dev/null +++ b/openstack/dataarts/v1.1/factory/connection/Create.go @@ -0,0 +1,244 @@ +package connection + +import ( + "encoding/json" + "fmt" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + TypeDWS = "DWS" + TypeDLI = "DLI" + TypeSparkSQL = "SparkSQL" + TypeHive = "HIVE" + TypeRDS = "RDS" + TypeCloudTable = "CloudTable" + TypeHOST = "HOST" +) + +const ( + MethodAgent = "agent" + MethodDirect = "direct" +) + +const HeaderWorkspace = "workspace" + +type Config struct { + // Connection name. The name contains a maximum of 100 characters, including only letters, numbers, hyphens (-), and underscores (_). + // The connection name must be unique. + Name string `json:"name" required:"true"` + // Connection type. Should be one of: DWS, DLI, SparkSQL, HIVE, RDS, CloudTable, HOST. + Type string `json:"type" required:"true"` + // Connection configuration item. The configuration item varies with the connection type. + // You do not need to set the config parameter for DLI connections. + // For other types of connections, see the description of connection configuration items. + Config interface{} `json:"config,omitempty"` + // Description of the connection. The description contains a maximum of 255 characters. + Description string `json:"description,omitempty"` +} + +func (c *Config) UnmarshalJSON(data []byte) error { + var obj map[string]json.RawMessage + + if err := json.Unmarshal(data, &obj); err != nil { + return err + } + + n, ok := obj["name"] + if !ok { + return fmt.Errorf("missed field in json, field: name") + } + + if err := json.Unmarshal(n, &c.Name); err != nil { + return err + } + + t, ok := obj["type"] + if !ok { + return fmt.Errorf("missed field in json, field: type") + } + + if err := json.Unmarshal(t, &c.Type); err != nil { + return err + } + + if d, ok := obj["description"]; ok { + if err := json.Unmarshal(d, &c.Description); err != nil { + return err + } + } + + switch c.Type { + case TypeDWS: + d := &DWSConfig{} + if err := json.Unmarshal(obj["config"], d); err != nil { + return err + } + c.Config = *d + case TypeDLI: + // There aren't any configurations for DLI type. + return nil + case TypeSparkSQL: + s := &SparkConfig{} + if err := json.Unmarshal(obj["config"], s); err != nil { + return err + } + c.Config = *s + case TypeHive: + h := &HiveConfig{} + if err := json.Unmarshal(obj["config"], h); err != nil { + return err + } + c.Config = *h + case TypeRDS: + r := &RDSConfig{} + if err := json.Unmarshal(obj["config"], r); err != nil { + return err + } + c.Config = *r + case TypeCloudTable: + ct := &CloudTableConfig{} + if err := json.Unmarshal(obj["config"], ct); err != nil { + return err + } + c.Config = *ct + case TypeHOST: + h := &HOSTConfig{} + if err := json.Unmarshal(obj["config"], h); err != nil { + return err + } + c.Config = *h + default: + return fmt.Errorf("connection type is not supported") + } + + return nil +} + +type DWSConfig struct { + // Name of a DWS cluster. + ClusterName string `json:"clusterName,omitempty"` + // IP address for accessing the DWS cluster. + IP string `json:"ip,omitempty"` + // Port for accessing the DWS cluster. + Port string `json:"port,omitempty"` + // Username of the database. This username is the username entered during the creation of the DWS cluster. + Username string `json:"userName" required:"true"` + // Password for accessing the database. This password is the password entered during the creation of the DWS cluster. + Password string `json:"password" required:"true"` + // Specifies whether to enable the SSL connection. + SSLEnable bool `json:"sslEnable" required:"true"` + // Name of a KMS key. + KMSKey string `json:"kmsKey" required:"true"` + // Name of a CDM cluster. + AgentName string `json:"agentName" required:"true"` +} + +type SparkConfig struct { + // Name of an MRS cluster. + ClusterName string `json:"clusterName" required:"true"` + // Method to connect. + // agent: connected through an agent. + // direct: connected directly. + ConnectionMethod string `json:"connectionMethod" required:"true"` + // Username of the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Username string `json:"userName,omitempty"` + // Password for accessing the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Password string `json:"password,omitempty"` + // Name of a CDM cluster. This parameter is mandatory when connectionMethod is set to agent. + AgentName string `json:"agentName,omitempty"` + // Name of a KMS key. This parameter is mandatory when connectionMethod is set to agent. + KMSKey string `json:"kmsKey,omitempty"` +} + +type HiveConfig struct { + // Name of an MRS cluster. + ClusterName string `json:"clusterName" required:"true"` + // Method to connect. + // agent: connected through an agent. + // direct: connected directly. + ConnectionMethod string `json:"connectionMethod" required:"true"` + // Username of the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Username string `json:"userName,omitempty"` + // Password for accessing the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. + Password string `json:"password,omitempty"` + // Name of a CDM cluster. This parameter is mandatory when connectionMethod is set to agent. + AgentName string `json:"agentName,omitempty"` + // Name of a KMS key. This parameter is mandatory when connectionMethod is set to agent. + KMSKey string `json:"kmsKey,omitempty"` +} + +type RDSConfig struct { + // Address for accessing RDS. + IP string `json:"ip" required:"true"` + // Port for accessing RDS. + Port string `json:"port" required:"true"` + // Username of the database. This username is the username entered during the creation of the cluster. + Username string `json:"userName" required:"true"` + // Password for accessing the database. This password is the password entered during the creation of the cluster. + Password string `json:"password" required:"true"` + // Name of a CDM cluster. + AgentName string `json:"agentName" required:"true"` + // Name of a KMS key. + KMSKey string `json:"kmsKey" required:"true"` + // Name of the driver. + DriverName string `json:"driverName" required:"true"` + // Path of the driver on OBS. + DriverPath string `json:"driverPath" required:"true"` +} + +type CloudTableConfig struct { + // Name of a CloudTable cluster. + ClusterName string `json:"clusterName" required:"true"` +} + +type HOSTConfig struct { + // IP address of the host. + IP string `json:"ip" required:"true"` + // SSH port number of the host. + Port string `json:"port" required:"true"` + // Username for logging in to the host. + Username string `json:"userName" required:"true"` + // Password for logging in to the host. + Password string `json:"password" required:"true"` + // Name of a CDM cluster. + AgentName string `json:"agentName" required:"true"` + // Name of a KMS key. + KMSKey string `json:"kmsKey" required:"true"` +} + +// Create is used to create a connection. The supported connection types include DWS, DLI, Spark SQL, RDS, CloudTable, and Hive. +// Send request /v1/{project_id}/connections +func Create(client *golangsdk.ServiceClient, opts Config, workspace string) (*CreateResp, error) { + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + var reqOpts *golangsdk.RequestOpts + if workspace != "" { + reqOpts = &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderWorkspace: workspace}, + } + } + + raw, err := client.Post(client.ServiceURL("connections"), b, nil, reqOpts) + + if err != nil { + return nil, err + } + + var res *CreateResp + err = extract.Into(raw.Body, res) + return res, err +} + +type CreateResp struct { + // Error code + ErrorCode string `json:"error_code,omitempty"` + // Error message + ErrorMsg string `json:"error_msg,omitempty"` +} diff --git a/openstack/dataarts/v1.1/factory/connection/Get.go b/openstack/dataarts/v1.1/factory/connection/Get.go new file mode 100644 index 000000000..6428d49fc --- /dev/null +++ b/openstack/dataarts/v1.1/factory/connection/Get.go @@ -0,0 +1,25 @@ +package connection + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// Get is used to query configuration details of a specific connection. +// Send request GET /v1/{project_id}/connections/{connection_name} +func Get(client *golangsdk.ServiceClient, connectionName string, workspace string) (*Config, error) { + var opts *golangsdk.RequestOpts + if workspace != "" { + opts = &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderWorkspace: workspace}, + } + } + raw, err := client.Get(client.ServiceURL("clusters", connectionName), nil, opts) + if err != nil { + return nil, err + } + + var res *Config + err = extract.Into(raw.Body, res) + return res, err +} diff --git a/openstack/dataarts/v1.1/factory/connection/List.go b/openstack/dataarts/v1.1/factory/connection/List.go new file mode 100644 index 000000000..d02fa4fa6 --- /dev/null +++ b/openstack/dataarts/v1.1/factory/connection/List.go @@ -0,0 +1,26 @@ +package connection + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + URLParamOffset = "offset" + URLParamLimit = "limit" + URLParamConnectionName = "connectionName" +) + +// List is used to query a connection list. +// Send request GET /v1/{project_id}/connections?offset={offset}&limit={limit}&connectionName={connectionName} +func List(client *golangsdk.ServiceClient, urlParams map[string]string) ([]*Config, error) { + + raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) + if err != nil { + return nil, err + } + + var res []*Config + err = extract.IntoSlicePtr(raw.Body, &res, "clusters") + return res, err +} From 4ce423921c892c38267e3e48dc50f64465b64f62 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 17 Apr 2024 11:30:54 +0200 Subject: [PATCH 06/11] Added api for link management. --- openstack/dataarts/v1.1/cluster/Create.go | 6 +- openstack/dataarts/v1.1/cluster/Delete.go | 7 +- openstack/dataarts/v1.1/cluster/Get.go | 2 +- openstack/dataarts/v1.1/cluster/List.go | 2 +- openstack/dataarts/v1.1/cluster/Restart.go | 4 +- openstack/dataarts/v1.1/cluster/Start.go | 4 +- openstack/dataarts/v1.1/cluster/Stop.go | 4 +- openstack/dataarts/v1.1/cluster/common.go | 16 +- openstack/dataarts/v1.1/factory/Get.go | 55 ---- .../dataarts/v1.1/factory/connection/List.go | 26 -- openstack/dataarts/v1.1/job/CreateRandom.go | 251 ++++++++++++++++++ openstack/dataarts/v1.1/job/CreateSpecific.go | 53 ++++ openstack/dataarts/v1.1/job/Delete.go | 16 ++ openstack/dataarts/v1.1/job/Get.go | 46 ++++ openstack/dataarts/v1.1/job/GetHistory.go | 41 +++ openstack/dataarts/v1.1/job/GetStatus.go | 115 ++++++++ openstack/dataarts/v1.1/job/Start.go | 21 ++ openstack/dataarts/v1.1/job/Stop.go | 21 ++ openstack/dataarts/v1.1/job/Update.go | 36 +++ openstack/dataarts/v1.1/job/common.go | 30 +++ .../{v1.1 => v1}/factory/connection/Create.go | 38 ++- .../dataarts/v1/factory/connection/Delete.go | 24 ++ .../dataarts/v1/factory/connection/Export.go | 31 +++ .../{v1.1 => v1}/factory/connection/Get.go | 6 +- .../dataarts/v1/factory/connection/List.go | 37 +++ .../dataarts/v1/factory/connection/Update.go | 41 +++ 26 files changed, 805 insertions(+), 128 deletions(-) delete mode 100644 openstack/dataarts/v1.1/factory/Get.go delete mode 100644 openstack/dataarts/v1.1/factory/connection/List.go create mode 100644 openstack/dataarts/v1.1/job/CreateRandom.go create mode 100644 openstack/dataarts/v1.1/job/CreateSpecific.go create mode 100644 openstack/dataarts/v1.1/job/Delete.go create mode 100644 openstack/dataarts/v1.1/job/Get.go create mode 100644 openstack/dataarts/v1.1/job/GetHistory.go create mode 100644 openstack/dataarts/v1.1/job/GetStatus.go create mode 100644 openstack/dataarts/v1.1/job/Start.go create mode 100644 openstack/dataarts/v1.1/job/Stop.go create mode 100644 openstack/dataarts/v1.1/job/Update.go create mode 100644 openstack/dataarts/v1.1/job/common.go rename openstack/dataarts/{v1.1 => v1}/factory/connection/Create.go (89%) create mode 100644 openstack/dataarts/v1/factory/connection/Delete.go create mode 100644 openstack/dataarts/v1/factory/connection/Export.go rename openstack/dataarts/{v1.1 => v1}/factory/connection/Get.go (80%) create mode 100644 openstack/dataarts/v1/factory/connection/List.go create mode 100644 openstack/dataarts/v1/factory/connection/Update.go diff --git a/openstack/dataarts/v1.1/cluster/Create.go b/openstack/dataarts/v1.1/cluster/Create.go index d18b05ade..88141f33c 100644 --- a/openstack/dataarts/v1.1/cluster/Create.go +++ b/openstack/dataarts/v1.1/cluster/Create.go @@ -79,14 +79,14 @@ type ExtendedProp struct { // Create is used to create a cluster. // Send request POST /v1.1/{project_id}/clusters -func Create(client *golangsdk.ServiceClient, opts CreateOpts) (*ClusterResp, error) { +func Create(client *golangsdk.ServiceClient, opts CreateOpts, xLang string) (*ClusterResp, error) { b, err := build.RequestBody(opts, "") if err != nil { return nil, err } - raw, err := client.Post(client.ServiceURL("clusters"), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + raw, err := client.Post(client.ServiceURL(clustersURL), b, nil, &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson, HeaderXLanguage: xLang}, }) if err != nil { diff --git a/openstack/dataarts/v1.1/cluster/Delete.go b/openstack/dataarts/v1.1/cluster/Delete.go index 8a61c27cc..9f05565dd 100644 --- a/openstack/dataarts/v1.1/cluster/Delete.go +++ b/openstack/dataarts/v1.1/cluster/Delete.go @@ -11,7 +11,7 @@ type DeleteOpts struct { KeepBackup int `json:"keep_last_manual_backup"` } -// Delete is used to create a cluster. +// Delete is used to delete a cluster. // Send request DELETE /v1.1/{project_id}/clusters/{cluster_id} func Delete(client *golangsdk.ServiceClient, id string, jsonOpts DeleteOpts) (*JobId, error) { b, err := build.RequestBody(jsonOpts, "") @@ -19,7 +19,10 @@ func Delete(client *golangsdk.ServiceClient, id string, jsonOpts DeleteOpts) (*J return nil, err } - r, err := client.DeleteWithBody(client.ServiceURL("clusters", id), b, nil) + r, err := client.DeleteWithBody(client.ServiceURL(clustersURL, id), b, nil) + if err != nil { + return nil, err + } var resp *JobId err = extract.Into(r.Body, resp) diff --git a/openstack/dataarts/v1.1/cluster/Get.go b/openstack/dataarts/v1.1/cluster/Get.go index 3565ba845..c03a77b2f 100644 --- a/openstack/dataarts/v1.1/cluster/Get.go +++ b/openstack/dataarts/v1.1/cluster/Get.go @@ -8,7 +8,7 @@ import ( // Get is used to query cluster details. // Send request GET /v1.1/{project_id}/clusters/{cluster_id} func Get(client *golangsdk.ServiceClient, clusterId string) (*ClusterQuery, error) { - raw, err := client.Get(client.ServiceURL("clusters", clusterId), nil, nil) + raw, err := client.Get(client.ServiceURL(clustersURL, clusterId), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1.1/cluster/List.go b/openstack/dataarts/v1.1/cluster/List.go index 684d6ee70..e2db4571b 100644 --- a/openstack/dataarts/v1.1/cluster/List.go +++ b/openstack/dataarts/v1.1/cluster/List.go @@ -9,7 +9,7 @@ import ( // Send request GET /v1.1/{project_id}/clusters func List(client *golangsdk.ServiceClient) ([]*ClusterQuery, error) { - raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) + raw, err := client.Get(client.ServiceURL(clustersURL), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1.1/cluster/Restart.go b/openstack/dataarts/v1.1/cluster/Restart.go index 4454e404c..13cb38584 100644 --- a/openstack/dataarts/v1.1/cluster/Restart.go +++ b/openstack/dataarts/v1.1/cluster/Restart.go @@ -47,11 +47,11 @@ func Restart(client *golangsdk.ServiceClient, clusterId string, opts RestartOpts } resp, err := client.Post( - client.ServiceURL("clusters", clusterId, "action"), + client.ServiceURL(clustersURL, clusterId, actionEndpoint), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, }, ) if err != nil { diff --git a/openstack/dataarts/v1.1/cluster/Start.go b/openstack/dataarts/v1.1/cluster/Start.go index d5db22590..b470fc976 100644 --- a/openstack/dataarts/v1.1/cluster/Start.go +++ b/openstack/dataarts/v1.1/cluster/Start.go @@ -21,11 +21,11 @@ func Start(client *golangsdk.ServiceClient, clusterId string, startOpts *StartOp } resp, err := client.Post( - client.ServiceURL("clusters", clusterId, "action"), + client.ServiceURL(clustersURL, clusterId, actionEndpoint), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, }, ) if err != nil { diff --git a/openstack/dataarts/v1.1/cluster/Stop.go b/openstack/dataarts/v1.1/cluster/Stop.go index 420c674e6..56df28806 100644 --- a/openstack/dataarts/v1.1/cluster/Stop.go +++ b/openstack/dataarts/v1.1/cluster/Stop.go @@ -34,11 +34,11 @@ func Stop(client *golangsdk.ServiceClient, clusterId string, opts StopOpts) (*Jo } raw, err := client.Post( - client.ServiceURL("clusters", clusterId, "action"), + client.ServiceURL(clustersURL, clusterId, actionEndpoint), b, nil, &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{"Content-Type": "application/json", HeaderXLanguage: RequestedLang}, + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, }) return respToJobId(raw) } diff --git a/openstack/dataarts/v1.1/cluster/common.go b/openstack/dataarts/v1.1/cluster/common.go index e71320562..60a93bb99 100644 --- a/openstack/dataarts/v1.1/cluster/common.go +++ b/openstack/dataarts/v1.1/cluster/common.go @@ -7,10 +7,16 @@ import ( ) const ( - HeaderXLanguage = "X-Language" - RequestedLang = "en" + HeaderXLanguage = "X-Language" + HeaderContentType = "Content-Type" + + ApplicationJson = "application/json" ) +const clustersURL = "clusters" + +const actionEndpoint = "action" + type JobId struct { JobId string `json:"jobId"` } @@ -20,9 +26,3 @@ func respToJobId(r *http.Response) (*JobId, error) { err := extract.Into(r.Body, res) return res, err } - -func respToJobIdSlice(r *http.Response) (*JobId, error) { - var res *JobId - err := extract.Into(r.Body, res) - return res, err -} diff --git a/openstack/dataarts/v1.1/factory/Get.go b/openstack/dataarts/v1.1/factory/Get.go deleted file mode 100644 index 71cfc8b90..000000000 --- a/openstack/dataarts/v1.1/factory/Get.go +++ /dev/null @@ -1,55 +0,0 @@ -package factory - -import ( - "github.com/opentelekomcloud/gophertelekomcloud" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" - "github.com/opentelekomcloud/gophertelekomcloud/pagination" -) - -type GetQuery struct { - Filter string `q:"filter"` - PageNo int `q:"page_no"` - PageSize int `q:"page_size"` - JobType string `q:"jobType"` - ClusterId string - JobName string -} - -// Get returns 500 error, not usable -func Get(client *golangsdk.ServiceClient, opts GetQuery) ([]Job, error) { - url, err := golangsdk.NewURLBuilder().WithEndpoints("clusters", opts.ClusterId, "cdm", "job", opts.JobName).WithQueryParams(&opts).Build() - if err != nil { - return nil, err - } - - pages, err := pagination.NewPager(client, client.ServiceURL(url.String()), - func(r pagination.PageResult) pagination.Page { - return JobPage{pagination.LinkedPageBase{PageResult: r}} - }).AllPages() - if err != nil { - return nil, err - } - - allJobs, err := ExtractJobs(pages) - if err != nil { - return nil, err - } - - return allJobs, err -} - -func ExtractJobs(r pagination.Page) ([]Job, error) { - var res []Job - err := extract.IntoSlicePtr(r.(JobPage).Result.BodyReader(), &res, "jobs") - if err != nil { - return nil, err - } - return res, nil -} - -type Job struct { -} - -type JobPage struct { - pagination.LinkedPageBase -} diff --git a/openstack/dataarts/v1.1/factory/connection/List.go b/openstack/dataarts/v1.1/factory/connection/List.go deleted file mode 100644 index d02fa4fa6..000000000 --- a/openstack/dataarts/v1.1/factory/connection/List.go +++ /dev/null @@ -1,26 +0,0 @@ -package connection - -import ( - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" -) - -const ( - URLParamOffset = "offset" - URLParamLimit = "limit" - URLParamConnectionName = "connectionName" -) - -// List is used to query a connection list. -// Send request GET /v1/{project_id}/connections?offset={offset}&limit={limit}&connectionName={connectionName} -func List(client *golangsdk.ServiceClient, urlParams map[string]string) ([]*Config, error) { - - raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) - if err != nil { - return nil, err - } - - var res []*Config - err = extract.IntoSlicePtr(raw.Body, &res, "clusters") - return res, err -} diff --git a/openstack/dataarts/v1.1/job/CreateRandom.go b/openstack/dataarts/v1.1/job/CreateRandom.go new file mode 100644 index 000000000..566fb463d --- /dev/null +++ b/openstack/dataarts/v1.1/job/CreateRandom.go @@ -0,0 +1,251 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + NormalJob = "NORMAL_JOB" + BatchJob = "BATCH_JOB" + ScenarioJob = "SCENARIO_JOB" +) + +type CreateRandomOpts struct { + // Jobs is a jobs list. + Jobs []Job `json:"jobs" required:"true"` + // Clusters is a list of IDs of CDM clusters. The system selects a random cluster in running state from the specified clusters and creates and executes a migration job in the cluster. + Clusters []string `json:"clusters" required:"true"` +} + +// CreateRandom is used to create and execute a job in a random cluster. +// Send request POST /v1.1/{project_id}/clusters/job +func CreateRandom(client *golangsdk.ServiceClient, opts CreateRandomOpts, xLang string) (*JobResp, error) { + + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + HeaderContentType: ApplicationJson, + HeaderXLanguage: xLang, + }, + } + + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + raw, err := client.Post(client.ServiceURL(clustersEndpoint, jobEndpoint), b, nil, reqOpts) + + if err != nil { + return nil, err + } + + var resp *JobResp + err = extract.Into(raw.Body, resp) + return resp, err +} + +// Job represents a job configuration +type Job struct { + // JobType specifies the type of job (e.g., NORMAL_JOB, BATCH_JOB, SCENARIO_JOB). + JobType string `json:"job_type,omitempty"` + + // FromConnectorName is the source link type (required). + FromConnectorName string `json:"from-connector-name" required:"true"` + + // ToConfigValues holds destination link parameter configuration. + ToConfigValues *ConfigValues `json:"to-config-values" required:"true"` + + // ToLinkName is the destination link name (required). + ToLinkName string `json:"to-link-name" required:"true"` + + // DriverConfigValues holds job parameter configuration. + DriverConfigValues *ConfigValues `json:"driver-config-values" required:"true"` + + // FromConfigValues holds source link parameter configuration. + FromConfigValues *ConfigValues `json:"from-config-values" required:"true"` + + // ToConnectorName is the destination link type (optional). + ToConnectorName string `json:"to-connector-name,omitempty"` + + // Name is the job name with a limit of 1-240 characters (optional). + Name string `json:"name,omitempty"` + + // FromLinkName is the source link name (optional). + FromLinkName string `json:"from-link-name,omitempty"` + + // CreationUser is the user who created the job (optional). + CreationUser string `json:"creation-user,omitempty"` + + // CreationDate is the time when the job was created (optional). + CreationDate int64 `json:"creation-date,omitempty"` + + // UpdateDate is the time when the job was last updated (optional). + UpdateDate int64 `json:"update-date,omitempty"` + + // IsIncremental indicates whether the job is incremental (optional). + IsIncremental bool `json:"is_incre_job,omitempty"` + + // Flag is a job flag (optional). + Flag int `json:"flag,omitempty"` + + // FilesRead is the number of files read during the job (optional). + FilesRead int `json:"files_read,omitempty"` + + // UpdateUser is the user who last updated the job (optional). + UpdateUser string `json:"update-user,omitempty"` + + // ExternalID is an external ID associated with the job (optional). + ExternalID string `json:"external_id,omitempty"` + + // Type is the task type (optional). + Type string `json:"type,omitempty"` + + // ExecuteStartDate is the execution start date (optional). + ExecuteStartDate int64 `json:"execute_start_date,omitempty"` + + // DeleteRows is the number of rows deleted during the job (optional). + DeleteRows int `json:"delete_rows,omitempty"` + + // Enabled indicates whether the link is activated (optional). + Enabled bool `json:"enabled,omitempty"` + + // BytesWritten is the number of bytes written during the job (optional). + BytesWritten int64 `json:"bytes_written,omitempty"` + + // ID is the job ID (optional). + ID int `json:"id,omitempty"` + + // IsUseSQL indicates whether to use SQL statements (optional). + IsUseSQL bool `json:"is_use_sql,omitempty"` + + // UpdateRows is the number of rows updated during the job (optional). + UpdateRows int `json:"update_rows,omitempty"` + + // GroupName is the group name associated with the job (optional). + GroupName string `json:"group_name,omitempty"` + + // BytesRead is the number of bytes read during the job (optional). + BytesRead int64 `json:"bytes_read,omitempty"` + + // ExecuteUpdateDate is the execution update date (optional). + ExecuteUpdateDate int64 `json:"execute_update_date,omitempty"` + + // WriteRows is the number of rows written during the job (optional). + WriteRows int `json:"write_rows,omitempty"` + + // RowsWritten is the number of rows written during the job (optional). + RowsWritten int `json:"rows_written,omitempty"` + + // RowsRead is the number of rows read during the job (optional). + RowsRead int64 `json:"rows_read,omitempty"` + + // FilesWritten is the number of written files (optional). + FilesWritten int64 `json:"files_written,omitempty"` + + // IsIncrementing indicates incremental or not (optional). + IsIncrementing bool `json:"is_incrementing,omitempty"` + + // ExecuteCreateDate is the execution creation date (optional). + ExecuteCreateDate int64 `json:"execute_create_date,omitempty"` + + // Status is Job execution status. Can be one of: BOOTING, RUNNING, SUCCEEDED, FAILED, NEW. Optional. + Status int64 `json:"status,omitempty"` +} + +type ConfigValues struct { + // Configs The data structures of source link parameters, destination link parameters, and job parameters are the same. However, the inputs parameter varies. + Configs []*Config `json:"configs" required:"true"` + + // ExtendedConfigs is extended configuration. + ExtendedConfigs *ExtendedConfigs `json:"extended-configs,omitempty"` +} + +type Config struct { + // Inputs is an Input parameter list. Each element in the list is in name,value format. For details, see the descriptions of inputs parameters. + // In the from-config-values data structure, the value of this parameter varies with the source link type. + // For details, see section "Source Job Parameters" in the Cloud Data Migration User Guide. In the to-cofig-values data structure, the value of this parameter varies with the destination link type. + // For details, see section "Destination Job Parameters" in the Cloud Data Migration User Guide. + // For details about the inputs parameter in the driver-config-values data structure, see the job parameter descriptions. + Inputs []*Input `json:"inputs" required:"true"` + + // Name is a configuration name. The value is fromJobConfig for a source job, toJobConfig for a destination job, and linkConfig for a link. + Name string `json:"name" required:"true"` + + // Id is a configuration ID. + Id int `json:"id,omitempty"` + + // Type is a configuration type. + Type string `json:"type,omitempty"` +} + +type Input struct { + Name string `json:"name" required:"true"` + Value string `json:"value" required:"true"` + Type string `json:"type,omitempty"` +} + +type ExtendedConfigs struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` +} + +// Response + +// Response holds job running information +type JobResp struct { + // Submissions is an array of StartJobSubmission objects. + Submissions []*StartJobSubmission `json:"submissions"` +} + +// StartJobSubmission represents a job submission +type StartJobSubmission struct { + // IsIncrementing indicates whether the job migrates incremental data. + IsIncrementing bool `json:"isIncrementing"` + + // DeleteRows is the number of rows deleted during the job. + DeleteRows int `json:"delete_rows"` + + // UpdateRows is the number of rows updated during the job. + UpdateRows int `json:"update_rows"` + + // WriteRows is the number of rows written during the job. + WriteRows int `json:"write_rows"` + + // SubmissionID is the ID of the submitted job. + SubmissionID int `json:"submission-id"` + + // JobName is the name of the job. + JobName string `json:"job-name"` + + // CreationUser is the user who created the job. + CreationUser string `json:"creation-user"` + + // CreationDate is the time when the job was created, accurate to millisecond. + CreationDate int64 `json:"creation-date"` + + // ExecuteDate is the time when the job was executed. + ExecuteDate int64 `json:"execute-date"` + + // Progress is the job progress. If a job fails, the value is -1. Otherwise, the value ranges from 0 to 100. + Progress float64 `json:"progress"` + + // Status represents the job's execution status. + Status string `json:"status"` + + // IsStopingIncrement indicates whether to stop incremental data migration. + IsStopingIncrement string `json:"isStopingIncrement"` + + // IsExecuteAuto indicates whether to execute the job as scheduled. + IsExecuteAuto bool `json:"is-execute-auto"` + + // LastUpdateDate is the time when the job was last updated. + LastUpdateDate int64 `json:"last-update-date"` + + // LastUpdateUser is the user who last updated the job status. + LastUpdateUser string `json:"last-udpate-user"` + + // IsDeleteJob indicates whether to delete the job after it is executed. + IsDeleteJob bool `json:"isDeleteJob"` +} diff --git a/openstack/dataarts/v1.1/job/CreateSpecific.go b/openstack/dataarts/v1.1/job/CreateSpecific.go new file mode 100644 index 000000000..9c3b27c10 --- /dev/null +++ b/openstack/dataarts/v1.1/job/CreateSpecific.go @@ -0,0 +1,53 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type CreateSpecificOpts struct { + // Jobs is a jobs list. + Jobs []Job `json:"jobs" required:"true"` +} + +// CreateSpecific is used to create a job in a specified cluster. +// Send request /v1.1/{project_id}/clusters/{cluster_id}/cdm/job +func CreateSpecific(client *golangsdk.ServiceClient, clusterID string, opts CreateRandomOpts) (*SpecificResp, error) { + + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + HeaderContentType: ApplicationJson, + }, + } + + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + raw, err := client.Post(client.ServiceURL(clustersEndpoint, clusterID, cdmEndpoint, jobEndpoint), b, nil, reqOpts) + + if err != nil { + return nil, err + } + + var resp *SpecificResp + err = extract.Into(raw.Body, resp) + return resp, err +} + +// SpecificResp holds job running information +type SpecificResp struct { + // Name is a job name. + Name string `json:"name"` + // ValidationResult is an array of ValidationResult objects. + ValidationResult []*JobValidationResult `json:"validation-result"` +} + +type JobValidationResult struct { + // Message is an error message. + Message string `json:"message,omitempty"` + // Status can be ERROR,WARNING. + Status string `json:"status,omitempty"` +} diff --git a/openstack/dataarts/v1.1/job/Delete.go b/openstack/dataarts/v1.1/job/Delete.go new file mode 100644 index 000000000..e1bd31d09 --- /dev/null +++ b/openstack/dataarts/v1.1/job/Delete.go @@ -0,0 +1,16 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +// Delete is used to delete a job. +// Send request DELETE /v1.1/{project_id}/clusters/{cluster_id}/cdm/job/{job_name} +func Delete(client *golangsdk.ServiceClient, clusterId, jobName string) error { + _, err := client.Delete(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, jobEndpoint, jobName), nil) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1.1/job/Get.go b/openstack/dataarts/v1.1/job/Get.go new file mode 100644 index 000000000..b16f609cf --- /dev/null +++ b/openstack/dataarts/v1.1/job/Get.go @@ -0,0 +1,46 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type GetOpts struct { + // Filter When job_name is all, this parameter is used for fuzzy job filtering. + Filter string `json:"filter,omitempty"` + // PageNumber is a page number + PageNumber int `json:"page_no,omitempty"` + // PageSize is a number of jobs on each page. The value ranges from 10 to 100. + PageSize int `json:"page_size,omitempty"` + // JobType is a type of the jobs to be queried. + JobType string `json:"jobType,omitempty"` +} + +// Get is used to query a job. +// Send request GET /v1.1/{project_id}/clusters/{cluster_id}/cdm/job/{job_name} +func Get(client *golangsdk.ServiceClient, clusterId, jobName string, opts *GetOpts) (*GetQueryResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(clustersEndpoint, clusterId, cdmEndpoint, jobEndpoint, jobName).WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) + if err != nil { + return nil, err + } + + var res *GetQueryResp + err = extract.Into(raw.Body, res) + return res, err +} + +type GetQueryResp struct { + // Total is a number of jobs. + Total int `json:"total"` + // Jobs is a Job list. For details, see the descriptions of jobs parameters. + Jobs []*Job `json:"jobs"` + // PageNumber is a page number. Jobs on the specified page will be returned. + PageNumber int `json:"page_no"` + // PageSize is a number of jobs on each page. + PageSize int `json:"page_size,"` +} diff --git a/openstack/dataarts/v1.1/job/GetHistory.go b/openstack/dataarts/v1.1/job/GetHistory.go new file mode 100644 index 000000000..ee1e49166 --- /dev/null +++ b/openstack/dataarts/v1.1/job/GetHistory.go @@ -0,0 +1,41 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const historyEndpoint = "submissions" + +type HistoryQuery struct { + JobName string `json:"jname" required:"true"` +} + +// GetHistory is used to query the job status. +// Send request GET /v1.1/{project_id}/clusters/{cluster_id}/cdm/submissions +func GetHistory(client *golangsdk.ServiceClient, clusterId string, opts *HistoryQuery) (*StatusResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(clustersEndpoint, clusterId, cdmEndpoint, historyEndpoint).WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) + if err != nil { + return nil, err + } + + var res *StatusResp + err = extract.Into(raw.Body, res) + return res, err +} + +type HistoryResp struct { + // Submissions is an array of StartJobSubmission objects. + Submissions []*StatusJobSubmission `json:"submissions"` + // Total is a number of historical records for a job. + Total int `json:"total"` + // PageNumber is a page number. + PageNumber int `json:"page_no"` + // PageSize is a number of records on each page. The default value is 10. + PageSize int `json:"page_size"` +} diff --git a/openstack/dataarts/v1.1/job/GetStatus.go b/openstack/dataarts/v1.1/job/GetStatus.go new file mode 100644 index 000000000..d7a3d1909 --- /dev/null +++ b/openstack/dataarts/v1.1/job/GetStatus.go @@ -0,0 +1,115 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const statusEndpoint = "status" + +// GetStatus is used to query the job status. +// Send request GET /v1.1/{project_id}/clusters/{cluster_id}/cdm/job/{job_name}/status +func GetStatus(client *golangsdk.ServiceClient, clusterId, jobName string, opts *GetOpts) (*StatusResp, error) { + raw, err := client.Get( + client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, jobEndpoint, jobName, statusEndpoint), + nil, + nil, + ) + if err != nil { + return nil, err + } + + var res *StatusResp + err = extract.Into(raw.Body, res) + return res, err +} + +type StatusResp struct { + // Submissions is an array of StartJobSubmission objects. + Submissions []*StatusJobSubmission `json:"submissions"` +} + +type StatusJobSubmission struct { + // IsIncrementing indicates whether the job migrates incremental data. + IsIncrementing bool `json:"isIncrementing"` + + // JobName is the name of the job. + JobName string `json:"job-name"` + + // Counters is Job's running result statistics. This parameter is available only when status is SUCCEEDED. For details, see the description of the counters parameter. + Counters *Counters `json:"counters"` + + // IsStopingIncrement indicates whether to stop incremental data migration. + IsStopingIncrement string `json:"isStopingIncrement"` + + // IsExecuteAuto indicates whether to execute the job as scheduled. + IsExecuteAuto bool `json:"is-execute-auto"` + + // LastUpdateDate is the time when the job was last updated. + LastUpdateDate int64 `json:"last-update-date"` + + // LastUpdateUser is the user who last updated the job status. + LastUpdateUser string `json:"last-udpate-user"` + + // IsDeleteJob indicates whether to delete the job after it is executed. + IsDeleteJob bool `json:"isDeleteJob"` + + // CreationUser is the user who created the job. + CreationUser string `json:"creation-user"` + + // CreationDate is the time when the job was created, accurate to millisecond. + CreationDate int64 `json:"creation-date"` + + // ExternalID is an external ID associated with the job (optional). + ExternalID string `json:"external-id,omitempty"` + + // Progress is the job progress. If a job fails, the value is -1. Otherwise, the value ranges from 0 to 100. + Progress float64 `json:"progress"` + + // SubmissionID is the ID of the submitted job. + SubmissionID int `json:"submission-id"` + + // DeleteRows is the number of rows deleted during the job. + DeleteRows int `json:"delete_rows"` + + // UpdateRows is the number of rows updated during the job. + UpdateRows int `json:"update_rows"` + + // WriteRows is the number of rows written during the job. + WriteRows int `json:"write_rows"` + + // ExecuteDate is the time when the job was executed. + ExecuteDate int64 `json:"execute-date"` + + // Status represents the job's execution status. + Status string `json:"status"` + + // ErrorDetails represents Error details. This parameter is available only when status is FAILED. + ErrorDetails string `json:"error-details"` + + // ErrorSummary represents Error summary. This parameter is available only when status is FAILED. + ErrorSummary string `json:"error-summary"` +} + +type Counters struct { + // BytesWritten is number of bytes that are written. + BytesWritten int64 `json:"BYTES_WRITTEN"` + // TotalFiles is the total number of files. + TotalFiles int `json:"TOTAL_FILES"` + // BytesWritten is number of rows that are read. + RowsRead int64 `json:"ROWS_READ"` + // BytesRead is number of bytes that are read + BytesRead int64 `json:"BYTES_READ"` + // RowsWritten is number of rows that are written. + RowsWritten int64 `json:"ROWS_WRITTEN"` + // FilesWritten is number of files that are written. + FilesWritten int `json:"FILES_WRITTEN"` + // FilesRead is number of files that are read. + FilesRead int `json:"FILES_READ"` + // TotalSize is total number of bytes. + TotalSize int64 `json:"TOTAL_SIZE"` + // FilesSkipped is number of files that are skipped. + FilesSkipped int `json:"FILES_SKIPPED"` + // RowsWrittenSkipped is number of rows that are skipped. + RowsWrittenSkipped int64 `json:"ROWS_WRITTEN_SKIPPED"` +} diff --git a/openstack/dataarts/v1.1/job/Start.go b/openstack/dataarts/v1.1/job/Start.go new file mode 100644 index 000000000..45b97a0bb --- /dev/null +++ b/openstack/dataarts/v1.1/job/Start.go @@ -0,0 +1,21 @@ +package job + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const startEndpoint = "start" + +// Start is used to start a job. +// Send request PUT /v1.1/{project_id}/clusters/{cluster_id}/cdm/job/{job_name}/start +func Start(client *golangsdk.ServiceClient, clusterId, jobName string) (*JobResp, error) { + raw, err := client.Put(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, jobEndpoint, jobName, startEndpoint), nil, nil, nil) + if err != nil { + return nil, err + } + + var resp *JobResp + err = extract.Into(raw.Body, resp) + return resp, err +} diff --git a/openstack/dataarts/v1.1/job/Stop.go b/openstack/dataarts/v1.1/job/Stop.go new file mode 100644 index 000000000..79d98f89d --- /dev/null +++ b/openstack/dataarts/v1.1/job/Stop.go @@ -0,0 +1,21 @@ +package job + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const stopEndpoint = "stop" + +// Stop is used to stop a job. +// Send request PUT /v1.1/{project_id}/clusters/{cluster_id}/cdm/job/{job_name}/stop +func Stop(client *golangsdk.ServiceClient, clusterId, jobName string) (*UpdateResp, error) { + raw, err := client.Put(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, jobEndpoint, jobName, stopEndpoint), nil, nil, nil) + if err != nil { + return nil, err + } + + var resp *UpdateResp + err = extract.Into(raw.Body, resp) + return resp, err +} diff --git a/openstack/dataarts/v1.1/job/Update.go b/openstack/dataarts/v1.1/job/Update.go new file mode 100644 index 000000000..09e7393a4 --- /dev/null +++ b/openstack/dataarts/v1.1/job/Update.go @@ -0,0 +1,36 @@ +package job + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type UpdateOpts struct { + Jobs []*Job `json:"jobs" required:"true"` +} + +// Update is used to modify a job. +// Send request PUT /v1/{project_id}/connections/{connection_name}?ischeck=true +func Update(client *golangsdk.ServiceClient, clusterId, jobName string, opts *UpdateOpts) (*UpdateResp, error) { + + b, err := build.RequestBody(opts, "jobs") + if err != nil { + return nil, err + } + + raw, err := client.Put(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, jobEndpoint, jobName), b, nil, nil) + if err != nil { + return nil, err + } + + var resp *UpdateResp + err = extract.Into(raw.Body, resp) + return resp, err + +} + +type UpdateResp struct { + // Submissions is an array of StartJobSubmission objects. + ValidationResult []*JobValidationResult `json:"validation-result"` +} diff --git a/openstack/dataarts/v1.1/job/common.go b/openstack/dataarts/v1.1/job/common.go new file mode 100644 index 000000000..c068f429e --- /dev/null +++ b/openstack/dataarts/v1.1/job/common.go @@ -0,0 +1,30 @@ +package job + +import ( + "net/http" + + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const ( + HeaderXLanguage = "X-Language" + HeaderContentType = "Content-Type" + + ApplicationJson = "application/json" +) + +const ( + clustersEndpoint = "clusters" + jobEndpoint = "job" + cdmEndpoint = "cdm" +) + +type JobId struct { + JobId string `json:"jobId"` +} + +func respToJobId(r *http.Response) (*JobId, error) { + var res *JobId + err := extract.Into(r.Body, res) + return res, err +} diff --git a/openstack/dataarts/v1.1/factory/connection/Create.go b/openstack/dataarts/v1/factory/connection/Create.go similarity index 89% rename from openstack/dataarts/v1.1/factory/connection/Create.go rename to openstack/dataarts/v1/factory/connection/Create.go index dbc281142..919d37a08 100644 --- a/openstack/dataarts/v1.1/factory/connection/Create.go +++ b/openstack/dataarts/v1/factory/connection/Create.go @@ -6,9 +6,10 @@ import ( golangsdk "github.com/opentelekomcloud/gophertelekomcloud" "github.com/opentelekomcloud/gophertelekomcloud/internal/build" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" ) +const connectionsUrl = "connections" + const ( TypeDWS = "DWS" TypeDLI = "DLI" @@ -26,13 +27,13 @@ const ( const HeaderWorkspace = "workspace" -type Config struct { +type Connection struct { // Connection name. The name contains a maximum of 100 characters, including only letters, numbers, hyphens (-), and underscores (_). // The connection name must be unique. Name string `json:"name" required:"true"` // Connection type. Should be one of: DWS, DLI, SparkSQL, HIVE, RDS, CloudTable, HOST. Type string `json:"type" required:"true"` - // Connection configuration item. The configuration item varies with the connection type. + // Config connection configuration. The configuration item varies with the connection type. // You do not need to set the config parameter for DLI connections. // For other types of connections, see the description of connection configuration items. Config interface{} `json:"config,omitempty"` @@ -40,7 +41,7 @@ type Config struct { Description string `json:"description,omitempty"` } -func (c *Config) UnmarshalJSON(data []byte) error { +func (c *Connection) UnmarshalJSON(data []byte) error { var obj map[string]json.RawMessage if err := json.Unmarshal(data, &obj); err != nil { @@ -212,33 +213,24 @@ type HOSTConfig struct { // Create is used to create a connection. The supported connection types include DWS, DLI, Spark SQL, RDS, CloudTable, and Hive. // Send request /v1/{project_id}/connections -func Create(client *golangsdk.ServiceClient, opts Config, workspace string) (*CreateResp, error) { +func Create(client *golangsdk.ServiceClient, opts Connection, workspace string) error { b, err := build.RequestBody(opts, "") if err != nil { - return nil, err + return err } - var reqOpts *golangsdk.RequestOpts - if workspace != "" { - reqOpts = &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{HeaderWorkspace: workspace}, - } + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, } - raw, err := client.Post(client.ServiceURL("connections"), b, nil, reqOpts) + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + _, err = client.Post(client.ServiceURL(connectionsUrl), b, nil, reqOpts) if err != nil { - return nil, err + return err } - var res *CreateResp - err = extract.Into(raw.Body, res) - return res, err -} - -type CreateResp struct { - // Error code - ErrorCode string `json:"error_code,omitempty"` - // Error message - ErrorMsg string `json:"error_msg,omitempty"` + return nil } diff --git a/openstack/dataarts/v1/factory/connection/Delete.go b/openstack/dataarts/v1/factory/connection/Delete.go new file mode 100644 index 000000000..8f70b5f3f --- /dev/null +++ b/openstack/dataarts/v1/factory/connection/Delete.go @@ -0,0 +1,24 @@ +package connection + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" +) + +// Delete is used to delete a connection. +// Send request DELETE /v1/{project_id}/connections/{connection_name} +func Delete(client *golangsdk.ServiceClient, connName, workspace string) error { + + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts = &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderWorkspace: workspace}, + } + } + + _, err := client.Delete(client.ServiceURL(connectionsUrl, connName), reqOpts) + + return err +} diff --git a/openstack/dataarts/v1/factory/connection/Export.go b/openstack/dataarts/v1/factory/connection/Export.go new file mode 100644 index 000000000..055670578 --- /dev/null +++ b/openstack/dataarts/v1/factory/connection/Export.go @@ -0,0 +1,31 @@ +package connection + +import ( + "io" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +const exportEndpoint = "export" + +const OctetStreamHeader = "application/octet-stream" + +// Export is used to export all connection information that is compressed in ZIP format. +// Send request POST /v1/{project_id}/connections/export +func Export(client *golangsdk.ServiceClient, workspace string) (io.ReadCloser, error) { + + opts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + "Content-Type": OctetStreamHeader, + }, + } + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + raw, err := client.Post(client.ServiceURL(connectionsUrl, exportEndpoint), nil, nil, opts) + if err != nil { + return nil, err + } + + return raw.Body, err +} diff --git a/openstack/dataarts/v1.1/factory/connection/Get.go b/openstack/dataarts/v1/factory/connection/Get.go similarity index 80% rename from openstack/dataarts/v1.1/factory/connection/Get.go rename to openstack/dataarts/v1/factory/connection/Get.go index 6428d49fc..ee23c77bb 100644 --- a/openstack/dataarts/v1.1/factory/connection/Get.go +++ b/openstack/dataarts/v1/factory/connection/Get.go @@ -7,19 +7,19 @@ import ( // Get is used to query configuration details of a specific connection. // Send request GET /v1/{project_id}/connections/{connection_name} -func Get(client *golangsdk.ServiceClient, connectionName string, workspace string) (*Config, error) { +func Get(client *golangsdk.ServiceClient, connectionName string, workspace string) (*Connection, error) { var opts *golangsdk.RequestOpts if workspace != "" { opts = &golangsdk.RequestOpts{ MoreHeaders: map[string]string{HeaderWorkspace: workspace}, } } - raw, err := client.Get(client.ServiceURL("clusters", connectionName), nil, opts) + raw, err := client.Get(client.ServiceURL(connectionsUrl, connectionName), nil, opts) if err != nil { return nil, err } - var res *Config + var res *Connection err = extract.Into(raw.Body, res) return res, err } diff --git a/openstack/dataarts/v1/factory/connection/List.go b/openstack/dataarts/v1/factory/connection/List.go new file mode 100644 index 000000000..2ffaf40ca --- /dev/null +++ b/openstack/dataarts/v1/factory/connection/List.go @@ -0,0 +1,37 @@ +package connection + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type ListOpts struct { + Offset int `q:"offset"` + Limit int `q:"limit"` + ConnectionName string `q:"connectionName"` +} + +type ListResp struct { + // Total the number of connections. + Total int `q:"total"` + // Connection the Connection list. + Connections []Connection `q:"connections"` +} + +// List is used to query a connection list. +// Send request GET /v1/{project_id}/connections?offset={offset}&limit={limit}&connectionName={connectionName} +func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(connectionsUrl).WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, nil) + if err != nil { + return nil, err + } + + var res *ListResp + err = extract.IntoSlicePtr(raw.Body, &res, "") + return res, err +} diff --git a/openstack/dataarts/v1/factory/connection/Update.go b/openstack/dataarts/v1/factory/connection/Update.go new file mode 100644 index 000000000..bf51c8618 --- /dev/null +++ b/openstack/dataarts/v1/factory/connection/Update.go @@ -0,0 +1,41 @@ +package connection + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +type UpdateOpts struct { + // IsCheck indicates whether to perform check. The default value is No. + IsCheck bool `q:"ischeck"` +} + +// Update is used to edit a connection. +// Send request PUT /v1/{project_id}/connections/{connection_name}?ischeck=true +func Update(client *golangsdk.ServiceClient, conn Connection, opts UpdateOpts, workspace string) error { + + url, err := golangsdk.NewURLBuilder().WithEndpoints(connectionsUrl, conn.Name).WithQueryParams(&opts).Build() + if err != nil { + return err + } + + b, err := build.RequestBody(conn, "") + if err != nil { + return err + } + + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + _, err = client.Put(url.String(), b, nil, reqOpts) + if err != nil { + return err + } + + return nil +} From a1da1126eb6efae956e195b68a11661b1d8d0894 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 17 Apr 2024 11:39:10 +0200 Subject: [PATCH 07/11] merge fixes --- .../v1.1/factory/connection/Create.go | 244 ------------------ .../dataarts/v1.1/factory/connection/Get.go | 25 -- .../dataarts/v1.1/factory/connection/List.go | 26 -- .../v1.1/{factory => job}/CreateRandom.go | 0 .../v1.1/{factory => job}/CreateSpecific.go | 0 .../dataarts/v1.1/{factory => job}/Delete.go | 0 .../dataarts/v1.1/{factory => job}/Get.go | 2 +- .../v1.1/{factory => job}/GetHistory.go | 0 .../v1.1/{factory => job}/GetStatus.go | 0 .../dataarts/v1.1/{factory => job}/Start.go | 0 .../dataarts/v1.1/{factory => job}/Stop.go | 0 .../dataarts/v1.1/{factory => job}/Update.go | 0 .../dataarts/v1.1/{factory => job}/common.go | 0 13 files changed, 1 insertion(+), 296 deletions(-) delete mode 100644 openstack/dataarts/v1.1/factory/connection/Create.go delete mode 100644 openstack/dataarts/v1.1/factory/connection/Get.go delete mode 100644 openstack/dataarts/v1.1/factory/connection/List.go rename openstack/dataarts/v1.1/{factory => job}/CreateRandom.go (100%) rename openstack/dataarts/v1.1/{factory => job}/CreateSpecific.go (100%) rename openstack/dataarts/v1.1/{factory => job}/Delete.go (100%) rename openstack/dataarts/v1.1/{factory => job}/Get.go (98%) rename openstack/dataarts/v1.1/{factory => job}/GetHistory.go (100%) rename openstack/dataarts/v1.1/{factory => job}/GetStatus.go (100%) rename openstack/dataarts/v1.1/{factory => job}/Start.go (100%) rename openstack/dataarts/v1.1/{factory => job}/Stop.go (100%) rename openstack/dataarts/v1.1/{factory => job}/Update.go (100%) rename openstack/dataarts/v1.1/{factory => job}/common.go (100%) diff --git a/openstack/dataarts/v1.1/factory/connection/Create.go b/openstack/dataarts/v1.1/factory/connection/Create.go deleted file mode 100644 index dbc281142..000000000 --- a/openstack/dataarts/v1.1/factory/connection/Create.go +++ /dev/null @@ -1,244 +0,0 @@ -package connection - -import ( - "encoding/json" - "fmt" - - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" - "github.com/opentelekomcloud/gophertelekomcloud/internal/build" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" -) - -const ( - TypeDWS = "DWS" - TypeDLI = "DLI" - TypeSparkSQL = "SparkSQL" - TypeHive = "HIVE" - TypeRDS = "RDS" - TypeCloudTable = "CloudTable" - TypeHOST = "HOST" -) - -const ( - MethodAgent = "agent" - MethodDirect = "direct" -) - -const HeaderWorkspace = "workspace" - -type Config struct { - // Connection name. The name contains a maximum of 100 characters, including only letters, numbers, hyphens (-), and underscores (_). - // The connection name must be unique. - Name string `json:"name" required:"true"` - // Connection type. Should be one of: DWS, DLI, SparkSQL, HIVE, RDS, CloudTable, HOST. - Type string `json:"type" required:"true"` - // Connection configuration item. The configuration item varies with the connection type. - // You do not need to set the config parameter for DLI connections. - // For other types of connections, see the description of connection configuration items. - Config interface{} `json:"config,omitempty"` - // Description of the connection. The description contains a maximum of 255 characters. - Description string `json:"description,omitempty"` -} - -func (c *Config) UnmarshalJSON(data []byte) error { - var obj map[string]json.RawMessage - - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - n, ok := obj["name"] - if !ok { - return fmt.Errorf("missed field in json, field: name") - } - - if err := json.Unmarshal(n, &c.Name); err != nil { - return err - } - - t, ok := obj["type"] - if !ok { - return fmt.Errorf("missed field in json, field: type") - } - - if err := json.Unmarshal(t, &c.Type); err != nil { - return err - } - - if d, ok := obj["description"]; ok { - if err := json.Unmarshal(d, &c.Description); err != nil { - return err - } - } - - switch c.Type { - case TypeDWS: - d := &DWSConfig{} - if err := json.Unmarshal(obj["config"], d); err != nil { - return err - } - c.Config = *d - case TypeDLI: - // There aren't any configurations for DLI type. - return nil - case TypeSparkSQL: - s := &SparkConfig{} - if err := json.Unmarshal(obj["config"], s); err != nil { - return err - } - c.Config = *s - case TypeHive: - h := &HiveConfig{} - if err := json.Unmarshal(obj["config"], h); err != nil { - return err - } - c.Config = *h - case TypeRDS: - r := &RDSConfig{} - if err := json.Unmarshal(obj["config"], r); err != nil { - return err - } - c.Config = *r - case TypeCloudTable: - ct := &CloudTableConfig{} - if err := json.Unmarshal(obj["config"], ct); err != nil { - return err - } - c.Config = *ct - case TypeHOST: - h := &HOSTConfig{} - if err := json.Unmarshal(obj["config"], h); err != nil { - return err - } - c.Config = *h - default: - return fmt.Errorf("connection type is not supported") - } - - return nil -} - -type DWSConfig struct { - // Name of a DWS cluster. - ClusterName string `json:"clusterName,omitempty"` - // IP address for accessing the DWS cluster. - IP string `json:"ip,omitempty"` - // Port for accessing the DWS cluster. - Port string `json:"port,omitempty"` - // Username of the database. This username is the username entered during the creation of the DWS cluster. - Username string `json:"userName" required:"true"` - // Password for accessing the database. This password is the password entered during the creation of the DWS cluster. - Password string `json:"password" required:"true"` - // Specifies whether to enable the SSL connection. - SSLEnable bool `json:"sslEnable" required:"true"` - // Name of a KMS key. - KMSKey string `json:"kmsKey" required:"true"` - // Name of a CDM cluster. - AgentName string `json:"agentName" required:"true"` -} - -type SparkConfig struct { - // Name of an MRS cluster. - ClusterName string `json:"clusterName" required:"true"` - // Method to connect. - // agent: connected through an agent. - // direct: connected directly. - ConnectionMethod string `json:"connectionMethod" required:"true"` - // Username of the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. - Username string `json:"userName,omitempty"` - // Password for accessing the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. - Password string `json:"password,omitempty"` - // Name of a CDM cluster. This parameter is mandatory when connectionMethod is set to agent. - AgentName string `json:"agentName,omitempty"` - // Name of a KMS key. This parameter is mandatory when connectionMethod is set to agent. - KMSKey string `json:"kmsKey,omitempty"` -} - -type HiveConfig struct { - // Name of an MRS cluster. - ClusterName string `json:"clusterName" required:"true"` - // Method to connect. - // agent: connected through an agent. - // direct: connected directly. - ConnectionMethod string `json:"connectionMethod" required:"true"` - // Username of the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. - Username string `json:"userName,omitempty"` - // Password for accessing the MRS cluster. This parameter is mandatory when connectionMethod is set to agent. - Password string `json:"password,omitempty"` - // Name of a CDM cluster. This parameter is mandatory when connectionMethod is set to agent. - AgentName string `json:"agentName,omitempty"` - // Name of a KMS key. This parameter is mandatory when connectionMethod is set to agent. - KMSKey string `json:"kmsKey,omitempty"` -} - -type RDSConfig struct { - // Address for accessing RDS. - IP string `json:"ip" required:"true"` - // Port for accessing RDS. - Port string `json:"port" required:"true"` - // Username of the database. This username is the username entered during the creation of the cluster. - Username string `json:"userName" required:"true"` - // Password for accessing the database. This password is the password entered during the creation of the cluster. - Password string `json:"password" required:"true"` - // Name of a CDM cluster. - AgentName string `json:"agentName" required:"true"` - // Name of a KMS key. - KMSKey string `json:"kmsKey" required:"true"` - // Name of the driver. - DriverName string `json:"driverName" required:"true"` - // Path of the driver on OBS. - DriverPath string `json:"driverPath" required:"true"` -} - -type CloudTableConfig struct { - // Name of a CloudTable cluster. - ClusterName string `json:"clusterName" required:"true"` -} - -type HOSTConfig struct { - // IP address of the host. - IP string `json:"ip" required:"true"` - // SSH port number of the host. - Port string `json:"port" required:"true"` - // Username for logging in to the host. - Username string `json:"userName" required:"true"` - // Password for logging in to the host. - Password string `json:"password" required:"true"` - // Name of a CDM cluster. - AgentName string `json:"agentName" required:"true"` - // Name of a KMS key. - KMSKey string `json:"kmsKey" required:"true"` -} - -// Create is used to create a connection. The supported connection types include DWS, DLI, Spark SQL, RDS, CloudTable, and Hive. -// Send request /v1/{project_id}/connections -func Create(client *golangsdk.ServiceClient, opts Config, workspace string) (*CreateResp, error) { - b, err := build.RequestBody(opts, "") - if err != nil { - return nil, err - } - - var reqOpts *golangsdk.RequestOpts - if workspace != "" { - reqOpts = &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{HeaderWorkspace: workspace}, - } - } - - raw, err := client.Post(client.ServiceURL("connections"), b, nil, reqOpts) - - if err != nil { - return nil, err - } - - var res *CreateResp - err = extract.Into(raw.Body, res) - return res, err -} - -type CreateResp struct { - // Error code - ErrorCode string `json:"error_code,omitempty"` - // Error message - ErrorMsg string `json:"error_msg,omitempty"` -} diff --git a/openstack/dataarts/v1.1/factory/connection/Get.go b/openstack/dataarts/v1.1/factory/connection/Get.go deleted file mode 100644 index 6428d49fc..000000000 --- a/openstack/dataarts/v1.1/factory/connection/Get.go +++ /dev/null @@ -1,25 +0,0 @@ -package connection - -import ( - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" -) - -// Get is used to query configuration details of a specific connection. -// Send request GET /v1/{project_id}/connections/{connection_name} -func Get(client *golangsdk.ServiceClient, connectionName string, workspace string) (*Config, error) { - var opts *golangsdk.RequestOpts - if workspace != "" { - opts = &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{HeaderWorkspace: workspace}, - } - } - raw, err := client.Get(client.ServiceURL("clusters", connectionName), nil, opts) - if err != nil { - return nil, err - } - - var res *Config - err = extract.Into(raw.Body, res) - return res, err -} diff --git a/openstack/dataarts/v1.1/factory/connection/List.go b/openstack/dataarts/v1.1/factory/connection/List.go deleted file mode 100644 index d02fa4fa6..000000000 --- a/openstack/dataarts/v1.1/factory/connection/List.go +++ /dev/null @@ -1,26 +0,0 @@ -package connection - -import ( - golangsdk "github.com/opentelekomcloud/gophertelekomcloud" - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" -) - -const ( - URLParamOffset = "offset" - URLParamLimit = "limit" - URLParamConnectionName = "connectionName" -) - -// List is used to query a connection list. -// Send request GET /v1/{project_id}/connections?offset={offset}&limit={limit}&connectionName={connectionName} -func List(client *golangsdk.ServiceClient, urlParams map[string]string) ([]*Config, error) { - - raw, err := client.Get(client.ServiceURL("clusters"), nil, nil) - if err != nil { - return nil, err - } - - var res []*Config - err = extract.IntoSlicePtr(raw.Body, &res, "clusters") - return res, err -} diff --git a/openstack/dataarts/v1.1/factory/CreateRandom.go b/openstack/dataarts/v1.1/job/CreateRandom.go similarity index 100% rename from openstack/dataarts/v1.1/factory/CreateRandom.go rename to openstack/dataarts/v1.1/job/CreateRandom.go diff --git a/openstack/dataarts/v1.1/factory/CreateSpecific.go b/openstack/dataarts/v1.1/job/CreateSpecific.go similarity index 100% rename from openstack/dataarts/v1.1/factory/CreateSpecific.go rename to openstack/dataarts/v1.1/job/CreateSpecific.go diff --git a/openstack/dataarts/v1.1/factory/Delete.go b/openstack/dataarts/v1.1/job/Delete.go similarity index 100% rename from openstack/dataarts/v1.1/factory/Delete.go rename to openstack/dataarts/v1.1/job/Delete.go diff --git a/openstack/dataarts/v1.1/factory/Get.go b/openstack/dataarts/v1.1/job/Get.go similarity index 98% rename from openstack/dataarts/v1.1/factory/Get.go rename to openstack/dataarts/v1.1/job/Get.go index c2b1fcc8c..b16f609cf 100644 --- a/openstack/dataarts/v1.1/factory/Get.go +++ b/openstack/dataarts/v1.1/job/Get.go @@ -1,4 +1,4 @@ -package factory +package job import ( golangsdk "github.com/opentelekomcloud/gophertelekomcloud" diff --git a/openstack/dataarts/v1.1/factory/GetHistory.go b/openstack/dataarts/v1.1/job/GetHistory.go similarity index 100% rename from openstack/dataarts/v1.1/factory/GetHistory.go rename to openstack/dataarts/v1.1/job/GetHistory.go diff --git a/openstack/dataarts/v1.1/factory/GetStatus.go b/openstack/dataarts/v1.1/job/GetStatus.go similarity index 100% rename from openstack/dataarts/v1.1/factory/GetStatus.go rename to openstack/dataarts/v1.1/job/GetStatus.go diff --git a/openstack/dataarts/v1.1/factory/Start.go b/openstack/dataarts/v1.1/job/Start.go similarity index 100% rename from openstack/dataarts/v1.1/factory/Start.go rename to openstack/dataarts/v1.1/job/Start.go diff --git a/openstack/dataarts/v1.1/factory/Stop.go b/openstack/dataarts/v1.1/job/Stop.go similarity index 100% rename from openstack/dataarts/v1.1/factory/Stop.go rename to openstack/dataarts/v1.1/job/Stop.go diff --git a/openstack/dataarts/v1.1/factory/Update.go b/openstack/dataarts/v1.1/job/Update.go similarity index 100% rename from openstack/dataarts/v1.1/factory/Update.go rename to openstack/dataarts/v1.1/job/Update.go diff --git a/openstack/dataarts/v1.1/factory/common.go b/openstack/dataarts/v1.1/job/common.go similarity index 100% rename from openstack/dataarts/v1.1/factory/common.go rename to openstack/dataarts/v1.1/job/common.go From ad47ef95e5b2dd8521f06888a3ad0248308fc993 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 17 Apr 2024 11:48:43 +0200 Subject: [PATCH 08/11] linter fixes --- acceptance/openstack/dataarts/v1.1/clusters_test.go | 4 ++-- openstack/dataarts/v1.1/cluster/Delete.go | 2 +- openstack/dataarts/v1.1/cluster/Stop.go | 4 ++++ openstack/dataarts/v1.1/job/common.go | 12 ------------ 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/acceptance/openstack/dataarts/v1.1/clusters_test.go b/acceptance/openstack/dataarts/v1.1/clusters_test.go index 98c5aab0c..ec180137f 100644 --- a/acceptance/openstack/dataarts/v1.1/clusters_test.go +++ b/acceptance/openstack/dataarts/v1.1/clusters_test.go @@ -53,7 +53,7 @@ func TestDataArtsClusterLifecycle(t *testing.T) { }, } - createResp, err := cluster.Create(client, createOpts) + createResp, err := cluster.Create(client, createOpts, "en") th.AssertNoErr(t, err) tools.PrintResource(t, createResp) @@ -86,7 +86,7 @@ func waitForStateAvailable(client *golangsdk.ServiceClient, secs int, instanceID func deleteDataArts(t *testing.T, client *golangsdk.ServiceClient, instanceId string) { t.Logf("Attempting to delete DataArts instance: %s", instanceId) - err := cluster.Delete(client, instanceId) + _, err := cluster.Delete(client, instanceId, nil) th.AssertNoErr(t, err) t.Logf("DataArts instance deleted: %s", instanceId) diff --git a/openstack/dataarts/v1.1/cluster/Delete.go b/openstack/dataarts/v1.1/cluster/Delete.go index 9f05565dd..56e03cd8a 100644 --- a/openstack/dataarts/v1.1/cluster/Delete.go +++ b/openstack/dataarts/v1.1/cluster/Delete.go @@ -13,7 +13,7 @@ type DeleteOpts struct { // Delete is used to delete a cluster. // Send request DELETE /v1.1/{project_id}/clusters/{cluster_id} -func Delete(client *golangsdk.ServiceClient, id string, jsonOpts DeleteOpts) (*JobId, error) { +func Delete(client *golangsdk.ServiceClient, id string, jsonOpts *DeleteOpts) (*JobId, error) { b, err := build.RequestBody(jsonOpts, "") if err != nil { return nil, err diff --git a/openstack/dataarts/v1.1/cluster/Stop.go b/openstack/dataarts/v1.1/cluster/Stop.go index 56df28806..809fa7aad 100644 --- a/openstack/dataarts/v1.1/cluster/Stop.go +++ b/openstack/dataarts/v1.1/cluster/Stop.go @@ -40,5 +40,9 @@ func Stop(client *golangsdk.ServiceClient, clusterId string, opts StopOpts) (*Jo &golangsdk.RequestOpts{ MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, }) + if err != nil { + return nil, err + } + return respToJobId(raw) } diff --git a/openstack/dataarts/v1.1/job/common.go b/openstack/dataarts/v1.1/job/common.go index c068f429e..d513dba29 100644 --- a/openstack/dataarts/v1.1/job/common.go +++ b/openstack/dataarts/v1.1/job/common.go @@ -1,11 +1,5 @@ package job -import ( - "net/http" - - "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" -) - const ( HeaderXLanguage = "X-Language" HeaderContentType = "Content-Type" @@ -22,9 +16,3 @@ const ( type JobId struct { JobId string `json:"jobId"` } - -func respToJobId(r *http.Response) (*JobId, error) { - var res *JobId - err := extract.Into(r.Body, res) - return res, err -} From dd3075e844dfc2c643194b055d5759a744799629 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Wed, 17 Apr 2024 13:30:58 +0200 Subject: [PATCH 09/11] added api for links --- openstack/dataarts/v1.1/link/Create.go | 135 +++++++++++++++++++++++++ openstack/dataarts/v1.1/link/Delete.go | 16 +++ openstack/dataarts/v1.1/link/Get.go | 28 +++++ openstack/dataarts/v1.1/link/Update.go | 36 +++++++ openstack/dataarts/v1.1/link/common.go | 18 ++++ 5 files changed, 233 insertions(+) create mode 100644 openstack/dataarts/v1.1/link/Create.go create mode 100644 openstack/dataarts/v1.1/link/Delete.go create mode 100644 openstack/dataarts/v1.1/link/Get.go create mode 100644 openstack/dataarts/v1.1/link/Update.go create mode 100644 openstack/dataarts/v1.1/link/common.go diff --git a/openstack/dataarts/v1.1/link/Create.go b/openstack/dataarts/v1.1/link/Create.go new file mode 100644 index 000000000..f3ae6ad47 --- /dev/null +++ b/openstack/dataarts/v1.1/link/Create.go @@ -0,0 +1,135 @@ +package link + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type CreateOpts struct { + Links []*Link `json:"links" required:"true"` +} + +type CreateQuery struct { + // Email address for receiving notifications. + Validate bool `json:"validate,omitempty"` +} + +type Link struct { + // User who created the link + LinkConfigValues *ConfigValues `json:"link-config-values" required:"true"` + + // User who created the link. + CreationUser string `json:"creation-user,omitempty"` + + // Link name. + Name string `json:"name" required:"true"` + + // Link ID. + ID int `json:"id,omitempty"` + + // Time when the link was created. + CreationDate int64 `json:"creation-date,omitempty"` + + // Connector name associated with the link. + ConnectorName string `json:"connector-name" required:"true"` + + // Time when the link was updated. + UpdateDate int64 `json:"update-date,omitempty"` + + // Whether to activate the link. + Enabled bool `json:"enabled"` + + // Update user who updated the link. + UpdateUser string `json:"update_user,omitempty"` +} + +type ConfigValues struct { + // Array of configuration objects + Configs []*Config `json:"configs" required:"true"` + + // Extended configurations (optional) + ExtendedConfigs *ExtendedConfigs `json:"extended-configs,omitempty"` + + // Validators (optional) + Validators []string `json:"validators,omitempty"` +} + +type Config struct { + // Inputs is a list of Input. Each element in the list is in name,value format. For details, see the descriptions of inputs parameters. + // In the from-config-values data structure, the value of this parameter varies with the source link type. + // For details, see section "Source Job Parameters" in the Cloud Data Migration User Guide. + // In the to-cofig-values data structure, the value of this parameter varies with the destination link type. + // For details, see section "Destination Job Parameters" in the Cloud Data Migration User Guide. + // For details about the inputs parameter in the driver-config-values data structure, see the job parameter descriptions. + Inputs []*Input `json:"inputs" required:"true"` + + // Name is a configuration name. The value is fromJobConfig for a source job, toJobConfig for a destination job, and linkConfig for a link. + Name string `json:"name" required:"true"` + + // Configuration ID (might not be returned) + ID int `json:"id,omitempty"` + + // Configuration type (might not be returned) + Type string `json:"type,omitempty"` +} + +type Input struct { + // Parameter name + Name string `json:"name" required:"true"` + + // Parameter value + Value string `json:"value" required:"true"` + + // Value type (might not be returned) + Type string `json:"type,omitempty"` +} + +type ExtendedConfigs struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` +} + +// Create is used to create a link. +// Send request POST /v1.1/{project_id}/clusters/{cluster_id}/cdm/link +func Create(client *golangsdk.ServiceClient, clusterId string, opts *CreateOpts, q *CreateQuery) (*CreateResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(clustersEndpoint, clusterId, cdmEndpoint, linkEndpoint).WithQueryParams(&q).Build() + if err != nil { + return nil, err + } + + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + raw, err := client.Post(client.ServiceURL(url.String()), b, nil, nil) + if err != nil { + return nil, err + } + + var res *CreateResp + err = extract.Into(raw.Body, res) + return res, err +} + +// CreateResp holds job running information +type CreateResp struct { + // Name is a link name. + Name string `json:"name"` + // ValidationResult is an array of ValidationResult objects. If a link fails to be created, the failure cause is returned. + // If a link is successfully created, an empty list is returned. + ValidationResult []*LinkValidationResult `json:"validation-result"` +} + +type LinkValidationResult struct { + // LinkConfig is a validation result of link creation or update. + LinkConfig []*ValidationLinkConfig `json:"linkConfig,omitempty"` +} + +type ValidationLinkConfig struct { + // Message is an error message. + Message string `json:"message,omitempty"` + // Status can be ERROR,WARNING. + Status string `json:"status,omitempty"` +} diff --git a/openstack/dataarts/v1.1/link/Delete.go b/openstack/dataarts/v1.1/link/Delete.go new file mode 100644 index 000000000..4bdcd84c7 --- /dev/null +++ b/openstack/dataarts/v1.1/link/Delete.go @@ -0,0 +1,16 @@ +package link + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +// Delete is used to delete a link. +// Send request DELETE /v1.1/{project_id}/clusters/{cluster_id}/cdm/link/{link_name} +func Delete(client *golangsdk.ServiceClient, clusterId, linkName string) error { + _, err := client.Delete(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, linkEndpoint, linkName), nil) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1.1/link/Get.go b/openstack/dataarts/v1.1/link/Get.go new file mode 100644 index 000000000..0d5b522fc --- /dev/null +++ b/openstack/dataarts/v1.1/link/Get.go @@ -0,0 +1,28 @@ +package link + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// Get is used to query a link. +// Send request GET /v1.1/{project_id}/clusters/{cluster_id}/cdm/link/{link_name} +func Get(client *golangsdk.ServiceClient, clusterId, linkName string) (*GetQueryResp, error) { + raw, err := client.Get(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, linkEndpoint, linkName), nil, nil) + if err != nil { + return nil, err + } + + var res *GetQueryResp + err = extract.Into(raw.Body, res) + return res, err +} + +type GetQueryResp struct { + // Links is a list of Link. + Links []*Link `json:"links"` + // FromToUnMapping is a Source and destination data sources not supported by table/file migration. + FromToUnMapping string `json:"fromTo-unMapping"` + // PageSize is a source and destination data sources supported by entire DB migration. + BatchFromToMapping string `json:"batchFromTo-mapping,"` +} diff --git a/openstack/dataarts/v1.1/link/Update.go b/openstack/dataarts/v1.1/link/Update.go new file mode 100644 index 000000000..a7d3d5ef0 --- /dev/null +++ b/openstack/dataarts/v1.1/link/Update.go @@ -0,0 +1,36 @@ +package link + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type UpdateOpts struct { + Links []*Link `json:"links" required:"true"` +} + +// Update is used to modify a link. +// Send request PUT /v1.1/{project_id}/clusters/{cluster_id}/cdm/link/{link_name} +func Update(client *golangsdk.ServiceClient, clusterId, linkName string, opts *UpdateOpts) (*UpdateResp, error) { + + b, err := build.RequestBody(opts, "links") + if err != nil { + return nil, err + } + + raw, err := client.Put(client.ServiceURL(clustersEndpoint, clusterId, cdmEndpoint, linkEndpoint, linkName), b, nil, nil) + if err != nil { + return nil, err + } + + var resp *UpdateResp + err = extract.Into(raw.Body, resp) + return resp, err + +} + +type UpdateResp struct { + // Submissions is an array of LinkValidationResult objects. + ValidationResult []*LinkValidationResult `json:"validation-result"` +} diff --git a/openstack/dataarts/v1.1/link/common.go b/openstack/dataarts/v1.1/link/common.go new file mode 100644 index 000000000..0df319708 --- /dev/null +++ b/openstack/dataarts/v1.1/link/common.go @@ -0,0 +1,18 @@ +package link + +const ( + HeaderXLanguage = "X-Language" + HeaderContentType = "Content-Type" + + ApplicationJson = "application/json" +) + +const ( + clustersEndpoint = "clusters" + cdmEndpoint = "cdm" + linkEndpoint = "link" +) + +type JobId struct { + JobId string `json:"jobId"` +} From 5eea9a1525379407603ce9df98b40b0bed5c5154 Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Fri, 19 Apr 2024 14:54:20 +0200 Subject: [PATCH 10/11] added script api --- Makefile | 3 + .../v1/{factory => }/connection/Create.go | 0 .../v1/{factory => }/connection/Delete.go | 0 .../v1/{factory => }/connection/Export.go | 0 .../v1/{factory => }/connection/Get.go | 0 .../v1/{factory => }/connection/List.go | 0 .../v1/{factory => }/connection/Update.go | 0 openstack/dataarts/v1/script/Create.go | 65 +++++++++++++++++++ openstack/dataarts/v1/script/Delete.go | 41 ++++++++++++ openstack/dataarts/v1/script/Execute.go | 51 +++++++++++++++ openstack/dataarts/v1/script/Get.go | 29 +++++++++ openstack/dataarts/v1/script/GetExecution.go | 58 +++++++++++++++++ openstack/dataarts/v1/script/List.go | 46 +++++++++++++ openstack/dataarts/v1/script/Stop.go | 25 +++++++ openstack/dataarts/v1/script/Update.go | 32 +++++++++ openstack/dataarts/v1/script/common.go | 12 ++++ 16 files changed, 362 insertions(+) rename openstack/dataarts/v1/{factory => }/connection/Create.go (100%) rename openstack/dataarts/v1/{factory => }/connection/Delete.go (100%) rename openstack/dataarts/v1/{factory => }/connection/Export.go (100%) rename openstack/dataarts/v1/{factory => }/connection/Get.go (100%) rename openstack/dataarts/v1/{factory => }/connection/List.go (100%) rename openstack/dataarts/v1/{factory => }/connection/Update.go (100%) create mode 100644 openstack/dataarts/v1/script/Create.go create mode 100644 openstack/dataarts/v1/script/Delete.go create mode 100644 openstack/dataarts/v1/script/Execute.go create mode 100644 openstack/dataarts/v1/script/Get.go create mode 100644 openstack/dataarts/v1/script/GetExecution.go create mode 100644 openstack/dataarts/v1/script/List.go create mode 100644 openstack/dataarts/v1/script/Stop.go create mode 100644 openstack/dataarts/v1/script/Update.go create mode 100644 openstack/dataarts/v1/script/common.go diff --git a/Makefile b/Makefile index 430d8b318..3dbab0d82 100644 --- a/Makefile +++ b/Makefile @@ -26,3 +26,6 @@ test-unit: test-acc: @echo "Starting acceptance tests..." @go test ./acceptance/... -race -covermode=atomic -coverprofile=coverage.txt -timeout 20m -v + +test-case: + go test -v github.com/opentelekomcloud/gophertelekomcloud/acceptance/openstack/$(scope) -run $(case) diff --git a/openstack/dataarts/v1/factory/connection/Create.go b/openstack/dataarts/v1/connection/Create.go similarity index 100% rename from openstack/dataarts/v1/factory/connection/Create.go rename to openstack/dataarts/v1/connection/Create.go diff --git a/openstack/dataarts/v1/factory/connection/Delete.go b/openstack/dataarts/v1/connection/Delete.go similarity index 100% rename from openstack/dataarts/v1/factory/connection/Delete.go rename to openstack/dataarts/v1/connection/Delete.go diff --git a/openstack/dataarts/v1/factory/connection/Export.go b/openstack/dataarts/v1/connection/Export.go similarity index 100% rename from openstack/dataarts/v1/factory/connection/Export.go rename to openstack/dataarts/v1/connection/Export.go diff --git a/openstack/dataarts/v1/factory/connection/Get.go b/openstack/dataarts/v1/connection/Get.go similarity index 100% rename from openstack/dataarts/v1/factory/connection/Get.go rename to openstack/dataarts/v1/connection/Get.go diff --git a/openstack/dataarts/v1/factory/connection/List.go b/openstack/dataarts/v1/connection/List.go similarity index 100% rename from openstack/dataarts/v1/factory/connection/List.go rename to openstack/dataarts/v1/connection/List.go diff --git a/openstack/dataarts/v1/factory/connection/Update.go b/openstack/dataarts/v1/connection/Update.go similarity index 100% rename from openstack/dataarts/v1/factory/connection/Update.go rename to openstack/dataarts/v1/connection/Update.go diff --git a/openstack/dataarts/v1/script/Create.go b/openstack/dataarts/v1/script/Create.go new file mode 100644 index 000000000..52c6db037 --- /dev/null +++ b/openstack/dataarts/v1/script/Create.go @@ -0,0 +1,65 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +type Script struct { + // Name is a Script name. The name contains a maximum of 128 characters, including only letters, numbers, hyphens (-), and periods (.). The script name must be unique. + Name string `json:"name" required:"true"` + // Type is a script type. Can be: FlinkSQL, DLISQL, SparkSQL, HiveSQL, DWSSQL, RDSSQL, Shell, PRESTO, ClickHouseSQL, HetuEngineSQL, PYTHON, ImpalaSQL, Spark Python + Type string `json:"type" required:"true"` + // Content maximum of 4 MB is supported. + Content string `json:"content,omitempty"` + + // Directory for storing the script. Access the DataArts Studio console and choose Data Development. The default directory is the root directory. + Directory string `json:"directory,omitempty"` + // ConnectionName is a name of the connection associated with the script. + // This parameter is mandatory when type is set to DLISQL, SparkSQL, HiveSQL, DWSSQL, Shell, PRESTO, ClickHouseSQL, HetuEngineSQL, RDSSQL, ImpalaSQL, Spark Python, or PYTHON. + // To obtain the existing connections, refer to the instructions in Querying a Connection List (to Be Taken Offline). By default, this parameter is left blank. + ConnectionName string `json:"connectionName,omitempty"` + // Database associated with an SQL statement. This parameter is available only when type is set to DLISQL, SparkSQL, HiveSQL, DWSSQL, PRESTO, RDSSQL, ClickHouseSQL, ImpalaSQL, or HetuEngineSQL. + // If type is set to DLI SQL, obtain database information by calling the API for querying all databases in the Data Lake Insight API Reference. + // This parameter is mandatory when the script is not of any type listed. + Database string `json:"database,omitempty"` + // Queue name of the DLI resource. This parameter is available only when type is set to DLISQL. You can obtain the queue information by calling the API for "Querying All Queues" in the Data Lake Insight API Reference. By default, this parameter is left blank. + QueueName string `json:"queueName" required:"true"` + // Configuration defined by a user for the job. This parameter is available only when type is set to DLISQL. For details about the supported configuration items, see conf parameter description in the "Submitting a SQL Job" section of the Data Lake Insight API Reference. By default, this parameter is left blank. + Configuration map[string]string `json:"configuration,omitempty"` + // Description contains a maximum of 255 characters. + Description string `json:"description,omitempty"` + // This parameter is required if the review function is enabled. It indicates the target status of the script. The value can be SAVED, SUBMITTED, or PRODUCTION. + TargetStatus string `json:"targetStatus,omitempty"` + // Approvers is a script approver. This parameter is required if the review function is enabled. + Approvers []*JobApprover `json:"approvers,omitempty"` +} + +type JobApprover struct { + ApproverName string `json:"approverName" required:"true"` +} + +// Create is used to create a script. Currently, the following script types are supported: DLI SQL, Flink SQL, RDS SQL, Spark SQL, Hive SQL, DWS SQL, Shell, Presto SQL, ClickHouse SQL, HetuEngine SQL, Python, Spark Python, and Impala SQL. +// Send request POST /v1/{project_id}/scripts +func Create(client *golangsdk.ServiceClient, opts Script, workspace string) error { + b, err := build.RequestBody(opts, "") + if err != nil { + return err + } + + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err = client.Post(client.ServiceURL(scriptsURL), b, nil, reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/script/Delete.go b/openstack/dataarts/v1/script/Delete.go new file mode 100644 index 000000000..19c1ff9b0 --- /dev/null +++ b/openstack/dataarts/v1/script/Delete.go @@ -0,0 +1,41 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +type DeleteReq struct { + Approvers []*JobApprover `json:"approvers,omitempty"` +} + +// Delete is used to delete a specific script. +// Send request DELETE /v1/{project_id}/scripts/{script_name} +func Delete(client *golangsdk.ServiceClient, scriptName, workspace string, opts *DeleteReq) error { + var err error + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{}, + OkCodes: []int{204}, + } + + var b *build.Body + if opts != nil { + b, err = build.RequestBody(opts, "") + if err != nil { + return err + } + + reqOpts.MoreHeaders[HeaderContentType] = ApplicationJson + } + + if workspace != "" { + reqOpts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err = client.DeleteWithBody(client.ServiceURL(scriptsURL, scriptName), b, reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/script/Execute.go b/openstack/dataarts/v1/script/Execute.go new file mode 100644 index 000000000..a8fb8dad4 --- /dev/null +++ b/openstack/dataarts/v1/script/Execute.go @@ -0,0 +1,51 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const executeURL = "execute" + +type ExecuteReq struct { + Params map[string]string `json:"params,omitempty"` +} + +// Execute is used to execute a specific script, which can be a DWS SQL, DLI SQL, RDS SQL, Flink SQL, Hive SQL, Presto SQL, or Spark SQL script. +// A script instance is generated each time the script is executed. You can call the API Querying the Execution Result of a Script Instance to obtain script execution results. +// Send request POST /v1/{project_id}/scripts/{script_name}/execute +func Execute(client *golangsdk.ServiceClient, scriptName, workspace string, opts *ExecuteReq) (*ExecuteResp, error) { + var err error + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{}, + OkCodes: []int{204}, + } + + var b *build.Body + if opts != nil { + b, err = build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + reqOpts.MoreHeaders[HeaderContentType] = ApplicationJson + } + + if workspace != "" { + reqOpts.MoreHeaders[HeaderWorkspace] = workspace + } + + raw, err := client.Post(client.ServiceURL(scriptsURL, scriptName, executeURL), b, nil, reqOpts) + if err != nil { + return nil, err + } + + var res *ExecuteResp + err = extract.Into(raw.Body, res) + return res, err +} + +type ExecuteResp struct { + InstanceID string `json:"instanceId"` +} diff --git a/openstack/dataarts/v1/script/Get.go b/openstack/dataarts/v1/script/Get.go new file mode 100644 index 000000000..44348626f --- /dev/null +++ b/openstack/dataarts/v1/script/Get.go @@ -0,0 +1,29 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// Get is used to query a script, including the script type and script content. +// Send request GET /v1/{project_id}/scripts/{script_name} +func Get(client *golangsdk.ServiceClient, scriptName, workspace string) (*Script, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(scriptsURL, scriptName), nil, opts) + if err != nil { + return nil, err + } + + var res Script + err = extract.Into(raw.Body, &res) + if err != nil { + return nil, err + } + + return &res, nil +} diff --git a/openstack/dataarts/v1/script/GetExecution.go b/openstack/dataarts/v1/script/GetExecution.go new file mode 100644 index 000000000..053572390 --- /dev/null +++ b/openstack/dataarts/v1/script/GetExecution.go @@ -0,0 +1,58 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// GetExecutionResult is used to obtain the execution status and result of a script instance. +// Send request GET /v1/{project_id}/scripts/{script_name}/instances/{instance_id} +func GetExecutionResult(client *golangsdk.ServiceClient, scriptName, instanceId, workspace string) (*Script, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(scriptsURL, scriptName, instancesURL, instanceId), nil, opts) + if err != nil { + return nil, err + } + + var res Script + err = extract.Into(raw.Body, &res) + if err != nil { + return nil, err + } + + return &res, nil +} + +type GetExecutionResp struct { + // Status is an execution status. + // Can be: + // + // LAUNCHING: The script instance is being submitted. + // + // RUNNING: The script instance is running. + // + // FINISHED: The script instance is successfully run. + // + // FAILED: The script instance fails to be run. + Status string `json:"status"` + // Results is an execution result of the script instance. + Results []*Result `json:"results"` +} + +type Result struct { + // Message Execution failure message. + Message string `json:"message,omitempty"` + // Duration is a time of executing the script instance. Unit: second + Duration float64 `json:"duration,omitempty"` + // RowCount is a number of the result rows. + RowCount int `json:"rowCount,omitempty"` + // Rows is a result data. + Rows [][]interface{} `json:"rows,omitempty"` + // Schema is a format definition of the result data. + Schema []map[string]string `json:"schema,omitempty"` +} diff --git a/openstack/dataarts/v1/script/List.go b/openstack/dataarts/v1/script/List.go new file mode 100644 index 000000000..7840a3e8d --- /dev/null +++ b/openstack/dataarts/v1/script/List.go @@ -0,0 +1,46 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type ListOpts struct { + Offset int `q:"offset"` + Limit int `q:"limit"` + ScriptName string `q:"scriptName"` +} + +// List is used to query the script list. A maximum of 1000 scripts can be returned for each query. +// Send request GET /v1/{project_id}/scripts?offset={offset}&limit={limit}&scriptName={scriptName} +func List(client *golangsdk.ServiceClient, opts *ListOpts, workspace string) (*ListResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(scriptsURL).WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + var reqOpts *golangsdk.RequestOpts + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, reqOpts) + if err != nil { + return nil, err + } + + var res *ListResp + err = extract.Into(raw.Body, &res) + if err != nil { + return nil, err + } + + return res, nil +} + +type ListResp struct { + // Total is the total number of scripts. + Total int `json:"total"` + // Scripts is a list of scripts. + Scripts []*Script `json:"scripts"` +} diff --git a/openstack/dataarts/v1/script/Stop.go b/openstack/dataarts/v1/script/Stop.go new file mode 100644 index 000000000..98b8d07b9 --- /dev/null +++ b/openstack/dataarts/v1/script/Stop.go @@ -0,0 +1,25 @@ +package script + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +const stopURL = "stop" + +// Stop is used to stop executing a script instance. +// Send request POST /v1/{project_id}/scripts/{script_name}/instances/{instance_id}/stop +func Stop(client *golangsdk.ServiceClient, scriptName, instanceId, workspace string) error { + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + _, err := client.Post(client.ServiceURL(scriptsURL, scriptName, instancesURL, instanceId, stopURL), nil, nil, reqOpts) + if err != nil { + return err + } + return nil +} diff --git a/openstack/dataarts/v1/script/Update.go b/openstack/dataarts/v1/script/Update.go new file mode 100644 index 000000000..06922fe5e --- /dev/null +++ b/openstack/dataarts/v1/script/Update.go @@ -0,0 +1,32 @@ +package script + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +// Update is used to modify the configuration items or script contents of a script. +// When modifying a script, specify the name of the script to be modified. The script name and type cannot be modified. +// Send request PUT /v1/{project_id}/scripts/{script_name} +func Update(client *golangsdk.ServiceClient, scriptName, workspace string, script Script) error { + + b, err := build.RequestBody(script, "") + if err != nil { + return err + } + + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + _, err = client.Put(client.ServiceURL(scriptsURL, scriptName), b, nil, reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/script/common.go b/openstack/dataarts/v1/script/common.go new file mode 100644 index 000000000..c84df6895 --- /dev/null +++ b/openstack/dataarts/v1/script/common.go @@ -0,0 +1,12 @@ +package script + +const ( + HeaderWorkspace = "workspace" + HeaderContentType = "Content-Type" + + ApplicationJson = "application/json" +) + +const instancesURL = "instances" + +const scriptsURL = "scripts" From caa7bae55b68af7939f6bb655ca99c993a173ade Mon Sep 17 00:00:00 2001 From: Sergei Martynov Date: Thu, 25 Apr 2024 11:32:29 +0200 Subject: [PATCH 11/11] added all factory apis --- openstack/dataarts/v1.1/cluster/Create.go | 2 +- openstack/dataarts/v1.1/cluster/Delete.go | 2 +- openstack/dataarts/v1.1/cluster/Get.go | 2 +- openstack/dataarts/v1.1/cluster/List.go | 2 +- openstack/dataarts/v1.1/cluster/Restart.go | 2 +- openstack/dataarts/v1.1/cluster/Start.go | 2 +- openstack/dataarts/v1.1/cluster/Stop.go | 2 +- openstack/dataarts/v1.1/cluster/common.go | 2 +- openstack/dataarts/v1/connection/Create.go | 4 +- openstack/dataarts/v1/connection/Delete.go | 2 +- openstack/dataarts/v1/connection/Export.go | 10 +- openstack/dataarts/v1/connection/Get.go | 2 +- openstack/dataarts/v1/connection/List.go | 2 +- openstack/dataarts/v1/connection/Update.go | 2 +- openstack/dataarts/v1/job/BatchExportJob.go | 39 +++ openstack/dataarts/v1/job/Create.go | 269 ++++++++++++++++++ openstack/dataarts/v1/job/Delete.go | 34 +++ .../dataarts/v1/job/ExecuteImmediately.go | 52 ++++ openstack/dataarts/v1/job/ExportJob.go | 25 ++ openstack/dataarts/v1/job/Get.go | 29 ++ openstack/dataarts/v1/job/GetJobFile.go | 64 +++++ openstack/dataarts/v1/job/GetJobInstance.go | 97 +++++++ .../dataarts/v1/job/GetJobInstanceList.go | 134 +++++++++ openstack/dataarts/v1/job/GetRunningStatus.go | 83 ++++++ openstack/dataarts/v1/job/GetSystemTask.go | 69 +++++ openstack/dataarts/v1/job/ImportJob.go | 58 ++++ openstack/dataarts/v1/job/List.go | 93 ++++++ openstack/dataarts/v1/job/RetryInstance.go | 26 ++ openstack/dataarts/v1/job/Start.go | 39 +++ openstack/dataarts/v1/job/Stop.go | 24 ++ openstack/dataarts/v1/job/StopInstance.go | 24 ++ openstack/dataarts/v1/job/Update.go | 32 +++ openstack/dataarts/v1/job/common.go | 14 + openstack/dataarts/v1/resource/Create.go | 61 ++++ openstack/dataarts/v1/resource/Delete.go | 26 ++ openstack/dataarts/v1/resource/Get.go | 29 ++ openstack/dataarts/v1/resource/List.go | 46 +++ openstack/dataarts/v1/resource/Update.go | 32 +++ openstack/dataarts/v1/resource/common.go | 10 + openstack/dataarts/v1/script/Create.go | 2 +- openstack/dataarts/v1/script/Delete.go | 2 +- openstack/dataarts/v1/script/Execute.go | 4 +- openstack/dataarts/v1/script/Get.go | 2 +- openstack/dataarts/v1/script/GetExecution.go | 2 +- openstack/dataarts/v1/script/List.go | 2 +- openstack/dataarts/v1/script/Stop.go | 4 +- openstack/dataarts/v1/script/Update.go | 2 +- openstack/dataarts/v1/script/common.go | 4 +- 48 files changed, 1437 insertions(+), 34 deletions(-) create mode 100644 openstack/dataarts/v1/job/BatchExportJob.go create mode 100644 openstack/dataarts/v1/job/Create.go create mode 100644 openstack/dataarts/v1/job/Delete.go create mode 100644 openstack/dataarts/v1/job/ExecuteImmediately.go create mode 100644 openstack/dataarts/v1/job/ExportJob.go create mode 100644 openstack/dataarts/v1/job/Get.go create mode 100644 openstack/dataarts/v1/job/GetJobFile.go create mode 100644 openstack/dataarts/v1/job/GetJobInstance.go create mode 100644 openstack/dataarts/v1/job/GetJobInstanceList.go create mode 100644 openstack/dataarts/v1/job/GetRunningStatus.go create mode 100644 openstack/dataarts/v1/job/GetSystemTask.go create mode 100644 openstack/dataarts/v1/job/ImportJob.go create mode 100644 openstack/dataarts/v1/job/List.go create mode 100644 openstack/dataarts/v1/job/RetryInstance.go create mode 100644 openstack/dataarts/v1/job/Start.go create mode 100644 openstack/dataarts/v1/job/Stop.go create mode 100644 openstack/dataarts/v1/job/StopInstance.go create mode 100644 openstack/dataarts/v1/job/Update.go create mode 100644 openstack/dataarts/v1/job/common.go create mode 100644 openstack/dataarts/v1/resource/Create.go create mode 100644 openstack/dataarts/v1/resource/Delete.go create mode 100644 openstack/dataarts/v1/resource/Get.go create mode 100644 openstack/dataarts/v1/resource/List.go create mode 100644 openstack/dataarts/v1/resource/Update.go create mode 100644 openstack/dataarts/v1/resource/common.go diff --git a/openstack/dataarts/v1.1/cluster/Create.go b/openstack/dataarts/v1.1/cluster/Create.go index 88141f33c..8faa7d0ac 100644 --- a/openstack/dataarts/v1.1/cluster/Create.go +++ b/openstack/dataarts/v1.1/cluster/Create.go @@ -85,7 +85,7 @@ func Create(client *golangsdk.ServiceClient, opts CreateOpts, xLang string) (*Cl return nil, err } - raw, err := client.Post(client.ServiceURL(clustersURL), b, nil, &golangsdk.RequestOpts{ + raw, err := client.Post(client.ServiceURL(clustersEndpoint), b, nil, &golangsdk.RequestOpts{ MoreHeaders: map[string]string{HeaderContentType: ApplicationJson, HeaderXLanguage: xLang}, }) diff --git a/openstack/dataarts/v1.1/cluster/Delete.go b/openstack/dataarts/v1.1/cluster/Delete.go index 56e03cd8a..e4a830fd1 100644 --- a/openstack/dataarts/v1.1/cluster/Delete.go +++ b/openstack/dataarts/v1.1/cluster/Delete.go @@ -19,7 +19,7 @@ func Delete(client *golangsdk.ServiceClient, id string, jsonOpts *DeleteOpts) (* return nil, err } - r, err := client.DeleteWithBody(client.ServiceURL(clustersURL, id), b, nil) + r, err := client.DeleteWithBody(client.ServiceURL(clustersEndpoint, id), b, nil) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1.1/cluster/Get.go b/openstack/dataarts/v1.1/cluster/Get.go index c03a77b2f..5328931a6 100644 --- a/openstack/dataarts/v1.1/cluster/Get.go +++ b/openstack/dataarts/v1.1/cluster/Get.go @@ -8,7 +8,7 @@ import ( // Get is used to query cluster details. // Send request GET /v1.1/{project_id}/clusters/{cluster_id} func Get(client *golangsdk.ServiceClient, clusterId string) (*ClusterQuery, error) { - raw, err := client.Get(client.ServiceURL(clustersURL, clusterId), nil, nil) + raw, err := client.Get(client.ServiceURL(clustersEndpoint, clusterId), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1.1/cluster/List.go b/openstack/dataarts/v1.1/cluster/List.go index e2db4571b..ec29dcad6 100644 --- a/openstack/dataarts/v1.1/cluster/List.go +++ b/openstack/dataarts/v1.1/cluster/List.go @@ -9,7 +9,7 @@ import ( // Send request GET /v1.1/{project_id}/clusters func List(client *golangsdk.ServiceClient) ([]*ClusterQuery, error) { - raw, err := client.Get(client.ServiceURL(clustersURL), nil, nil) + raw, err := client.Get(client.ServiceURL(clustersEndpoint), nil, nil) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1.1/cluster/Restart.go b/openstack/dataarts/v1.1/cluster/Restart.go index 13cb38584..7b1c41fbf 100644 --- a/openstack/dataarts/v1.1/cluster/Restart.go +++ b/openstack/dataarts/v1.1/cluster/Restart.go @@ -47,7 +47,7 @@ func Restart(client *golangsdk.ServiceClient, clusterId string, opts RestartOpts } resp, err := client.Post( - client.ServiceURL(clustersURL, clusterId, actionEndpoint), + client.ServiceURL(clustersEndpoint, clusterId, actionEndpoint), b, nil, &golangsdk.RequestOpts{ diff --git a/openstack/dataarts/v1.1/cluster/Start.go b/openstack/dataarts/v1.1/cluster/Start.go index b470fc976..0a0693320 100644 --- a/openstack/dataarts/v1.1/cluster/Start.go +++ b/openstack/dataarts/v1.1/cluster/Start.go @@ -21,7 +21,7 @@ func Start(client *golangsdk.ServiceClient, clusterId string, startOpts *StartOp } resp, err := client.Post( - client.ServiceURL(clustersURL, clusterId, actionEndpoint), + client.ServiceURL(clustersEndpoint, clusterId, actionEndpoint), b, nil, &golangsdk.RequestOpts{ diff --git a/openstack/dataarts/v1.1/cluster/Stop.go b/openstack/dataarts/v1.1/cluster/Stop.go index 809fa7aad..313227bb9 100644 --- a/openstack/dataarts/v1.1/cluster/Stop.go +++ b/openstack/dataarts/v1.1/cluster/Stop.go @@ -34,7 +34,7 @@ func Stop(client *golangsdk.ServiceClient, clusterId string, opts StopOpts) (*Jo } raw, err := client.Post( - client.ServiceURL(clustersURL, clusterId, actionEndpoint), + client.ServiceURL(clustersEndpoint, clusterId, actionEndpoint), b, nil, &golangsdk.RequestOpts{ diff --git a/openstack/dataarts/v1.1/cluster/common.go b/openstack/dataarts/v1.1/cluster/common.go index 60a93bb99..4136cc9d2 100644 --- a/openstack/dataarts/v1.1/cluster/common.go +++ b/openstack/dataarts/v1.1/cluster/common.go @@ -13,7 +13,7 @@ const ( ApplicationJson = "application/json" ) -const clustersURL = "clusters" +const clustersEndpoint = "clusters" const actionEndpoint = "action" diff --git a/openstack/dataarts/v1/connection/Create.go b/openstack/dataarts/v1/connection/Create.go index 919d37a08..26f00bba1 100644 --- a/openstack/dataarts/v1/connection/Create.go +++ b/openstack/dataarts/v1/connection/Create.go @@ -8,7 +8,7 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud/internal/build" ) -const connectionsUrl = "connections" +const connectionsEndpoint = "connections" const ( TypeDWS = "DWS" @@ -227,7 +227,7 @@ func Create(client *golangsdk.ServiceClient, opts Connection, workspace string) reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} } - _, err = client.Post(client.ServiceURL(connectionsUrl), b, nil, reqOpts) + _, err = client.Post(client.ServiceURL(connectionsEndpoint), b, nil, reqOpts) if err != nil { return err } diff --git a/openstack/dataarts/v1/connection/Delete.go b/openstack/dataarts/v1/connection/Delete.go index 8f70b5f3f..180ce7cfb 100644 --- a/openstack/dataarts/v1/connection/Delete.go +++ b/openstack/dataarts/v1/connection/Delete.go @@ -18,7 +18,7 @@ func Delete(client *golangsdk.ServiceClient, connName, workspace string) error { } } - _, err := client.Delete(client.ServiceURL(connectionsUrl, connName), reqOpts) + _, err := client.Delete(client.ServiceURL(connectionsEndpoint, connName), reqOpts) return err } diff --git a/openstack/dataarts/v1/connection/Export.go b/openstack/dataarts/v1/connection/Export.go index 055670578..521e487aa 100644 --- a/openstack/dataarts/v1/connection/Export.go +++ b/openstack/dataarts/v1/connection/Export.go @@ -8,21 +8,15 @@ import ( const exportEndpoint = "export" -const OctetStreamHeader = "application/octet-stream" - // Export is used to export all connection information that is compressed in ZIP format. // Send request POST /v1/{project_id}/connections/export func Export(client *golangsdk.ServiceClient, workspace string) (io.ReadCloser, error) { - opts := &golangsdk.RequestOpts{ - MoreHeaders: map[string]string{ - "Content-Type": OctetStreamHeader, - }, - } + opts := &golangsdk.RequestOpts{} if workspace != "" { opts.MoreHeaders[HeaderWorkspace] = workspace } - raw, err := client.Post(client.ServiceURL(connectionsUrl, exportEndpoint), nil, nil, opts) + raw, err := client.Post(client.ServiceURL(connectionsEndpoint, exportEndpoint), nil, nil, opts) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/connection/Get.go b/openstack/dataarts/v1/connection/Get.go index ee23c77bb..41d0e04dd 100644 --- a/openstack/dataarts/v1/connection/Get.go +++ b/openstack/dataarts/v1/connection/Get.go @@ -14,7 +14,7 @@ func Get(client *golangsdk.ServiceClient, connectionName string, workspace strin MoreHeaders: map[string]string{HeaderWorkspace: workspace}, } } - raw, err := client.Get(client.ServiceURL(connectionsUrl, connectionName), nil, opts) + raw, err := client.Get(client.ServiceURL(connectionsEndpoint, connectionName), nil, opts) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/connection/List.go b/openstack/dataarts/v1/connection/List.go index 2ffaf40ca..2464e23ad 100644 --- a/openstack/dataarts/v1/connection/List.go +++ b/openstack/dataarts/v1/connection/List.go @@ -21,7 +21,7 @@ type ListResp struct { // List is used to query a connection list. // Send request GET /v1/{project_id}/connections?offset={offset}&limit={limit}&connectionName={connectionName} func List(client *golangsdk.ServiceClient, opts ListOpts) (*ListResp, error) { - url, err := golangsdk.NewURLBuilder().WithEndpoints(connectionsUrl).WithQueryParams(&opts).Build() + url, err := golangsdk.NewURLBuilder().WithEndpoints(connectionsEndpoint).WithQueryParams(&opts).Build() if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/connection/Update.go b/openstack/dataarts/v1/connection/Update.go index bf51c8618..cf53baa64 100644 --- a/openstack/dataarts/v1/connection/Update.go +++ b/openstack/dataarts/v1/connection/Update.go @@ -14,7 +14,7 @@ type UpdateOpts struct { // Send request PUT /v1/{project_id}/connections/{connection_name}?ischeck=true func Update(client *golangsdk.ServiceClient, conn Connection, opts UpdateOpts, workspace string) error { - url, err := golangsdk.NewURLBuilder().WithEndpoints(connectionsUrl, conn.Name).WithQueryParams(&opts).Build() + url, err := golangsdk.NewURLBuilder().WithEndpoints(connectionsEndpoint, conn.Name).WithQueryParams(&opts).Build() if err != nil { return err } diff --git a/openstack/dataarts/v1/job/BatchExportJob.go b/openstack/dataarts/v1/job/BatchExportJob.go new file mode 100644 index 000000000..12d3d4eb3 --- /dev/null +++ b/openstack/dataarts/v1/job/BatchExportJob.go @@ -0,0 +1,39 @@ +package job + +import ( + "io" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +const batchExportEndpoint = "batch-export" + +type BatchExportReq struct { + // A list of jobs to be exported. A maximum of 100 jobs can be exported at a time. + JobList []string `json:"jobList" required:"true"` + // Specifies whether to export the scripts and resources that the job depends on. + // Default value: true + ExportDepend bool `json:"exportDepend,omitempty"` +} + +// BatchExportJob is used to batch export jobs, including job dependency scripts and CDM job definitions. +// Send request POST /v1/{project_id}/jobs/batch-export +func BatchExportJob(client *golangsdk.ServiceClient, reqOpts *BatchExportReq, workspace string) (io.ReadCloser, error) { + b, err := build.RequestBody(reqOpts, "") + if err != nil { + return nil, err + } + + opts := &golangsdk.RequestOpts{} + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + + raw, err := client.Post(client.ServiceURL(jobsEndpoint, batchExportEndpoint), b, nil, opts) + if err != nil { + return nil, err + } + + return raw.Body, err +} diff --git a/openstack/dataarts/v1/job/Create.go b/openstack/dataarts/v1/job/Create.go new file mode 100644 index 000000000..b5fbd18b3 --- /dev/null +++ b/openstack/dataarts/v1/job/Create.go @@ -0,0 +1,269 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +type Job struct { + // Job name. The name contains a maximum of 128 characters, including only letters, numbers, hyphens (-), underscores (_), and periods (.). The job name must be unique. + Name string `json:"name" required:"true"` + // Nodes is a node definition. + Nodes []Node `json:"nodes" required:"true"` + // Schedule is a scheduling configuration. + Schedule Schedule `json:"schedule" required:"true"` + // Job parameter definition. + Params []Param `json:"params,omitempty"` + // Path of a job in the directory tree. If the directory of the path does not exist during job creation, a directory is automatically created in the root directory /, for example, /dir/a/. + Directory string `json:"directory,omitempty"` + // Job type. + // REAL_TIME: real-time processing + // BATCH: batch processing + ProcessType string `json:"processType" required:"true"` + // Job ID + Id int64 `json:"id,omitempty"` + // User who last updated the job + LastUpdateUser string `json:"lastUpdateUser,omitempty"` + // OBS path for storing job run logs + LogPath string `json:"logPath,omitempty"` + // Basic job information. + BasicConfig BasicConfig `json:"basicConfig,omitempty"` + // This parameter is required if the review function is enabled. It indicates the target status of the job. The value can be SAVED, SUBMITTED, or PRODUCTION. + TargetStatus string `json:"targetStatus,omitempty"` + // Job approver. This parameter is required if the review function is enabled. + Approvers []*JobApprover `json:"approvers,omitempty"` +} + +type Node struct { + // Node name. The name contains a maximum of 128 characters, including only letters, numbers, hyphens (-), underscores (_), and periods (.). Names of the nodes in a job must be unique. + Name string `json:"name" required:"true"` + // Node type. The options are as follows: + // + // Hive SQL: Runs Hive SQL scripts. + // + // Spark SQL: Runs Spark SQL scripts. + // + // DWS SQL: Runs DWS SQL scripts. + // + // DLI SQL: Runs DLI SQL scripts. + // + // Shell: Runs shell SQL scripts. + // + // CDM Job: Runs CDM jobs. + // + // CloudTable Manager: Manages CloudTable tables, including creating and deleting tables. + // + // OBS Manager: Manages OBS paths, including creating and deleting paths. + // + // RESTAPI: Sends REST API requests. + // + // SMN: Sends short messages or emails. + // + // MRS Spark: Runs Spark jobs of MRS. + // + // MapReduce: Runs MapReduce jobs of MRS. + // + // MRS Flink: Runs Flink jobs of MRS. + // + // MRS HetuEngine: Runs HetuEngine jobs of MRS. + // + // DLI Spark: Runs Spark jobs of DLF. + // + // RDS SQL: Transfers SQL statements to RDS for execution. + Type string `json:"type" required:"true"` + // Location of a node on the job canvas. + Location Location `json:"location" required:"true"` + // Name of the previous node on which the current node depends. + PreNodeName []string `json:"preNodeName,omitempty"` + // Node execution condition. Whether the node is executed or not depends on the calculation result of the EL expression saved in the expression field of condition. + Conditions []*Condition `json:"conditions,omitempty"` + // Node properties. + Properties []*Property `json:"properties,omitempty" required:"true"` + // Interval at which node running results are checked. + // Unit: second; value range: 1 to 60 + // Default value: 10 + PollingInterval int `json:"pollingInterval,omitempty"` + // Maximum execution time of a node. If a node is not executed within the maximum execution time, the node is set to the failed state. + // Unit: minute; value range: 5 to 1440 + // Default value: 60 + MaxExecutionTime int `json:"maxExecutionTime,omitempty"` + // Number of the node retries. The value ranges from 0 to 5. 0 indicates no retry. + RetryTimes int `json:"retryTimes,omitempty"` + // Interval at which a retry is performed upon a failure. The value ranges from 5 to 120. + RetryInterval int `json:"retryInterval,omitempty"` + // Node failure policy. + // FAIL: Terminate the execution of the current job. + // IGNORE: Continue to execute the next node. + // SUSPEND: Suspend the execution of the current job. + // FAIL_CHILD: Terminate the execution of the subsequent node. + // The default value is FAIL. + FailPolicy string `json:"failPolicy,omitempty"` + // Event trigger for the real-time job node. + EventTrigger *Event `json:"eventTrigger,omitempty"` + // Cron trigger for the real-time job node. + CronTrigger *CronTrigger `json:"cronTrigger,omitempty"` +} + +type Schedule struct { + // Scheduling type. + // EXECUTE_ONCE: The job runs immediately and runs only once. + // CRON: The job runs periodically. + // EVENT: The job is triggered by events. + Type string `json:"type" required:"true"` + // When type is set to CRON, configure the scheduling frequency and start time. + Cron *Cron `json:"cron,omitempty"` + // When type is set to EVENT, configure information such as the event source. + Event *Event `json:"event,omitempty"` +} + +type Param struct { + // Name of a parameter. The name contains a maximum of 64 characters, including only letters, numbers, hyphens (-), and underscores (_). + Name string `json:"name" required:"true"` + // Value of the parameter. It cannot exceed 1,024 characters. + Value string `json:"value" required:"true"` + // Parameter type + // variable + // constants + // Default value: variable + Type string `json:"type,omitempty"` +} + +type Location struct { + // Position of the node on the horizontal axis of the job canvas. + X int `json:"x" required:"true"` + // Position of the node on the vertical axis of the job canvas. + Y int `json:"y" required:"true"` +} + +type Condition struct { + // Name of the previous node on which the current node depends. + PreNodeName string `json:"preNodeName" required:"true"` + // EL expression. If the calculation result of the EL expression is true, this node is executed. + Expression string `json:"expression" required:"true"` +} + +type CronTrigger struct { + // Scheduling start time in the format of yyyy-MM-dd'T'HH:mm:ssZ, which is an ISO 8601 time format. For example, 2018-10-22T23:59:59+08, which indicates that a job starts to be scheduled at 23:59:59 on October 22nd, 2018. + StartTime string `json:"startTime" required:"true"` + // Scheduling end time in the format of yyyy-MM-dd'T'HH:mm:ssZ, which is an ISO 8601 time format. For example, 2018-10-22T23:59:59+08, which indicates that a job stops to be scheduled at 23:59:59 on October 22nd, 2018. If the end time is not set, the job will continuously be executed based on the scheduling period. + EndTime string `json:"endTime,omitempty"` + // Cron expression in the format of . + Expression string `json:"expression" required:"true"` + // Time zone corresponding to the Cron expression, for example, GMT+8. + ExpressionTimeZone string `json:"expressionTimeZone,omitempty"` + // Job execution interval consisting of a time and time unit + // + // Example: 1 hours, 1 days, 1 weeks, 1 months + Period string `json:"period" required:"true"` + // Indicates whether to depend on the execution result of the current job's dependent job in the previous scheduling period. + DependPrePeriod bool `json:"dependPrePeriod.,omitempty"` + // Job dependency configuration. + DependJobs *DependJobs `json:"dependJobs,omitempty"` + // Number of concurrent executions allowed + Concurrent int `json:"concurrent,omitempty"` +} + +type Cron struct { + // Scheduling start time in the format of yyyy-MM-dd'T'HH:mm:ssZ, which is an ISO 8601 time format. For example, 2018-10-22T23:59:59+08, which indicates that a job starts to be scheduled at 23:59:59 on October 22nd, 2018. + StartTime string `json:"startTime" required:"true"` + // Scheduling end time in the format of yyyy-MM-dd'T'HH:mm:ssZ, which is an ISO 8601 time format. For example, 2018-10-22T23:59:59+08, which indicates that a job stops to be scheduled at 23:59:59 on October 22nd, 2018. If the end time is not set, the job will continuously be executed based on the scheduling period. + EndTime string `json:"endTime,omitempty"` + // Cron expression in the format of . + Expression string `json:"expression" required:"true"` + // Time zone corresponding to the Cron expression, for example, GMT+8. + ExpressionTimeZone string `json:"expressionTimeZone,omitempty"` + // Indicates whether to depend on the execution result of the current job's dependent job in the previous scheduling period. + DependPrePeriod bool `json:"dependPrePeriod.,omitempty"` + // Job dependency configuration. + DependJobs *DependJobs `json:"dependJobs,omitempty"` +} + +type Event struct { + // Select the corresponding connection name and topic. When a new Kafka message is received, the job is triggered. + // Set this parameter to KAFKA. + // Event type. Currently, only newly reported data events from the DIS stream can be monitored. Each time a data record is reported, the job runs once. + // This parameter is set to DIS. + // Select the OBS path to be listened to. If new files exist in the path, scheduling is triggered. The path name can be referenced using variable Job.trigger.obsNewFiles. The prerequisite is that DIS notifications have been configured for the OBS path. + // Set this parameter to OBS. + EventType string `json:"eventType" required:"true"` + // Job failure policy. + // SUSPEND: Suspend the event. + // IGNORE: Ignore the failure and process with the next event. + // Default value: SUSPEND + FailPolicy string `json:"failPolicy"` + // Number of the concurrently scheduled jobs. + // Value range: 1 to 128 + // Default value: 1 + Concurrent int `json:"concurrent"` + // Access policy. + // LAST: Access data from the last location. + // NEW: Access data from a new location. + // Default value: LAST + ReadPolicy string `json:"readPolicy"` +} + +type DependJobs struct { + // A list of dependent jobs. Only the existing jobs can be depended on. + Jobs []string `json:"jobs" required:"true"` + // Dependency period. + // SAME_PERIOD: To run a job or not depends on the execution result of its depended job in the current scheduling period. + // PRE_PERIOD: To run a job or not depends on the execution result of its depended job in the previous scheduling period. + // Default value: SAME_PERIOD + DependPeriod string `json:"dependPeriod,omitempty"` + // Dependency job failure policy. + // FAIL: Stop the job and set the job to the failed state. + // IGNORE: Continue to run the job. + // SUSPEND: Suspend the job. + // Default value: FAIL + DependFailPolicy string `json:"dependFailPolicy,omitempty"` +} + +type Property struct { + // Property name + Name string `json:"name" required:"true"` + // Property value + Value string `json:"value" required:"true"` +} + +type BasicConfig struct { + // Job owner. The length cannot exceed 128 characters. + Owner string `json:"owner,omitempty"` + // Job priority. The value ranges from 0 to 2. The default value is 0. 0 indicates a top priority, 1 indicates a medium priority, and 2 indicates a low priority. + Priority int `json:"priority,omitempty"` + // Job execution user. The value must be an existing username. + ExecuteUser string `json:"executeUser,omitempty"` + // Instance timeout interval. The unit is minute. The value ranges from 5 to 1440. The default value is 60. + InstanceTimeout int `json:"instanceTimeout,omitempty"` + // User-defined field. The length cannot exceed 2048 characters. + CustomFields map[string]string `json:"customFields,omitempty"` +} + +type JobApprover struct { + // Approver name. + ApproverName string `json:"approverName" required:"true"` +} + +// Create is used to create a job. A job consists of one or more nodes, such as Hive SQL and CDM Job nodes. DLF supports two types of jobs: batch jobs and real-time jobs. +// Send request POST /v1/{project_id}/jobs +func Create(client *golangsdk.ServiceClient, opts Job, workspace string) error { + b, err := build.RequestBody(opts, "") + if err != nil { + return err + } + + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + } + + if workspace != "" { + reqOpts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err = client.Post(client.ServiceURL(jobsEndpoint), b, nil, reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/Delete.go b/openstack/dataarts/v1/job/Delete.go new file mode 100644 index 000000000..f13eaf7c2 --- /dev/null +++ b/openstack/dataarts/v1/job/Delete.go @@ -0,0 +1,34 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +type DeleteReq struct { + Approvers []JobApprover `json:"approvers,omitempty"` +} + +// Delete is used to stop a job. +// Send request POST /v1/{project_id}/jobs/{job_name} +func Delete(client *golangsdk.ServiceClient, jobName, workspace string, reqOpts *DeleteReq) error { + b, err := build.RequestBody(reqOpts, "") + if err != nil { + return err + } + + opts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{}, + OkCodes: []int{204}, + } + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err = client.DeleteWithBody(client.ServiceURL(jobsEndpoint, jobName), b, opts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/ExecuteImmediately.go b/openstack/dataarts/v1/job/ExecuteImmediately.go new file mode 100644 index 000000000..2a74813be --- /dev/null +++ b/openstack/dataarts/v1/job/ExecuteImmediately.go @@ -0,0 +1,52 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const executeImmediatelyEndpoint = "run-immediate" + +type ExecuteImmediatelyReq struct { + // Parameters for executing a job immediately + JobParams []*JobParam `json:"jobParams,omitempty"` +} + +type JobParam struct { + // Name of the parameter. It cannot exceed 64 characters. + Name string `json:"name" required:"true"` + // Value of the parameter. It cannot exceed 1,024 characters. + Value string `json:"value" required:"true"` + // Parameter type + // variable + // constants + ParamType string `json:"paramType,omitempty"` +} + +// ExecuteImmediately is used to execute a job immediately and check whether the job can be executed successfully. +// Send request POST /v1/{project_id}/jobs/{job_name}/run-immediate +func ExecuteImmediately(client *golangsdk.ServiceClient, jobName, workspace string, reqOpts *ExecuteImmediatelyReq) (*ExecuteImmediatelyResp, error) { + b, err := build.RequestBody(reqOpts, "") + if err != nil { + return nil, err + } + + opts := &golangsdk.RequestOpts{} + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + raw, err := client.Post(client.ServiceURL(jobsEndpoint, jobName, executeImmediatelyEndpoint), b, nil, opts) + if err != nil { + return nil, err + } + + var res *ExecuteImmediatelyResp + err = extract.Into(raw.Body, res) + return res, err +} + +type ExecuteImmediatelyResp struct { + // Job instance ID. + InstanceId int64 `json:"instanceId"` +} diff --git a/openstack/dataarts/v1/job/ExportJob.go b/openstack/dataarts/v1/job/ExportJob.go new file mode 100644 index 000000000..ae1e22faf --- /dev/null +++ b/openstack/dataarts/v1/job/ExportJob.go @@ -0,0 +1,25 @@ +package job + +import ( + "io" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +const exportEndpoint = "export" + +// ExportJob is used to export a job, including job definitions, job dependency scripts, and CDM job definitions. +// Send request POST /v1/{project_id}/jobs/{job_name}/export +func ExportJob(client *golangsdk.ServiceClient, jobName, workspace string) (io.ReadCloser, error) { + + opts := &golangsdk.RequestOpts{} + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + raw, err := client.Post(client.ServiceURL(jobsEndpoint, exportEndpoint), nil, nil, opts) + if err != nil { + return nil, err + } + + return raw.Body, err +} diff --git a/openstack/dataarts/v1/job/Get.go b/openstack/dataarts/v1/job/Get.go new file mode 100644 index 000000000..8d9d9fa42 --- /dev/null +++ b/openstack/dataarts/v1/job/Get.go @@ -0,0 +1,29 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// Get is used to view job details. +// Send request GET /v1/{project_id}/jobs/{name} +func Get(client *golangsdk.ServiceClient, jobName, workspace string) (*Job, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(jobsEndpoint, jobName), nil, opts) + if err != nil { + return nil, err + } + + var res *Job + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/openstack/dataarts/v1/job/GetJobFile.go b/openstack/dataarts/v1/job/GetJobFile.go new file mode 100644 index 000000000..38e1cc9ca --- /dev/null +++ b/openstack/dataarts/v1/job/GetJobFile.go @@ -0,0 +1,64 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const checkFileEndpoint = "check-file" + +type GetJobFileParams struct { + // If OBS is deployed, the job definition file is stored on OBS, for example, obs://myBucket/jobs.zip. + Path string `json:"path,omitempty"` +} + +// GetJobFile is used to check whether there are jobs and scripts in the job file to be imported from OBS to DLF. +// Send request POST /v1/{project_id}/jobs/check-file +func GetJobFile(client *golangsdk.ServiceClient, opts *GetJobFileParams) (*GetJobFileResp, error) { + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + reqOpts := &golangsdk.RequestOpts{ + OkCodes: []int{204}, + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + } + + raw, err := client.Post(client.ServiceURL(jobsEndpoint, checkFileEndpoint), b, nil, reqOpts) + if err != nil { + return nil, err + } + + var resp *GetJobFileResp + err = extract.Into(raw.Body, resp) + if err != nil { + return nil, err + } + + return resp, nil +} + +type GetJobFileResp struct { + // Job information. + Jobs []*JobFile `json:"jobs,omitempty"` + // Script information. + Scripts []*Script `json:"scripts,omitempty"` +} + +type JobFile struct { + // Job parameter. + Params map[string]string `json:"params,omitempty"` + // Job name. + Name string `json:"name"` + // Path of the job. + Path string `json:"path"` +} + +type Script struct { + // Script name. + Name string `json:"name"` + // Path of the script. + Path string `json:"path"` +} diff --git a/openstack/dataarts/v1/job/GetJobInstance.go b/openstack/dataarts/v1/job/GetJobInstance.go new file mode 100644 index 000000000..a542a20b0 --- /dev/null +++ b/openstack/dataarts/v1/job/GetJobInstance.go @@ -0,0 +1,97 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// GetJobInstance is used to view job instance details, including the execution information about each node in a job instance. +// Send request GET /v1/{project_id}/jobs/{job_name}/instances/{instance_id} +func GetJobInstance(client *golangsdk.ServiceClient, jobName, instanceId, workspace string) (*JobInstanceResp, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(jobsEndpoint, jobName, instancesEndpoint, instanceId), nil, opts) + if err != nil { + return nil, err + } + + var res *JobInstanceResp + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} + +type JobInstanceResp struct { + // Job name. + JobName string `json:"jobName"` + // Job instance ID. + InstanceId int64 `json:"instanceId"` + // Job instance status. + // waiting + // running + // success + // fail + // running-exception + // pause + // manual-stop + Status string `json:"status"` + // Planned execution time of the job instance. + PlanTime int64 `json:"planTime"` + // Actual execution start time of the job instance. + StartTime int64 `json:"startTime"` + // Actual execution end time of the job instance. + EndTime int64 `json:"endTime,omitempty"` + // Execution duration in milliseconds. + ExecuteTime int64 `json:"executeTime,omitempty"` + // Total number of node records. + Total int `json:"total"` + // Node instance status. + Nodes []NodeJobInstanceResp `json:"nodes"` + // Whether the job instance status is forcibly successful + // + // Default value: false + ForceSuccess bool `json:"forceSuccess,omitempty"` + // Whether the job instance status is failure ignored + // + // Default value: false + IgnoreSuccess bool `json:"ignoreSuccess,omitempty"` +} + +type NodeJobInstanceResp struct { + // Node name. + NodeName string `json:"nodeName"` + // Node status. + // waiting + // running + // success + // fail + // skip + // pause + // manual-stop + Status string `json:"status,omitempty"` + // Planned execution time of the job instance. + PlanTime int64 `json:"planTime"` + // Actual execution start time of the job instance. + StartTime int64 `json:"startTime"` + // Actual execution end time of the job instance. + EndTime int64 `json:"endTime,omitempty"` + // Node type. + Type string `json:"type"` + // Number of attempts upon a failure. + RetryTimes int `json:"retryTimes,omitempty"` + // Job instance ID. + InstanceId int64 `json:"instanceId"` + // Rows of input data. + InputRowCount int64 `json:"inputRowCount,omitempty"` + // Write speed (row/second) + Speed float64 `json:"speed,omitempty"` + // Path for storing node execution logs. + LogPath string `json:"logPath,omitempty"` +} diff --git a/openstack/dataarts/v1/job/GetJobInstanceList.go b/openstack/dataarts/v1/job/GetJobInstanceList.go new file mode 100644 index 000000000..7929ba450 --- /dev/null +++ b/openstack/dataarts/v1/job/GetJobInstanceList.go @@ -0,0 +1,134 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const detailEndpoint = "detail" + +type GetJobInstanceListReq struct { + // Project ID. + ProjectId string `q:"project_id" required:"true"` + // Job name. + // If you want to query the instance list of a specific batch job, jobName is the batch job name. + // If you want to query sub-jobs associated with a node in a real-time job, the jobName format is real-time job name _ node name. + JobName string `q:"jobName"` + // Minimum planned job execution time in milliseconds. Job instances whose start time is greater than this time are returned. + MinPlanTime int64 `q:"minPlanTime"` + // Minimum planned job execution time in milliseconds. Job instances whose start time is less than this time are returned. + MaxPlanTime int64 `q:"maxPlanTime"` + // The maximum number of records on each page. + // The parameter value ranges from 1 to 1000. + // Default value: 10 + Limit int `q:"limit"` + // Start page of the paging list. The default value is 0. The value must be greater than or equal to 0. + Offset int `q:"offset"` + // Job instance status. + // waiting + // running + // success + // fail + // running-exception + // pause + // manual-stop + Status string `q:"status"` + // Job scheduling modes. + // 0: General scheduling + // 2: Manual scheduling + // 5: PatchData + // 6: Subjob scheduling + // 7: Schedule once + InstanceType int `q:"instanceType"` + // Whether exact search of jobs by name is supported + PreciseQuery bool `q:"preciseQuery"` +} + +// GetJobInstanceList is used to view a job instance list. +// +// A job instance is generated each time you run a batch job for which periodic scheduling or event-based scheduling is configured. +// If a real-time job contains a node for which periodic scheduling or event-based scheduling is configured, you can call this API to view the instance list of the subjobs associated with the node. +// The format of the jobName parameter is real-time job name_node name. +// +// Send request GET /v1/{project_id}/jobs/instances/detail?jobName={jobName}&minPlanTime={minPlanTime}&maxPlanTime={maxPlanTime}&limit={limit}&offset={offset}&status={status}&instanceType={instanceType}&preciseQuery={preciseQuery} +func GetJobInstanceList(client *golangsdk.ServiceClient, reqOpts GetJobInstanceListReq, workspace string) (*GetJobInstanceListResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(jobsEndpoint, instancesEndpoint, detailEndpoint).WithQueryParams(&reqOpts).Build() + if err != nil { + return nil, err + } + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(url.String(), nil, opts) + + if err != nil { + return nil, err + } + + var res *GetJobInstanceListResp + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} + +type GetJobInstanceListResp struct { + // Total number of records. + Total int `json:"total"` + // Job instance status. + Instances []*NodeStatusListResp `json:"instances"` +} + +type NodeStatusListResp struct { + // Job name. When you view the instance list of a specified batch job, jobName is the name of the batch job. + // When you view the subjobs associated with a node in a real-time job, jobName is in format of real-time job name_node name. + JobName string `json:"jobName"` + // Job ID + JobId string `json:"jobId,omitempty"` + // Name of a job instance recorded by the log, rather than the name defined during job creation + JobInstanceName string `json:"jobInstanceName"` + // Job instance ID, which is used to query job instance details. + InstanceId int64 `json:"instanceId"` + // Job instance status. + // waiting + // running + // success + // fail + // running-exception + // pause + // manual-stop + Status string `json:"status"` + // Planned execution time of the job instance. + PlanTime int64 `json:"planTime"` + // Actual execution start time of the job instance. + StartTime int64 `json:"startTime"` + // Actual execution end time of the job instance. + EndTime int64 `json:"endTime,omitempty"` + // Execution duration in milliseconds. + ExecuteTime int64 `json:"executeTime,omitempty"` + + // Time when a job is submitted. + SubmitTime int64 `json:"submitTime"` + // Node instance status. + // Job scheduling modes. + // 0: General scheduling + // 2: Manual scheduling + // 5: PatchData + // 6: Subjob scheduling + // 7: Schedule once + InstanceType int `json:"instanceType"` + // Whether the job instance status is forcibly successful + // + // Default value: false + ForceSuccess bool `json:"forceSuccess,omitempty"` + // Whether the job instance status is failure ignored + // + // Default value: false + IgnoreSuccess bool `json:"ignoreSuccess,omitempty"` + // Job instance version + Version bool `json:"version,omitempty"` +} diff --git a/openstack/dataarts/v1/job/GetRunningStatus.go b/openstack/dataarts/v1/job/GetRunningStatus.go new file mode 100644 index 000000000..d8a152b97 --- /dev/null +++ b/openstack/dataarts/v1/job/GetRunningStatus.go @@ -0,0 +1,83 @@ +package job + +import ( + "time" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const statusEndpoint = "status" + +// GetRunningStatus is used to view running status of a real-time job. +// Send request GET /v1/{project_id}/jobs/{job_name}/status +func GetRunningStatus(client *golangsdk.ServiceClient, jobName, workspace string) (*RunningStatusResp, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(jobsEndpoint, jobName, statusEndpoint), nil, opts) + if err != nil { + return nil, err + } + + var res *RunningStatusResp + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} + +type RunningStatusResp struct { + // Name of a solution. + Name string `json:"name"` + // Node status list. + Nodes []*NodeStatusResp `json:"nodes,omitempty"` + // Job status. + // STARTING + // NORMAL + // EXCEPTION + // STOPPING + // STOPPED + Status string `json:"status,omitempty"` + // Start time. + StartTime time.Time `json:"startTime"` + // End time. + EndTime *time.Time `json:"endTime,omitempty"` + // Last update time. + LastUpdateTime *time.Time `json:"lastUpdateTime,omitempty"` +} + +type NodeStatusResp struct { + // Node name. + Name string `json:"name"` + // Node status. + // STARTING + // NORMAL + // EXCEPTION + // STOPPING + // STOPPED + Status string `json:"status,omitempty"` + // Path for storing node run logs. + LogPath string `json:"logPath,omitempty"` + // Node type. + // Hive SQL: Runs Hive SQL scripts. + // Spark SQL: Runs Spark SQL scripts. + // DWS SQL: Runs DWS SQL scripts. + // DLI SQL: Runs DLI SQL scripts. + // Shell: Runs shell SQL scripts. + // CDM Job: Runs CDM jobs. + // DIS Transfer Task: Creates DIS dump tasks. + // CS Job: Creates and starts CloudStream jobs. + // CloudTable Manager: Manages CloudTable tables, including creating and deleting tables. + // OBS Manager: Manages OBS paths, including creating and deleting paths. + // RESTAPI: Sends REST API requests. + // SMN: Sends short messages or emails. + // MRS Spark: Runs Spark jobs of MRS. + // MapReduce: Runs MapReduce jobs of MRS. + Type string `json:"type"` +} diff --git a/openstack/dataarts/v1/job/GetSystemTask.go b/openstack/dataarts/v1/job/GetSystemTask.go new file mode 100644 index 000000000..e6a9073f6 --- /dev/null +++ b/openstack/dataarts/v1/job/GetSystemTask.go @@ -0,0 +1,69 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +const systemTasksEndpoint = "system-tasks" + +// GetSystemTask is used to query details about asynchronous tasks. +// Send request GET /v1/{project_id}/system-tasks/{task_id} +func GetSystemTask(client *golangsdk.ServiceClient, taskId, workspace string) (*SystemTaskResp, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(systemTasksEndpoint, taskId), nil, opts) + if err != nil { + return nil, err + } + + var res *SystemTaskResp + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} + +type SystemTaskResp struct { + // Task ID. + Id string `json:"id"` + // Name of the task. + Name string `json:"name"` + // Start time. + StartTime int64 `json:"startTime"` + // End time. + EndTime int64 `json:"endTime,omitempty"` + // Time when the task was last updated. + LastUpdate int64 `json:"lastUpdate"` + // Task status. + // RUNNING + // SUCCESSFUL + // FAILED + Status string `json:"status"` + // Project ID + ProjectId string `json:"projectId,omitempty"` + // Subtask. + SubTasks []*SubTask `json:"subtasks,omitempty"` +} + +type SubTask struct { + // Subtask ID. + Id string `json:"id"` + // Name of the subtask. + Name string `json:"name"` + // Time when the task was last updated. + LastUpdate int64 `json:"lastUpdate"` + // Task status. + // RUNNING + // SUCCESSFUL + // FAILED + Status string `json:"status"` + // Task information. + TaskId string `json:"taskId,omitempty"` +} diff --git a/openstack/dataarts/v1/job/ImportJob.go b/openstack/dataarts/v1/job/ImportJob.go new file mode 100644 index 000000000..7583a63dd --- /dev/null +++ b/openstack/dataarts/v1/job/ImportJob.go @@ -0,0 +1,58 @@ +package job + +import ( + "io" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +const importEndpoint = "import" + +type ImportReq struct { + // If OBS is deployed, it refers to the OBS path for storing the job definition file. For the format of the job definition file, see the response message of the exported job, for example, obs://myBucket/jobs.zip. + Path string `json:"path" required:"true"` + // Public job parameter. + Params map[string]string `json:"params,omitempty"` + // Policy for specifying how to handle duplicate names. The options are as follows: + // SKIP + // OVERWRITE + // Default value: SKIP + SameNamePolicy string `json:"sameNamePolicy,omitempty"` + // Job parameter. + JobsParam []*JobParamImported `json:"jobsParam,omitempty"` + // User that executes the job. + ExecuteUser string `json:"executeUser,omitempty"` + // This parameter is required if the review function is enabled. It indicates the target status of the job. The value can be SAVED, SUBMITTED, or PRODUCTION. + // SAVED indicates that the job is saved but cannot be scheduled or executed. It can be executed only after submitted and approved. + // SUBMITTED indicates that the job is automatically submitted after it is saved and can be executed after it is approved. + // PRODUCTION indicates that the job can be directly executed after it is created. Note: Only the workspace administrator can create jobs in the PRODUCTION state. + TargetStatus string `json:"targetStatus,omitempty"` + // Job approver. This parameter is required if the review function is enabled. + Approvers []*JobApprover `json:"approvers,omitempty"` +} + +type JobParamImported struct { + Name string `json:"name" required:"true"` + Params map[string]string `json:"params,omitempty"` +} + +// ImportJob is used to import one or more job files from OBS to DLF. +// Send request POST /v1/{project_id}/jobs/import +func ImportJob(client *golangsdk.ServiceClient, jobName, workspace string) (io.ReadCloser, error) { + + opts := &golangsdk.RequestOpts{} + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + raw, err := client.Post(client.ServiceURL(jobsEndpoint, importEndpoint), nil, nil, opts) + if err != nil { + return nil, err + } + + return raw.Body, err +} + +type ImportResp struct { + // ID of the task. Used to call the API for querying system tasks to obtain the import status. + TaskId string `json:"taskId" required:"true"` +} diff --git a/openstack/dataarts/v1/job/List.go b/openstack/dataarts/v1/job/List.go new file mode 100644 index 000000000..08143e097 --- /dev/null +++ b/openstack/dataarts/v1/job/List.go @@ -0,0 +1,93 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type ListOpts struct { + Offset int `q:"offset"` + Limit int `q:"limit"` + JobType string `q:"jobType"` + JobName string `q:"jobName"` +} + +// List is used to query a list of batch or real-time jobs. A maximum of 100 jobs can be returned for each query. +// Send request GET /v1/{project_id}/jobs?jobType={jobType}&offset={offset}&limit={limit}&jobName={jobName} +func List(client *golangsdk.ServiceClient, opts *ListOpts, workspace string) (*ListResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(jobsEndpoint).WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + var reqOpts *golangsdk.RequestOpts + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, reqOpts) + if err != nil { + return nil, err + } + + var res *ListResp + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} + +type ListResp struct { + // Total is the number of jobs. + Total int `json:"total"` + // Jobs is a list of jobs. + Jobs []*JobList `json:"jobs"` +} + +type JobList struct { + // Job name. + Name string `json:"name"` + // Job type. + // REAL_TIME: real-time processing + // BATCH: batch processing + JobType string `json:"jobType"` + // Job owner. The length cannot exceed 128 characters. + Owner string `json:"owner,omitempty"` + // Job priority. The value ranges from 0 to 2. The default value is 0. 0 indicates a top priority, 1 indicates a medium priority, and 2 indicates a low priority. + Priority int `json:"priority,omitempty"` + // Job status. + // When jobType is set to REAL_TIME, the status is as follows: + // STARTING + // NORMAL + // EXCEPTION + // STOPPING + // STOPPED + // + // When jobType is set to BATCH, the status is as follows: + // SCHEDULING + // STOPPED + // PAUSED + Status string `json:"status"` + // Job creator. + CreateUser string `json:"createUser"` + // Time when the job is created. + CreateTime int64 `json:"createTime"` + // Time when the job starts running. + StartTime int64 `json:"startTime,omitempty"` + // Time when the job stops running. + EndTime int64 `json:"endTime,omitempty"` + // Most recent running status of the job instance. This parameter is available only when jobType is set to BATCH. + LastInstanceStatus string `json:"lastInstanceStatus,omitempty"` + // Time when the most recent job instance stops to run. This parameter is available only when jobType is set to BATCH. + LastInstanceEndTime int64 `json:"lastInstanceEndTime,omitempty"` + // Time when the job was last updated. + LastUpdateTime int64 `json:"lastUpdateTime,omitempty"` + // User who last updated the job. + LastUpdateUser string `json:"lastUpdateUser,omitempty"` + // Path of the job. + Path string `json:"path,omitempty"` + // Whether the job is a single-task job. + SingleNodeJobFlag bool `json:"singleNodeJobFlag,omitempty"` +} diff --git a/openstack/dataarts/v1/job/RetryInstance.go b/openstack/dataarts/v1/job/RetryInstance.go new file mode 100644 index 000000000..2c155400e --- /dev/null +++ b/openstack/dataarts/v1/job/RetryInstance.go @@ -0,0 +1,26 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +const restartEndpoint = "restart" + +// RetryInstance is used to retry a specific job instance. A job instance can be retried only when it is in the successful, failed, or canceled state. +// Send request POST /v1/{project_id}/jobs/{job_name}/instances/{instance_id}/restart +func RetryInstance(client *golangsdk.ServiceClient, jobName, instanceId, workspace string) error { + opts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{}, + OkCodes: []int{204}, + } + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err := client.Post(client.ServiceURL(jobsEndpoint, jobName, instancesEndpoint, instanceId, restartEndpoint), nil, nil, opts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/Start.go b/openstack/dataarts/v1/job/Start.go new file mode 100644 index 000000000..ffe3725c2 --- /dev/null +++ b/openstack/dataarts/v1/job/Start.go @@ -0,0 +1,39 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +const startEndpoint = "start" + +type StartReq struct { + // Parameter for starting the job. + JobParams []*JobParam `json:"jobParams,omitempty"` +} + +// Start is used to start a job. +// Send request POST /v1/{project_id}/jobs/{job_name}/start +func Start(client *golangsdk.ServiceClient, jobName, workspace string, reqOpts *StartReq) error { + b, err := build.RequestBody(reqOpts, "") + if err != nil { + return err + } + + opts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{ + HeaderContentType: ApplicationJson, + }, + OkCodes: []int{204}, + } + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err = client.Post(client.ServiceURL(jobsEndpoint, jobName, startEndpoint), b, nil, opts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/Stop.go b/openstack/dataarts/v1/job/Stop.go new file mode 100644 index 000000000..b1be4111d --- /dev/null +++ b/openstack/dataarts/v1/job/Stop.go @@ -0,0 +1,24 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +// Stop is used to stop a job. +// Send request POST /v1/{project_id}/jobs/{job_name}/stop +func Stop(client *golangsdk.ServiceClient, jobName, workspace string) error { + opts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{}, + OkCodes: []int{204}, + } + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err := client.Post(client.ServiceURL(jobsEndpoint, jobName, stopEndpoint), nil, nil, opts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/StopInstance.go b/openstack/dataarts/v1/job/StopInstance.go new file mode 100644 index 000000000..d65614b92 --- /dev/null +++ b/openstack/dataarts/v1/job/StopInstance.go @@ -0,0 +1,24 @@ +package job + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +// StopInstance is used to stop a specific job instance. A job instance can be stopped only when it is in the running state. +// Send request POST /v1/{project_id}/jobs/{job_name}/instances/{instance_id}/stop +func StopInstance(client *golangsdk.ServiceClient, jobName, instanceId, workspace string) error { + opts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{}, + OkCodes: []int{204}, + } + if workspace != "" { + opts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err := client.Post(client.ServiceURL(jobsEndpoint, jobName, instancesEndpoint, instanceId, stopEndpoint), nil, nil, opts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/Update.go b/openstack/dataarts/v1/job/Update.go new file mode 100644 index 000000000..cb9c6c600 --- /dev/null +++ b/openstack/dataarts/v1/job/Update.go @@ -0,0 +1,32 @@ +package job + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +// Update is used to edit a job. +// Send request PUT /v1/{project_id}/jobs/{job_name} +func Update(client *golangsdk.ServiceClient, jobName, workspace string, job Job) error { + + b, err := build.RequestBody(job, "") + if err != nil { + return err + } + + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + _, err = client.Put(client.ServiceURL(jobsEndpoint, jobName), b, nil, reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/job/common.go b/openstack/dataarts/v1/job/common.go new file mode 100644 index 000000000..43e7ff5da --- /dev/null +++ b/openstack/dataarts/v1/job/common.go @@ -0,0 +1,14 @@ +package job + +const ( + HeaderWorkspace = "workspace" + HeaderContentType = "Content-Type" + + ApplicationJson = "application/json" +) + +const ( + jobsEndpoint = "jobs" + instancesEndpoint = "instances" + stopEndpoint = "stop" +) diff --git a/openstack/dataarts/v1/resource/Create.go b/openstack/dataarts/v1/resource/Create.go new file mode 100644 index 000000000..7a17f7549 --- /dev/null +++ b/openstack/dataarts/v1/resource/Create.go @@ -0,0 +1,61 @@ +package resource + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type Resource struct { + // Name is a name of the resource. The name contains a maximum of 32 characters, including only letters, numbers, underscores (_), and hyphens (-). + Name string `json:"name" required:"true"` + // Type is a resource type. Can be: archive, file, jar + Type string `json:"type" required:"true"` + // Location is an OBS path for storing the resource file. When type is set to jar, location is the path for storing the main JAR package. The path contains a maximum of 1,023 characters. For example, obs://myBucket/test.jar + Location string `json:"location" required:"true"` + // JAR package and properties file that the main JAR package depends on. The description contains a maximum of 10,240 characters. If this parameter and the dependFiles parameter are both available, this parameter is preferentially parsed. + DependPackages []*DependPackage `json:"dependPackages,omitempty"` + // DependFiles is a JAR package and properties file that the main JAR package depends on. The description contains a maximum of 10,240 characters. + DependFiles []string `json:"dependFiles,omitempty"` + // Description of the resource. The description contains a maximum of 255 characters. + Desc string `json:"desc,omitempty"` + // Directory for storing the resource. Access the DataArts Studio console and choose Data Development. The default directory is the root directory. + Directory string `json:"directory,omitempty"` +} + +type DependPackage struct { + // Type is a file type. + Type string `json:"type,omitempty"` + // Location is a file path. + Location string `json:"location,omitempty"` +} + +// Create is used to create a resource. Types of nodes, including DLI Spark, MRS Spark, and MRS MapReduce, can reference files such as JAR and properties through resources. +// Send request POST /v1/{project_id}/resources +func Create(client *golangsdk.ServiceClient, opts Resource, workspace string) (*CreateResp, error) { + b, err := build.RequestBody(opts, "") + if err != nil { + return nil, err + } + + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + } + + if workspace != "" { + reqOpts.MoreHeaders[HeaderWorkspace] = workspace + } + + raw, err := client.Post(client.ServiceURL(resourcesEndpoint), b, nil, reqOpts) + if err != nil { + return nil, err + } + + var resp *CreateResp + err = extract.Into(raw.Body, resp) + return resp, err +} + +type CreateResp struct { + ResourceId string `json:"resourceId"` +} diff --git a/openstack/dataarts/v1/resource/Delete.go b/openstack/dataarts/v1/resource/Delete.go new file mode 100644 index 000000000..c07b1d1a7 --- /dev/null +++ b/openstack/dataarts/v1/resource/Delete.go @@ -0,0 +1,26 @@ +package resource + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +// Delete is used to delete a resource. +// Send request DELETE /v1/{project_id}/resources/{resource_id} +func Delete(client *golangsdk.ServiceClient, resourceId, workspace string) error { + var err error + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders[HeaderWorkspace] = workspace + } + + _, err = client.Delete(client.ServiceURL(resourcesEndpoint, resourceId), reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/resource/Get.go b/openstack/dataarts/v1/resource/Get.go new file mode 100644 index 000000000..5c572d700 --- /dev/null +++ b/openstack/dataarts/v1/resource/Get.go @@ -0,0 +1,29 @@ +package resource + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +// Get is used to query resource details. A resource contains various files such as JAR, ZIP, and properties files. A created resource can be used in job nodes such as DLI Spark and MRS Spark. +// Send request GET /v1/{project_id}/resources/{resource_id} +func Get(client *golangsdk.ServiceClient, resourceId, workspace string) (*Resource, error) { + + var opts *golangsdk.RequestOpts + if workspace != "" { + opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(resourcesEndpoint, resourceId), nil, opts) + if err != nil { + return nil, err + } + + var res *Resource + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/openstack/dataarts/v1/resource/List.go b/openstack/dataarts/v1/resource/List.go new file mode 100644 index 000000000..c1b6ea006 --- /dev/null +++ b/openstack/dataarts/v1/resource/List.go @@ -0,0 +1,46 @@ +package resource + +import ( + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" +) + +type ListOpts struct { + Offset int `q:"offset"` + Limit int `q:"limit"` + ResourceName string `q:"resourceName"` +} + +// List is used to query a resource list. During the query, you can specify the page number and the maximum number of records on each page. +// Send request GET /v1/{project_id}/resources?offset={offset}&limit={limit}&resourceName={resourceName} +func List(client *golangsdk.ServiceClient, opts *ListOpts, workspace string) (*ListResp, error) { + url, err := golangsdk.NewURLBuilder().WithEndpoints(resourcesEndpoint).WithQueryParams(&opts).Build() + if err != nil { + return nil, err + } + + var reqOpts *golangsdk.RequestOpts + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + raw, err := client.Get(client.ServiceURL(url.String()), nil, reqOpts) + if err != nil { + return nil, err + } + + var res *ListResp + err = extract.Into(raw.Body, res) + if err != nil { + return nil, err + } + + return res, nil +} + +type ListResp struct { + // Total is the total number of resources. + Total int `json:"total"` + // Resources is a list of resources. + Resources []*Resource `json:"resources"` +} diff --git a/openstack/dataarts/v1/resource/Update.go b/openstack/dataarts/v1/resource/Update.go new file mode 100644 index 000000000..2e940adc0 --- /dev/null +++ b/openstack/dataarts/v1/resource/Update.go @@ -0,0 +1,32 @@ +package resource + +import ( + "github.com/opentelekomcloud/gophertelekomcloud" + "github.com/opentelekomcloud/gophertelekomcloud/internal/build" +) + +// Update is used to modify a specific resource. When modifying the resource, specify the resource ID. The resource type and directory cannot be modified. +// Send request PUT /v1/{project_id}/resources/{resource_id} +func Update(client *golangsdk.ServiceClient, resourceId, workspace string, resource Resource) error { + + b, err := build.RequestBody(resource, "") + if err != nil { + return err + } + + reqOpts := &golangsdk.RequestOpts{ + MoreHeaders: map[string]string{HeaderContentType: ApplicationJson}, + OkCodes: []int{204}, + } + + if workspace != "" { + reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} + } + + _, err = client.Put(client.ServiceURL(resourcesEndpoint, resourceId), b, nil, reqOpts) + if err != nil { + return err + } + + return nil +} diff --git a/openstack/dataarts/v1/resource/common.go b/openstack/dataarts/v1/resource/common.go new file mode 100644 index 000000000..208f8c9b1 --- /dev/null +++ b/openstack/dataarts/v1/resource/common.go @@ -0,0 +1,10 @@ +package resource + +const ( + HeaderWorkspace = "workspace" + HeaderContentType = "Content-Type" + + ApplicationJson = "application/json" +) + +const resourcesEndpoint = "instances" diff --git a/openstack/dataarts/v1/script/Create.go b/openstack/dataarts/v1/script/Create.go index 52c6db037..8374562c8 100644 --- a/openstack/dataarts/v1/script/Create.go +++ b/openstack/dataarts/v1/script/Create.go @@ -56,7 +56,7 @@ func Create(client *golangsdk.ServiceClient, opts Script, workspace string) erro reqOpts.MoreHeaders[HeaderWorkspace] = workspace } - _, err = client.Post(client.ServiceURL(scriptsURL), b, nil, reqOpts) + _, err = client.Post(client.ServiceURL(scriptsEndpoint), b, nil, reqOpts) if err != nil { return err } diff --git a/openstack/dataarts/v1/script/Delete.go b/openstack/dataarts/v1/script/Delete.go index 19c1ff9b0..18cfcab80 100644 --- a/openstack/dataarts/v1/script/Delete.go +++ b/openstack/dataarts/v1/script/Delete.go @@ -32,7 +32,7 @@ func Delete(client *golangsdk.ServiceClient, scriptName, workspace string, opts reqOpts.MoreHeaders[HeaderWorkspace] = workspace } - _, err = client.DeleteWithBody(client.ServiceURL(scriptsURL, scriptName), b, reqOpts) + _, err = client.DeleteWithBody(client.ServiceURL(scriptsEndpoint, scriptName), b, reqOpts) if err != nil { return err } diff --git a/openstack/dataarts/v1/script/Execute.go b/openstack/dataarts/v1/script/Execute.go index a8fb8dad4..8329478ce 100644 --- a/openstack/dataarts/v1/script/Execute.go +++ b/openstack/dataarts/v1/script/Execute.go @@ -6,7 +6,7 @@ import ( "github.com/opentelekomcloud/gophertelekomcloud/internal/extract" ) -const executeURL = "execute" +const executeEndpoint = "execute" type ExecuteReq struct { Params map[string]string `json:"params,omitempty"` @@ -36,7 +36,7 @@ func Execute(client *golangsdk.ServiceClient, scriptName, workspace string, opts reqOpts.MoreHeaders[HeaderWorkspace] = workspace } - raw, err := client.Post(client.ServiceURL(scriptsURL, scriptName, executeURL), b, nil, reqOpts) + raw, err := client.Post(client.ServiceURL(scriptsEndpoint, scriptName, executeEndpoint), b, nil, reqOpts) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/script/Get.go b/openstack/dataarts/v1/script/Get.go index 44348626f..02b92d5d2 100644 --- a/openstack/dataarts/v1/script/Get.go +++ b/openstack/dataarts/v1/script/Get.go @@ -14,7 +14,7 @@ func Get(client *golangsdk.ServiceClient, scriptName, workspace string) (*Script opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} } - raw, err := client.Get(client.ServiceURL(scriptsURL, scriptName), nil, opts) + raw, err := client.Get(client.ServiceURL(scriptsEndpoint, scriptName), nil, opts) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/script/GetExecution.go b/openstack/dataarts/v1/script/GetExecution.go index 053572390..6bae106da 100644 --- a/openstack/dataarts/v1/script/GetExecution.go +++ b/openstack/dataarts/v1/script/GetExecution.go @@ -14,7 +14,7 @@ func GetExecutionResult(client *golangsdk.ServiceClient, scriptName, instanceId, opts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} } - raw, err := client.Get(client.ServiceURL(scriptsURL, scriptName, instancesURL, instanceId), nil, opts) + raw, err := client.Get(client.ServiceURL(scriptsEndpoint, scriptName, instancesEndpoint, instanceId), nil, opts) if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/script/List.go b/openstack/dataarts/v1/script/List.go index 7840a3e8d..e5b237785 100644 --- a/openstack/dataarts/v1/script/List.go +++ b/openstack/dataarts/v1/script/List.go @@ -14,7 +14,7 @@ type ListOpts struct { // List is used to query the script list. A maximum of 1000 scripts can be returned for each query. // Send request GET /v1/{project_id}/scripts?offset={offset}&limit={limit}&scriptName={scriptName} func List(client *golangsdk.ServiceClient, opts *ListOpts, workspace string) (*ListResp, error) { - url, err := golangsdk.NewURLBuilder().WithEndpoints(scriptsURL).WithQueryParams(&opts).Build() + url, err := golangsdk.NewURLBuilder().WithEndpoints(scriptsEndpoint).WithQueryParams(&opts).Build() if err != nil { return nil, err } diff --git a/openstack/dataarts/v1/script/Stop.go b/openstack/dataarts/v1/script/Stop.go index 98b8d07b9..3ea8a2809 100644 --- a/openstack/dataarts/v1/script/Stop.go +++ b/openstack/dataarts/v1/script/Stop.go @@ -4,7 +4,7 @@ import ( golangsdk "github.com/opentelekomcloud/gophertelekomcloud" ) -const stopURL = "stop" +const stopEndpoint = "stop" // Stop is used to stop executing a script instance. // Send request POST /v1/{project_id}/scripts/{script_name}/instances/{instance_id}/stop @@ -17,7 +17,7 @@ func Stop(client *golangsdk.ServiceClient, scriptName, instanceId, workspace str reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} } - _, err := client.Post(client.ServiceURL(scriptsURL, scriptName, instancesURL, instanceId, stopURL), nil, nil, reqOpts) + _, err := client.Post(client.ServiceURL(scriptsEndpoint, scriptName, instancesEndpoint, instanceId, stopEndpoint), nil, nil, reqOpts) if err != nil { return err } diff --git a/openstack/dataarts/v1/script/Update.go b/openstack/dataarts/v1/script/Update.go index 06922fe5e..025fddd2f 100644 --- a/openstack/dataarts/v1/script/Update.go +++ b/openstack/dataarts/v1/script/Update.go @@ -23,7 +23,7 @@ func Update(client *golangsdk.ServiceClient, scriptName, workspace string, scrip reqOpts.MoreHeaders = map[string]string{HeaderWorkspace: workspace} } - _, err = client.Put(client.ServiceURL(scriptsURL, scriptName), b, nil, reqOpts) + _, err = client.Put(client.ServiceURL(scriptsEndpoint, scriptName), b, nil, reqOpts) if err != nil { return err } diff --git a/openstack/dataarts/v1/script/common.go b/openstack/dataarts/v1/script/common.go index c84df6895..df812f2f4 100644 --- a/openstack/dataarts/v1/script/common.go +++ b/openstack/dataarts/v1/script/common.go @@ -7,6 +7,6 @@ const ( ApplicationJson = "application/json" ) -const instancesURL = "instances" +const instancesEndpoint = "instances" -const scriptsURL = "scripts" +const scriptsEndpoint = "scripts"