This commit is contained in:
asteam
2024-07-25 14:33:38 +03:00
commit 6f40af6a5f
946 changed files with 98335 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
package provider
import (
"github.com/hashicorp/terraform-plugin-framework/datasource"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/account"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/extnet"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/image"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/kvmvm"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/lb"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/rg"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/stack"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/vfpool"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/vins"
cbaccount "repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/account"
cbStack "repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudbroker/stack"
)
func newDataSourcesMap() []func() datasource.DataSource {
return []func() datasource.DataSource{
account.NewDataSourceAccount,
account.NewDataSourceAccountAuditsList,
account.NewDataSourceAccountComputesList,
account.NewDataSourceAccountConsumedUnits,
account.NewDataSourceAccountConsumedUnitsByType,
account.NewDataSourceAccountDisksList,
account.NewDataSourceAccountFlipgroupsList,
account.NewDataSourceAccountList,
account.NewDataSourceAccountListDeleted,
account.NewDataSourceAccountRGList,
account.NewDataSourceAccountTemplatesList,
account.NewDataSourceAccountVinsList,
account.NewDataSourceAccountGetResourceConsumption,
account.NewDataSourceAccountReservedUnits,
account.NewDataSourceAccountGetResourceConsumptionList,
bservice.NewDataSourceBService,
bservice.NewDataSourceBServiceList,
bservice.NewDataSourceBServiceGroup,
bservice.NewDataSourceBServiceDeletedList,
bservice.NewDataSourceBServiceSnapshotList,
disks.NewDataSourceDisk,
disks.NewDataSourceDiskList,
disks.NewDataSourceDiskListDeleted,
disks.NewDataSourceDiskListTypes,
disks.NewDataSourceDiskListTypesDetailed,
disks.NewDataSourceDiskListUnattached,
disks.NewDataSourceDiskSnapshot,
disks.NewDataSourceDiskSnapshotList,
disks.NewDataSourceDiskReplication,
extnet.NewDataSourceExtNet,
extnet.NewDataSourceExtNetComputesList,
extnet.NewDataSourceExtNetDefault,
extnet.NewDataSourceExtNetList,
flipgroup.NewDataSourceFlipgroup,
flipgroup.NewDataSourceFlipgroupList,
image.NewDataSourceImage,
image.NewDataSourceImageList,
k8s.NewDataSourceK8S,
k8s.NewDataSourceK8SWgCloudInit,
k8s.NewDataSourceK8SList,
k8s.NewDataSourceK8SListDeleted,
k8s.NewDataSourceK8SWg,
k8s.NewDataSourceK8SComputes,
k8s.NewDataSourceK8ciList,
k8s.NewDataSourceK8SWgList,
kvmvm.NewDataSourceComputeAudits,
kvmvm.NewDataSourceComputeGetAudits,
kvmvm.NewDataSourceComputeGetConsoleUrl,
kvmvm.NewDataSourceComputeGetLog,
kvmvm.NewDataSourceComputePciDeviceList,
kvmvm.NewDataSourceComputePFWList,
kvmvm.NewDataSourceComputeSnapshotUsage,
kvmvm.NewDataSourceComputeUserList,
kvmvm.NewDataSourceComputeVGPUList,
kvmvm.NewDataSourceComputeList,
kvmvm.NewDataSourceComputeListDeleted,
kvmvm.NewDataSourceCompute,
lb.NewDataSourceLB,
lb.NewDataSourceLBList,
lb.NewDataSourceLBListDeleted,
rg.NewDataSourceRG,
rg.NewDataSourceRGAffinityGroupComputes,
rg.NewDataSourceRGAffinityGroupsGet,
rg.NewDataSourceRGAffinityGroupsList,
rg.NewDataSourceRGAudits,
rg.NewDataSourceRGGetResourceConsumption,
rg.NewDataSourceRGList,
rg.NewDataSourceRGListComputes,
rg.NewDataSourceRGListDeleted,
rg.NewDataSourceRGListLB,
rg.NewDataSourceRGListPFW,
rg.NewDataSourceRGListVins,
rg.NewDataSourceRGResourceConsumptionList,
rg.NewDataSourceRGUsage,
stack.NewDataSourceStack,
stack.NewDataSourceStackList,
vfpool.NewDataSourceVFPool,
vfpool.NewDataSourceVFPoolList,
vins.NewDataSourceVINS,
vins.NewDataSourceVINSAudits,
vins.NewDataSourceVINSExtNetList,
vins.NewDataSourceVINSIPList,
vins.NewDataSourceVINSList,
vins.NewDataSourceVINSListDeleted,
vins.NewDataSourceVINSNATRuleList,
vins.NewDataSourceVINSStaticRoute,
vins.NewDataSourceVINSStaticRouteList,
cbaccount.NewDataSourceAccount,
cbaccount.NewDataSourceAccountList,
cbaccount.NewDataSourceAccountVinsList,
cbStack.NewDataSourceStack,
cbStack.NewDataSourceStackList,
}
}

View File

@@ -0,0 +1,228 @@
package provider
import (
"context"
"crypto/tls"
"net/http"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
log "github.com/sirupsen/logrus"
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
sdk_config "repository.basistech.ru/BASIS/decort-golang-sdk/config"
)
// enumerated constants that define authentication modes for Configure
const (
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
MODE_LEGACY
MODE_DECS3O
MODE_JWT
MODE_BVS
)
// Ensure DynamixProvider satisfies various provider interfaces.
var _ provider.Provider = &DynamixProvider{}
// DynamixProvider defines the provider implementation.
type DynamixProvider struct {
// version is set to the provider version on release, "dev" when the
// provider is built and ran locally, and "test" when running acceptance
// testing.
version string
}
// dynamixProviderModel describes the provider data model.
type dynamixProviderModel struct {
Authenticator types.String `tfsdk:"authenticator"`
Oauth2Url types.String `tfsdk:"oauth2_url"`
ControllerUrl types.String `tfsdk:"controller_url"`
User types.String `tfsdk:"user"`
Password types.String `tfsdk:"password"`
BvsUser types.String `tfsdk:"bvs_user"`
BvsPassword types.String `tfsdk:"bvs_password"`
Domain types.String `tfsdk:"domain"`
AppId types.String `tfsdk:"app_id"`
AppSecret types.String `tfsdk:"app_secret"`
Jwt types.String `tfsdk:"jwt"`
AllowUnverifiedSsl types.Bool `tfsdk:"allow_unverified_ssl"`
PathConfig types.String `tfsdk:"path_config"`
PathToken types.String `tfsdk:"path_token"`
TimeToRefresh types.Int64 `tfsdk:"time_to_refresh"`
}
func (p *DynamixProvider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "dynamix"
resp.Version = p.version
}
func (p *DynamixProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"authenticator": schema.StringAttribute{
MarkdownDescription: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'decs3o', 'legacy', 'jwt' or 'bvs'.",
Required: true,
Validators: []validator.String{
stringvalidator.OneOfCaseInsensitive("decs3o", "legacy", "jwt", "bvs"), // ignore case while validating
},
},
"oauth2_url": schema.StringAttribute{
MarkdownDescription: "OAuth2 application URL in 'decs3o' and 'bvs' authentication mode.",
Optional: true,
},
"controller_url": schema.StringAttribute{
MarkdownDescription: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.",
Required: true,
},
"user": schema.StringAttribute{
MarkdownDescription: "User name for DECORT cloud API operations in 'legacy' authentication mode.",
Optional: true,
},
"password": schema.StringAttribute{
MarkdownDescription: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
Optional: true,
},
"bvs_user": schema.StringAttribute{
MarkdownDescription: "User name for DECORT cloud API operations in 'bvs' authentication mode.",
Optional: true,
},
"bvs_password": schema.StringAttribute{
MarkdownDescription: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
Optional: true,
},
"domain": schema.StringAttribute{
MarkdownDescription: "User password for DECORT cloud API operations in 'bvs' authentication mode.",
Optional: true,
},
"app_id": schema.StringAttribute{
MarkdownDescription: "Application ID to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
Optional: true,
},
"app_secret": schema.StringAttribute{
MarkdownDescription: "Application secret to access DECORT cloud API in 'decs3o' and 'bvs' authentication mode.",
Optional: true,
},
"jwt": schema.StringAttribute{
MarkdownDescription: "JWT to access DECORT cloud API in 'jwt' authentication mode.",
Optional: true,
},
"allow_unverified_ssl": schema.BoolAttribute{
MarkdownDescription: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only! Default is false.",
Optional: true,
},
"path_config": schema.StringAttribute{
MarkdownDescription: "The path of the configuration file entry.",
Optional: true,
},
"path_token": schema.StringAttribute{
MarkdownDescription: "The path of the token file entry.",
Optional: true,
},
"time_to_refresh": schema.Int64Attribute{
MarkdownDescription: "The number of minutes before the expiration of the token, a refresh will be made.",
Optional: true,
},
},
}
}
func (p *DynamixProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
// Retrieve provider data from configuration
var config dynamixProviderModel
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
log.Debugf("Provider Configure error after req.Config.Get")
return
}
// Set up default values, values from env and save user provided values into decortConfig
dynamixConfig := dynamixProviderConfig{}
dynamixConfig.new(config)
// Validate and set up authentication mode
mode, err := dynamixConfig.validateAuthenticator()
if err != nil {
log.Debug(err)
return
}
// Set up client transport
if dynamixConfig.allowUnverifiedSsl {
log.Warn("Provider Configure: allow_unverified_ssl is set - will not check certificates!")
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec
dynamixConfig.cc_client = &http.Client{
Transport: transCfg,
}
} else {
dynamixConfig.cc_client = &http.Client{}
}
// Set up clients for data sources and resources depending on authentication mode
switch mode {
case MODE_LEGACY:
legacyConf := sdk_config.LegacyConfig{
Username: dynamixConfig.user,
Password: dynamixConfig.password,
DecortURL: dynamixConfig.controllerUrl,
SSLSkipVerify: dynamixConfig.allowUnverifiedSsl,
}
legacyClient := decort.NewLegacy(legacyConf)
resp.DataSourceData = legacyClient
resp.ResourceData = legacyClient
case MODE_JWT:
case MODE_DECS3O:
sdkConf := sdk_config.Config{
AppID: dynamixConfig.appId,
AppSecret: dynamixConfig.appSecret,
SSOURL: dynamixConfig.oauth2Url,
DecortURL: dynamixConfig.controllerUrl,
SSLSkipVerify: dynamixConfig.allowUnverifiedSsl,
}
decortClient := decort.New(sdkConf)
resp.DataSourceData = decortClient
resp.ResourceData = decortClient
case MODE_BVS:
bvsConf := sdk_config.BVSConfig{
AppID: dynamixConfig.appId,
AppSecret: dynamixConfig.appSecret,
SSOURL: dynamixConfig.oauth2Url,
DecortURL: dynamixConfig.controllerUrl,
SSLSkipVerify: dynamixConfig.allowUnverifiedSsl,
Username: dynamixConfig.bvsUser,
Password: dynamixConfig.bvsPassword,
Domain: dynamixConfig.domain,
Token: dynamixConfig.token,
PathCfg: dynamixConfig.pathConfig,
PathToken: dynamixConfig.pathToken,
TimeToRefresh: dynamixConfig.timeToRefresh,
}
bvsClient := decort.NewBVS(bvsConf)
resp.DataSourceData = bvsClient
resp.ResourceData = bvsClient
default:
log.Debugf("unknown authenticator mode code %d provided", mode)
return
}
}
func (p *DynamixProvider) Resources(_ context.Context) []func() resource.Resource {
return newResourcesMap()
}
func (p *DynamixProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return newDataSourcesMap()
}
func New(version string) func() provider.Provider {
return func() provider.Provider {
return &DynamixProvider{
version: version,
}
}
}

View File

@@ -0,0 +1,178 @@
package provider
import (
"fmt"
"net/http"
"os"
"strings"
log "github.com/sirupsen/logrus"
sdk_config "repository.basistech.ru/BASIS/decort-golang-sdk/config"
)
// dynamixProviderConfig helps organize provider validation
type dynamixProviderConfig struct {
authenticator string
oauth2Url string
controllerUrl string
user string
password string
bvsUser string
bvsPassword string
domain string
appId string
appSecret string
jwt string
allowUnverifiedSsl bool
pathConfig string
pathToken string
timeToRefresh int64
token sdk_config.Token
cc_client *http.Client
}
// new sets up default values, values from env and save user provided values for decort provider into decortConfig:
// authenticator, oauth2Url, controllerUrl transformed to lowercase;
// oauth2Url, user, password, bvsUser, bvsPassword, domain, appId, appSecret, jwt uploaded from env if not provided;
// allowUnverifiedSsl default value set as false.
func (d *dynamixProviderConfig) new(config dynamixProviderModel) {
d.authenticator = strings.ToLower(config.Authenticator.ValueString())
if config.Oauth2Url.IsUnknown() {
d.oauth2Url = os.Getenv("DECORT_OAUTH2_URL")
} else {
d.oauth2Url = config.Oauth2Url.ValueString()
}
d.oauth2Url = strings.ToLower(d.oauth2Url)
d.controllerUrl = strings.ToLower(config.ControllerUrl.ValueString())
if d.controllerUrl == "" {
log.Debugf("empty DECORT cloud controller URL provided")
return
}
if config.User.IsUnknown() {
d.user = os.Getenv("DECORT_USER")
} else {
d.user = config.User.ValueString()
}
if config.Password.IsUnknown() {
d.password = os.Getenv("DECORT_PASSWORD")
} else {
d.password = config.Password.ValueString()
}
if config.BvsUser.IsUnknown() {
d.bvsUser = os.Getenv("DECORT_BVS_USER")
} else {
d.bvsUser = config.BvsUser.ValueString()
}
if config.BvsPassword.IsUnknown() {
d.bvsPassword = os.Getenv("DECORT_BVS_PASSWORD")
} else {
d.bvsPassword = config.BvsPassword.ValueString()
}
if config.Domain.IsUnknown() {
d.domain = os.Getenv("DECORT_DOMAIN")
} else {
d.domain = config.Domain.ValueString()
}
if config.AppId.IsUnknown() {
d.appId = os.Getenv("DECORT_APP_ID")
} else {
d.appId = config.AppId.ValueString()
}
if config.AppSecret.IsUnknown() {
d.appSecret = os.Getenv("DECORT_APP_SECRET")
} else {
d.appSecret = config.AppSecret.ValueString()
}
if config.Jwt.IsUnknown() {
d.jwt = os.Getenv("DECORT_JWT")
} else {
d.jwt = config.Jwt.ValueString()
}
if config.AllowUnverifiedSsl.IsUnknown() {
d.allowUnverifiedSsl = false // default false
} else {
d.allowUnverifiedSsl = config.AllowUnverifiedSsl.ValueBool()
}
if !config.PathConfig.IsUnknown() {
d.pathConfig = config.PathConfig.ValueString()
}
if !config.PathToken.IsUnknown() {
d.pathToken = config.PathToken.ValueString()
}
if !config.TimeToRefresh.IsUnknown() {
d.timeToRefresh = config.TimeToRefresh.ValueInt64()
}
d.token = sdk_config.Token{}
}
// validateAuthenticator validates authenticator and other parameters from provider configuration provided by user.
// If successful, the mode and nil is returned. If unsuccessful for any
// reason, the method will return mode = MODE_UNDEF and error.
func (d *dynamixProviderConfig) validateAuthenticator() (int, error) {
var mode = MODE_UNDEF
switch d.authenticator {
case "jwt":
if d.jwt == "" {
return mode, fmt.Errorf("authenticator mode 'jwt' specified but no JWT provided")
}
mode = MODE_JWT
case "decs3o":
if d.oauth2Url == "" {
return mode, fmt.Errorf("authenticator mode 'decs3o' specified but no OAuth2 URL provided")
}
if d.appId == "" {
return mode, fmt.Errorf("authenticator mode 'decs3o' specified but no Application ID provided")
}
if d.appSecret == "" {
return mode, fmt.Errorf("authenticator mode 'decs3o' specified but no Secret ID provided")
}
mode = MODE_DECS3O
case "legacy":
if d.user == "" {
return mode, fmt.Errorf("authenticator mode 'legacy' specified but no user provided")
}
if d.password == "" {
return mode, fmt.Errorf("authenticator mode 'legacy' specified but no password provided")
}
mode = MODE_LEGACY
case "bvs":
if d.bvsUser == "" {
return mode, fmt.Errorf("authenticator mode 'bvs' specified but no bvs user provided")
}
if d.bvsPassword == "" {
return mode, fmt.Errorf("authenticator mode 'bvs' specified but no bvs password provided")
}
if d.oauth2Url == "" {
return mode, fmt.Errorf("authenticator mode 'bvs' specified but no bvs URL provided")
}
if d.appId == "" {
return mode, fmt.Errorf("authenticator mode 'bvs' specified but no Application ID provided")
}
if d.appSecret == "" {
return mode, fmt.Errorf("authenticator mode 'bvs' specified but no Secret ID provided")
}
if d.domain == "" {
return mode, fmt.Errorf("authenticator mode 'bvs' specified but no Domain provided")
}
mode = MODE_BVS
default:
return mode, fmt.Errorf("unknown authenticator mode %q provided", d.authenticator)
}
return mode, nil
}

View File

@@ -0,0 +1,40 @@
package provider
import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/account"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/bservice"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/disks"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/flipgroup"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/image"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/k8s"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/kvmvm"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/lb"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/rg"
"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/service/cloudapi/vins"
)
func newResourcesMap() []func() resource.Resource {
return []func() resource.Resource{
account.NewResourceAccount,
image.NewResourceImage,
image.NewResourceImageVirtual,
disks.NewResourceDisk,
disks.NewResourceDiskSnapshot,
disks.NewResourceDiskReplications,
flipgroup.NewResourceFlipgroup,
k8s.NewResourceK8SCP,
k8s.NewResourceK8SWG,
kvmvm.NewResourceCompute,
lb.NewResourceLB,
lb.NewResourceLBBackend,
lb.NewResourceLBBackendServer,
lb.NewResourceLBFrontend,
lb.NewResourceLBFrontendBind,
rg.NewResourceRG,
vins.NewResourceVINS,
vins.NewResourceVINSStaticRoute,
bservice.NewResourceBService,
bservice.NewResourceBServiceGroup,
}
}