mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-29 17:58:36 +08:00
@@ -0,0 +1,53 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package compute
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
|
||||
const (
|
||||
APP_TYPE_WEB = "web"
|
||||
|
||||
APP_STATUS_READY = "ready"
|
||||
APP_STATUS_UNKNOWN = "unknown"
|
||||
)
|
||||
|
||||
type AppListInput struct {
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
apis.EnabledResourceBaseListInput
|
||||
|
||||
ManagedResourceListInput
|
||||
RegionalFilterListInput
|
||||
|
||||
TechStack string `json:"tech_stack"`
|
||||
}
|
||||
|
||||
type AppDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
ManagedResourceInfo
|
||||
CloudregionResourceInfo
|
||||
}
|
||||
|
||||
type AppEnvironmentListInput struct {
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
|
||||
AppId string
|
||||
InstanceType string
|
||||
}
|
||||
|
||||
type AppEnvironmentDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
}
|
||||
@@ -60,6 +60,7 @@ const (
|
||||
CLOUD_CAPABILITY_MONGO_DB = "mongodb" // MongoDB
|
||||
CLOUD_CAPABILITY_ES = "es" // ElasticSearch
|
||||
CLOUD_CAPABILITY_KAFKA = "kafka" // Kafka
|
||||
CLOUD_CAPABILITY_APP = "app" //App
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -183,6 +183,9 @@ type ICloudRegion interface {
|
||||
|
||||
GetICloudKafkas() ([]ICloudKafka, error)
|
||||
GetICloudKafkaById(id string) (ICloudKafka, error)
|
||||
|
||||
GetICloudApps() ([]ICloudApp, error)
|
||||
GetICloudAppById(id string) (ICloudApp, error)
|
||||
}
|
||||
|
||||
type ICloudZone interface {
|
||||
@@ -1443,3 +1446,18 @@ type ICloudKafka interface {
|
||||
|
||||
Delete() error
|
||||
}
|
||||
|
||||
type ICloudApp interface {
|
||||
IVirtualResource
|
||||
GetEnvironments() ([]ICloudAppEnvironment, error)
|
||||
GetTechStack() string
|
||||
GetType() string
|
||||
GetKind() string
|
||||
GetOsType() string
|
||||
}
|
||||
|
||||
type ICloudAppEnvironment interface {
|
||||
IVirtualResource
|
||||
GetInstanceType() (string, error)
|
||||
GetInstanceNumber() (int, error)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,407 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
type SAppManager struct {
|
||||
db.SVirtualResourceBaseManager
|
||||
db.SExternalizedResourceBaseManager
|
||||
db.SEnabledResourceBaseManager
|
||||
|
||||
SManagedResourceBaseManager
|
||||
SCloudregionResourceBaseManager
|
||||
}
|
||||
|
||||
type SApp struct {
|
||||
db.SVirtualResourceBase
|
||||
db.SExternalizedResourceBase
|
||||
db.SEnabledResourceBase
|
||||
|
||||
SManagedResourceBase
|
||||
SCloudregionResourceBase
|
||||
|
||||
Type string `width:"16" charset:"ascii" nullable:"false" get:"user" list:"user"`
|
||||
TechStack string `width:"64" charset:"ascii" nullable:"false" get:"user" list:"user"`
|
||||
Kind string `width:"64" charset:"ascii" nullable:"false" get:"user" list:"user"`
|
||||
}
|
||||
|
||||
var AppManager *SAppManager
|
||||
|
||||
func init() {
|
||||
AppManager = &SAppManager{
|
||||
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
|
||||
SApp{},
|
||||
"apps_tbl",
|
||||
"webapp",
|
||||
"webapps",
|
||||
),
|
||||
}
|
||||
AppManager.SetVirtualObject(AppManager)
|
||||
}
|
||||
|
||||
func (am *SAppManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (am *SAppManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.AppListInput) (*sqlchemy.SQuery, error) {
|
||||
q, err := am.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = am.SEnabledResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SEnabledResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = am.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = am.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = am.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if query.TechStack != "" {
|
||||
q = q.Equals("tech_stack", query.TechStack)
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.AppListInput) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = am.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = am.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = am.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CloudregionResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = am.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = am.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = am.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
switch field {
|
||||
case "tech_stack":
|
||||
q = am.Query("tech_stack").Distinct()
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = am.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
if keys.ContainsAny(am.SManagedResourceBaseManager.GetExportKeys()...) {
|
||||
q, err = am.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
}
|
||||
|
||||
if keys.ContainsAny(am.SCloudregionResourceBaseManager.GetExportKeys()...) {
|
||||
q, err = am.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, isList bool) (api.AppDetails, error) {
|
||||
return api.AppDetails{}, nil
|
||||
}
|
||||
|
||||
func (a *SApp) GetAppEnvironments() ([]SAppEnvironment, error) {
|
||||
q := AppEnvironmentManager.Query().Equals("app_id", a.Id)
|
||||
ret := []SAppEnvironment{}
|
||||
err := db.FetchModelObjects(AppEnvironmentManager, q, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) GetApps(providerId string) ([]SApp, error) {
|
||||
q := AppManager.Query().Equals("manager_id", providerId)
|
||||
ret := []SApp{}
|
||||
err := db.FetchModelObjects(AppManager, q, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SCloudregion) GetApps(managerId string) ([]SApp, error) {
|
||||
q := AppManager.Query().Equals("cloudregion_id", self.Id)
|
||||
if len(managerId) > 0 {
|
||||
q = q.Equals("manager_id", managerId)
|
||||
}
|
||||
ret := []SApp{}
|
||||
err := db.FetchModelObjects(AppManager, q, &ret)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SCloudregion) SyncApps(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudApp) compare.SyncResult {
|
||||
lockman.LockRawObject(ctx, AppManager.KeywordPlural(), fmt.Sprintf("%s-%s", provider.Id, self.Id))
|
||||
defer lockman.ReleaseRawObject(ctx, AppManager.KeywordPlural(), fmt.Sprintf("%s-%s", provider.Id, self.Id))
|
||||
result := compare.SyncResult{}
|
||||
apps, err := self.GetApps(provider.Id)
|
||||
if err != nil {
|
||||
result.Error(err)
|
||||
return result
|
||||
}
|
||||
|
||||
removed := make([]SApp, 0)
|
||||
commondb := make([]SApp, 0)
|
||||
commonext := make([]cloudprovider.ICloudApp, 0)
|
||||
added := make([]cloudprovider.ICloudApp, 0)
|
||||
// compare
|
||||
err = compare.CompareSets(apps, exts, &removed, &commondb, &commonext, &added)
|
||||
if err != nil {
|
||||
result.Error(err)
|
||||
return result
|
||||
}
|
||||
|
||||
// remove
|
||||
for i := 0; i < len(removed); i++ {
|
||||
err := removed[i].syncRemoveCloudApp(ctx, userCred)
|
||||
if err != nil {
|
||||
result.DeleteError(err)
|
||||
continue
|
||||
}
|
||||
result.Delete()
|
||||
}
|
||||
|
||||
// sync with cloud app
|
||||
for i := 0; i < len(commondb); i++ {
|
||||
err := commondb[i].SyncWithCloudApp(ctx, userCred, provider, commonext[i])
|
||||
if err != nil {
|
||||
result.UpdateError(err)
|
||||
continue
|
||||
}
|
||||
result.Update()
|
||||
}
|
||||
|
||||
// new one
|
||||
for i := 0; i < len(added); i++ {
|
||||
_, err := self.newFromCloudApp(ctx, userCred, provider, added[i])
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
continue
|
||||
}
|
||||
result.Add()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (self *SCloudregion) newFromCloudApp(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudApp) (*SApp, error) {
|
||||
app := SApp{}
|
||||
app.SetModelManager(AppManager, &app)
|
||||
|
||||
app.ExternalId = ext.GetGlobalId()
|
||||
app.CloudregionId = self.Id
|
||||
app.ManagerId = provider.Id
|
||||
app.IsEmulated = ext.IsEmulated()
|
||||
app.Status = ext.GetStatus()
|
||||
app.Type = ext.GetType()
|
||||
app.Kind = ext.GetKind()
|
||||
app.TechStack = ext.GetTechStack()
|
||||
app.Name = ext.GetName()
|
||||
app.Enabled = tristate.True
|
||||
|
||||
err := AppManager.TableSpec().Insert(ctx, &app)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to insert app")
|
||||
}
|
||||
aes, err := ext.GetEnvironments()
|
||||
if err != nil {
|
||||
return &app, errors.Wrap(err, "unable to GetEnvironments")
|
||||
}
|
||||
result := app.SyncAppEnvironments(ctx, userCred, provider, aes)
|
||||
if result.IsError() {
|
||||
return &app, errors.Wrap(result.AllError(), "unable to SyncAppEnvironments")
|
||||
}
|
||||
SyncCloudProject(userCred, &app, provider.GetOwnerId(), ext, provider.Id)
|
||||
|
||||
db.OpsLog.LogEvent(&app, db.ACT_CREATE, app.GetShortDesc(ctx), userCred)
|
||||
|
||||
return &app, nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) purgeAll(ctx context.Context, userCred mcclient.TokenCredential, providerId string) error {
|
||||
apps, err := am.GetApps(providerId)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to GetApps of provider id %s", providerId)
|
||||
}
|
||||
for i := range apps {
|
||||
err = apps[i].purge(ctx, userCred)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *SApp) purge(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
aes, err := a.GetAppEnvironments()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to GetAppEnvironments")
|
||||
}
|
||||
for i := range aes {
|
||||
err = aes[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to Delete AppEnvironment %s", aes[i].Id)
|
||||
}
|
||||
}
|
||||
return a.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (a *SApp) syncRemoveCloudApp(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return a.purge(ctx, userCred)
|
||||
}
|
||||
|
||||
func (a *SApp) SyncWithCloudApp(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudApp) error {
|
||||
_, err := db.UpdateWithLock(ctx, a, func() error {
|
||||
a.ExternalId = ext.GetGlobalId()
|
||||
a.Status = ext.GetStatus()
|
||||
a.Type = ext.GetType()
|
||||
a.Kind = ext.GetKind()
|
||||
a.TechStack = ext.GetTechStack()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.Update")
|
||||
}
|
||||
aes, err := ext.GetEnvironments()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to GetAppEnvironments for ICloudApp %s", ext.GetGlobalId())
|
||||
}
|
||||
result := a.SyncAppEnvironments(ctx, userCred, provider, aes)
|
||||
if result.IsError() {
|
||||
return result.AllError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *SAppManager) FetchCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, objs []interface{}, fields stringutils2.SSortedStrings, isList bool) []api.AppDetails {
|
||||
rows := make([]api.AppDetails, len(objs))
|
||||
virtRows := am.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
manRows := am.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
regRows := am.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range rows {
|
||||
rows[i].VirtualResourceDetails = virtRows[i]
|
||||
rows[i].ManagedResourceInfo = manRows[i]
|
||||
rows[i].CloudregionResourceInfo = regRows[i]
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (a *SApp) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return a.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, a, "syncstatus")
|
||||
}
|
||||
|
||||
func (a *SApp) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
var openTask = true
|
||||
count, err := taskman.TaskManager.QueryTasksOfObject(a, time.Now().Add(-3*time.Minute), &openTask).CountWithError()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count > 0 {
|
||||
return nil, httperrors.NewBadRequestError("WebApp has %d task active, can't sync status", count)
|
||||
}
|
||||
|
||||
return nil, StartResourceSyncStatusTask(ctx, userCred, a, "AppSyncstatusTask", "")
|
||||
}
|
||||
|
||||
func (a *SApp) GetRegion() (*SCloudregion, error) {
|
||||
region, err := CloudregionManager.FetchById(a.CloudregionId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CloudregionManager.FetchById(%s)", a.CloudregionId)
|
||||
}
|
||||
return region.(*SCloudregion), nil
|
||||
}
|
||||
|
||||
func (a *SApp) GetIRegion() (cloudprovider.ICloudRegion, error) {
|
||||
region, err := a.GetRegion()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetRegion")
|
||||
}
|
||||
provider, err := a.GetDriver()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetDriver")
|
||||
}
|
||||
return provider.GetIRegionById(region.GetExternalId())
|
||||
}
|
||||
|
||||
func (a *SApp) GetIApp() (cloudprovider.ICloudApp, error) {
|
||||
if len(a.ExternalId) == 0 {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty externalId")
|
||||
}
|
||||
iRegion, err := a.GetIRegion()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetIRegion")
|
||||
}
|
||||
return iRegion.GetICloudAppById(a.ExternalId)
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
type SAppEnvironmentManager struct {
|
||||
db.SVirtualResourceBaseManager
|
||||
db.SExternalizedResourceBaseManager
|
||||
}
|
||||
|
||||
type SAppEnvironment struct {
|
||||
db.SVirtualResourceBase
|
||||
db.SExternalizedResourceBase
|
||||
|
||||
AppId string `width:"36" charset:"ascii" index:"true"`
|
||||
InstanceType string `width:"16" charset:"ascii" index:"true" get:"user" list:"user"`
|
||||
InstanceNumber int `get:"user" list:"user"`
|
||||
}
|
||||
|
||||
var AppEnvironmentManager *SAppEnvironmentManager
|
||||
|
||||
func init() {
|
||||
AppEnvironmentManager = &SAppEnvironmentManager{
|
||||
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
|
||||
SAppEnvironment{},
|
||||
"appenvironments_tbl",
|
||||
"webappenvironment",
|
||||
"webappenvironments",
|
||||
),
|
||||
}
|
||||
AppEnvironmentManager.SetVirtualObject(AppEnvironmentManager)
|
||||
}
|
||||
|
||||
func (aem *SAppEnvironmentManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, input api.AppEnvironmentListInput) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = aem.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, input.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = aem.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, input.ExternalizedResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if input.AppId != "" {
|
||||
q = q.Equals("app_id", input.AppId)
|
||||
}
|
||||
if input.InstanceType != "" {
|
||||
q = q.Equals("instance_type", input.InstanceType)
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (aem *SAppEnvironmentManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.AppEnvironmentListInput) (*sqlchemy.SQuery, error) {
|
||||
return aem.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
}
|
||||
|
||||
func (aem *SAppEnvironmentManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
q, err = aem.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (aem *SAppEnvironmentManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
q, err := aem.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
switch field {
|
||||
case "instance_type":
|
||||
q = aem.Query("instance_type").Distinct()
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (a *SApp) SyncAppEnvironments(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudAppEnvironment) compare.SyncResult {
|
||||
lockman.LockRawObject(ctx, AppEnvironmentManager.KeywordPlural(), a.Id)
|
||||
defer lockman.LockRawObject(ctx, AppEnvironmentManager.KeywordPlural(), a.Id)
|
||||
result := compare.SyncResult{}
|
||||
aes, err := a.GetAppEnvironments()
|
||||
if err != nil {
|
||||
result.Error(err)
|
||||
return result
|
||||
}
|
||||
|
||||
removed := make([]SAppEnvironment, 0)
|
||||
commondb := make([]SAppEnvironment, 0)
|
||||
commonext := make([]cloudprovider.ICloudAppEnvironment, 0)
|
||||
added := make([]cloudprovider.ICloudAppEnvironment, 0)
|
||||
// compare
|
||||
err = compare.CompareSets(aes, exts, &removed, &commondb, &commonext, &added)
|
||||
if err != nil {
|
||||
result.Error(err)
|
||||
return result
|
||||
}
|
||||
|
||||
// remove
|
||||
for i := 0; i < len(removed); i++ {
|
||||
err := removed[i].syncRemoveCloudAppEnvironment(ctx, userCred)
|
||||
if err != nil {
|
||||
result.DeleteError(err)
|
||||
continue
|
||||
}
|
||||
result.Delete()
|
||||
}
|
||||
|
||||
// sync with cloud
|
||||
for i := 0; i < len(commondb); i++ {
|
||||
err := commondb[i].SyncWithCloudAppEnvironment(ctx, userCred, commonext[i])
|
||||
if err != nil {
|
||||
result.UpdateError(err)
|
||||
continue
|
||||
}
|
||||
result.Update()
|
||||
}
|
||||
|
||||
// new one
|
||||
for i := 0; i < len(added); i++ {
|
||||
_, err := a.newFromCloudAppEnvironment(ctx, userCred, provider, added[i])
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
continue
|
||||
}
|
||||
result.Add()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (a *SApp) newFromCloudAppEnvironment(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudAppEnvironment) (*SAppEnvironment, error) {
|
||||
var err error
|
||||
appEnvironment := SAppEnvironment{}
|
||||
appEnvironment.SetModelManager(AppEnvironmentManager, &appEnvironment)
|
||||
|
||||
appEnvironment.ExternalId = ext.GetGlobalId()
|
||||
appEnvironment.IsEmulated = ext.IsEmulated()
|
||||
appEnvironment.Status = ext.GetStatus()
|
||||
appEnvironment.InstanceType, err = ext.GetInstanceType()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to GetInsntaceType")
|
||||
}
|
||||
|
||||
appEnvironment.InstanceNumber, err = ext.GetInstanceNumber()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to GetInstanceNumber")
|
||||
}
|
||||
|
||||
appEnvironment.Name = ext.GetName()
|
||||
appEnvironment.AppId = a.Id
|
||||
err = AppEnvironmentManager.TableSpec().Insert(ctx, &appEnvironment)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudAppEnvironment.Insert")
|
||||
}
|
||||
|
||||
SyncCloudProject(userCred, &appEnvironment, provider.GetOwnerId(), ext, provider.Id)
|
||||
db.OpsLog.LogEvent(&appEnvironment, db.ACT_CREATE, appEnvironment.GetShortDesc(ctx), userCred)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (ae *SAppEnvironment) syncRemoveCloudAppEnvironment(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return ae.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (ae *SAppEnvironment) SyncWithCloudAppEnvironment(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudAppEnvironment) error {
|
||||
_, err := db.UpdateWithLock(ctx, ae, func() error {
|
||||
var err error
|
||||
ae.ExternalId = ext.GetGlobalId()
|
||||
ae.Status = ext.GetStatus()
|
||||
ae.InstanceType, err = ext.GetInstanceType()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ae.InstanceNumber, err = ext.GetInstanceNumber()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "db.Update")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aem *SAppEnvironmentManager) FetchCustomizeColumns(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, objs []interface{}, fields stringutils2.SSortedStrings, isList bool) []api.AppEnvironmentDetails {
|
||||
rows := make([]api.AppEnvironmentDetails, len(objs))
|
||||
virRows := aem.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range rows {
|
||||
rows[i].VirtualResourceDetails = virRows[i]
|
||||
}
|
||||
return rows
|
||||
}
|
||||
@@ -1484,6 +1484,7 @@ func (self *SCloudprovider) RealDelete(ctx context.Context, userCred mcclient.To
|
||||
WafIPSetCacheManager,
|
||||
WafRegexSetCacheManager,
|
||||
WafInstanceManager,
|
||||
AppManager,
|
||||
VpcManager,
|
||||
ElasticipManager,
|
||||
MongoDBManager,
|
||||
|
||||
@@ -1170,6 +1170,24 @@ func syncKafkas(ctx context.Context, userCred mcclient.TokenCredential, syncResu
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncApps(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
|
||||
log.Infof("try to syncApps")
|
||||
iApps, err := remoteRegion.GetICloudApps()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetICloudApps for region %s failed %s", remoteRegion.GetName(), err)
|
||||
log.Errorf(msg)
|
||||
return err
|
||||
}
|
||||
result := localRegion.SyncApps(ctx, userCred, provider, iApps)
|
||||
syncResults.Add(AppManager, result)
|
||||
msg := result.Result()
|
||||
log.Infof("SyncApps for region %s result: %s", localRegion.Name, msg)
|
||||
if result.IsError() {
|
||||
return result.AllError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syncWafInstances(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
|
||||
wafIns, err := remoteRegion.GetICloudWafInstances()
|
||||
if err != nil {
|
||||
@@ -1416,6 +1434,10 @@ func syncPublicCloudProviderInfo(
|
||||
syncKafkas(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
|
||||
}
|
||||
|
||||
if utils.IsInStringArray(cloudprovider.CLOUD_CAPABILITY_APP, driver.GetCapabilities()) {
|
||||
syncApps(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
|
||||
}
|
||||
|
||||
if cloudprovider.IsSupportCompute(driver) {
|
||||
log.Debugf("storageCachePairs count %d", len(storageCachePairs))
|
||||
for i := range storageCachePairs {
|
||||
|
||||
@@ -231,6 +231,9 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.ElasticSearchManager,
|
||||
|
||||
models.KafkaManager,
|
||||
|
||||
models.AppManager,
|
||||
models.AppEnvironmentManager,
|
||||
} {
|
||||
db.RegisterModelManager(manager)
|
||||
handler := db.NewModelHandler(manager)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/compute/models"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
)
|
||||
|
||||
type AppSyncstatusTask struct {
|
||||
taskman.STask
|
||||
}
|
||||
|
||||
func init() {
|
||||
taskman.RegisterTask(AppSyncstatusTask{})
|
||||
}
|
||||
|
||||
func (at *AppSyncstatusTask) taskFailed(ctx context.Context, app *models.SApp, err error) {
|
||||
app.SetStatus(at.UserCred, api.APP_STATUS_UNKNOWN, err.Error())
|
||||
db.OpsLog.LogEvent(app, db.ACT_SYNC_STATUS, err, at.GetUserCred())
|
||||
logclient.AddActionLogWithStartable(at, app, logclient.ACT_SYNC_STATUS, err, at.UserCred, false)
|
||||
at.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
|
||||
}
|
||||
|
||||
func (at *AppSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
app := obj.(*models.SApp)
|
||||
|
||||
iApp, err := app.GetIApp()
|
||||
if err != nil {
|
||||
at.taskFailed(ctx, app, errors.Wrapf(err, "app.GetIApp"))
|
||||
return
|
||||
}
|
||||
app.SyncWithCloudApp(ctx, at.UserCred, app.GetCloudprovider(), iApp)
|
||||
at.SetStageComplete(ctx, nil)
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package modules
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
|
||||
type AppManager struct {
|
||||
modulebase.ResourceManager
|
||||
}
|
||||
|
||||
type AppEnvironmentManager struct {
|
||||
modulebase.ResourceManager
|
||||
}
|
||||
|
||||
var (
|
||||
Apps AppManager
|
||||
AppEnvironments AppEnvironmentManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
Apps = AppManager{NewComputeManager("webapp", "webapps",
|
||||
[]string{},
|
||||
[]string{},
|
||||
)}
|
||||
AppEnvironments = AppEnvironmentManager{NewComputeManager("webappenvironment", "webappenvironments",
|
||||
[]string{},
|
||||
[]string{},
|
||||
)}
|
||||
registerCompute(&Apps)
|
||||
registerCompute(&AppEnvironments)
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
)
|
||||
|
||||
type AppListOptions struct {
|
||||
options.BaseListOptions
|
||||
TechStack string
|
||||
}
|
||||
|
||||
func (opts *AppListOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return options.ListStructToParams(opts)
|
||||
}
|
||||
|
||||
type AppIdOptions struct {
|
||||
ID string `help:"App Id"`
|
||||
}
|
||||
|
||||
func (opts *AppIdOptions) GetId() string {
|
||||
return opts.ID
|
||||
}
|
||||
|
||||
func (opts *AppIdOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type AppEnvironmentListOptions struct {
|
||||
options.BaseListOptions
|
||||
AppId string `help:"App Id"`
|
||||
InstanceType string `help:"Instance Type"`
|
||||
}
|
||||
|
||||
func (opts *AppEnvironmentListOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return options.ListStructToParams(opts)
|
||||
}
|
||||
|
||||
type AppEnvironmentIdOption struct {
|
||||
ID string `help:"AppEnvironment ID"`
|
||||
}
|
||||
|
||||
func (opts *AppEnvironmentIdOption) GetId() string {
|
||||
return opts.ID
|
||||
}
|
||||
|
||||
func (opts *AppEnvironmentIdOption) Params() (jsonutils.JSONObject, error) {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SAppServicePlan struct {
|
||||
multicloud.AzureTags
|
||||
region *SRegion
|
||||
|
||||
Properties SAppServicePlanProperties
|
||||
ID string
|
||||
Kind string
|
||||
Location string
|
||||
Name string
|
||||
Type string
|
||||
Sku SSkuDescription
|
||||
}
|
||||
|
||||
type SAppServicePlanProperties struct {
|
||||
FreeOfferExpirationTime string
|
||||
GeoRegion string
|
||||
HostingEnvironmentProfile SHostingEnvironmentProfile
|
||||
HyperV bool
|
||||
IsSpot bool
|
||||
MaximumElasticWorkerCount int
|
||||
MaximumNumberOfWorkers int
|
||||
NumberOfSites int
|
||||
PerSiteScaling bool
|
||||
// 应用服务环境的预配状态
|
||||
ProvisioningState string
|
||||
Reserved bool
|
||||
ResourceGroup string
|
||||
SpotExpirationTime string
|
||||
// Creating Pending Ready
|
||||
Status string
|
||||
Subscription string
|
||||
TargetWorkerCount int
|
||||
TargetWorkerSizeId int
|
||||
WorkerTierName string
|
||||
}
|
||||
|
||||
type SHostingEnvironmentProfile struct {
|
||||
ID string
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type SSkuDescription struct {
|
||||
Capabilities []SCapability
|
||||
Capacity int
|
||||
Family string
|
||||
locations []string
|
||||
Name string
|
||||
Size string
|
||||
SkuCapacity SSkuCapacity
|
||||
Tier string
|
||||
}
|
||||
|
||||
type SCapability struct {
|
||||
Name string
|
||||
Reason string
|
||||
Value string
|
||||
}
|
||||
|
||||
type SSkuCapacity struct {
|
||||
Default int
|
||||
Maximum int
|
||||
Minimum int
|
||||
ScaleType string
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAppServicePlanWithCache(id string) (*SAppServicePlan, error) {
|
||||
if r.appServicePlans == nil {
|
||||
plans, err := r.GetAppServicePlans()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
appServicePlans := make(map[string]*SAppServicePlan, len(plans))
|
||||
for i := range plans {
|
||||
appServicePlans[plans[i].ID] = &plans[i]
|
||||
}
|
||||
r.appServicePlans = appServicePlans
|
||||
}
|
||||
if ret, ok := r.appServicePlans[id]; ok {
|
||||
return ret, nil
|
||||
}
|
||||
return r.GetAppServicePlan(id)
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAppServicePlans() ([]SAppServicePlan, error) {
|
||||
result := []SAppServicePlan{}
|
||||
resource := "Microsoft.Web/serverfarms"
|
||||
err := r.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range result {
|
||||
result[i].region = r
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAppServicePlan(planId string) (*SAppServicePlan, error) {
|
||||
asp := &SAppServicePlan{region: r}
|
||||
params := url.Values{"api-version": []string{"2019-08-01"}}
|
||||
return asp, r.get(planId, params, asp)
|
||||
}
|
||||
|
||||
type SServerFarmSku struct {
|
||||
ResourceType string
|
||||
Sku SSkuSpec
|
||||
Capacity SSkuCapacity
|
||||
}
|
||||
|
||||
type SSkuSpec struct {
|
||||
Name string
|
||||
Tier string
|
||||
}
|
||||
|
||||
func (asp *SAppServicePlan) GetSkus() ([]SServerFarmSku, error) {
|
||||
result := []SServerFarmSku{}
|
||||
resource := fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/serverfarms/%s/skus", asp.region.client._subscriptionId(), asp.Properties.ResourceGroup, asp.Name)
|
||||
err := asp.region.client.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type SAppServicePlanVnet struct {
|
||||
Id string
|
||||
Name string
|
||||
Properties SASPVnetProperties
|
||||
}
|
||||
|
||||
type SASPVnetProperties struct {
|
||||
VnetResourceId string
|
||||
}
|
||||
|
||||
func (asp *SAppServicePlan) GetNetworks() ([]SNetwork, error) {
|
||||
vnets, err := asp.GetVnets()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get Vnets")
|
||||
}
|
||||
networks := make([]SNetwork, 0, len(vnets))
|
||||
for i := range vnets {
|
||||
network, err := asp.region.GetNetwork(vnets[i].Properties.VnetResourceId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get Network")
|
||||
}
|
||||
networks = append(networks, *network)
|
||||
}
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
func (asp *SAppServicePlan) GetVnets() ([]SAppServicePlanVnet, error) {
|
||||
result := []SAppServicePlanVnet{}
|
||||
resource := fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/serverfarms/%s/virtualNetworkConnections", asp.region.client._subscriptionId(), asp.Properties.ResourceGroup, asp.Name)
|
||||
err := asp.region.client.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type SSkuInfos struct {
|
||||
ResourceType string
|
||||
Skus []SResourceSku
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAppServiceSkus() ([]SSkuInfos, error) {
|
||||
result := []SSkuInfos{}
|
||||
resource := "Microsoft.Web/skus"
|
||||
err := r.client.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azure
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SAutoscaleSettingResource struct {
|
||||
multicloud.AzureTags
|
||||
region *SRegion
|
||||
|
||||
Properties SAutoscaleSettingProperties
|
||||
ID string
|
||||
Location string
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type SAutoscaleSettingProperties struct {
|
||||
Enabled bool
|
||||
Name string
|
||||
TargetResourceUri string
|
||||
Profiles []SAutoscaleProfile
|
||||
}
|
||||
|
||||
type SAutoscaleProfile struct {
|
||||
Capacity SScaleCapacity
|
||||
FixedDate STimeWindow
|
||||
Name string
|
||||
Recurrence SRecurrence
|
||||
Rule []SScaleRule
|
||||
}
|
||||
|
||||
type SRecurrence struct {
|
||||
Frequency string
|
||||
Schedule SRecurrentSchedule
|
||||
}
|
||||
|
||||
type SRecurrentSchedule struct {
|
||||
Days []string
|
||||
Hours []int
|
||||
Minutes []int
|
||||
TimeZone string
|
||||
}
|
||||
|
||||
type STimeWindow struct {
|
||||
// 采用 ISO 8601 格式的配置文件的结束时间。
|
||||
End string
|
||||
// 采用 ISO 8601 格式的配置文件的开始时间。
|
||||
Start string
|
||||
TimeZone string
|
||||
}
|
||||
|
||||
type SScaleAction struct {
|
||||
Cooldown string
|
||||
Direction string
|
||||
Type string
|
||||
Value string
|
||||
}
|
||||
|
||||
// 可以在此配置文件期间使用的实例数。
|
||||
type SScaleCapacity struct {
|
||||
Default string
|
||||
Maximum string
|
||||
Minimum string
|
||||
}
|
||||
|
||||
// Decrease string
|
||||
// Increase string
|
||||
// None string
|
||||
|
||||
// 为缩放操作提供触发器和参数的规则。
|
||||
type SScaleRule struct {
|
||||
MetricTrigger SMetricTrigger
|
||||
ScaleAction SScaleAction
|
||||
}
|
||||
|
||||
// 维度运算符。 仅支持"Equals"和"NotEquals"。 "Equals"等于任何值。 "NotEquals"不等于所有值
|
||||
type SScaleRuleMetricDimensionOperationType struct {
|
||||
Equals string
|
||||
NotEquals string
|
||||
}
|
||||
|
||||
//触发缩放规则时应发生的操作类型。
|
||||
// ChangeCount string
|
||||
// ExactCount string
|
||||
// PercentChangeCount string
|
||||
|
||||
type SScaleRuleMetricDimension struct {
|
||||
DimensionName string
|
||||
Operator string
|
||||
Values []string
|
||||
}
|
||||
|
||||
type SMetricTrigger struct {
|
||||
// 维度条件的列表。 例如: [{"DimensionName": "AppName"、"Operator": "Equals"、"Values": ["App1"]}、{"DimensionName": "Deployment"、"Operator": "Equals"、"Values": ["default"]}]。
|
||||
Dimensions []SScaleRuleMetricDimension
|
||||
|
||||
// 一个值,该值指示度量值是否应除以每个实例。
|
||||
DividePerInstance bool
|
||||
|
||||
// 定义规则监视内容的指标的名称。
|
||||
MetricName string
|
||||
|
||||
// 定义规则监视内容的指标的命名空间。
|
||||
MetricNamespace string
|
||||
|
||||
// 规则监视的资源的资源标识符。
|
||||
MetricResourceUri string
|
||||
|
||||
// 用于比较指标数据和阈值的运算符。
|
||||
// Equals GreaterThan GreaterThanOrEqual LessThan LessThanOrEqual NotEquals
|
||||
Operator string
|
||||
|
||||
// 指标统计信息类型。 来自多个实例的指标进行组合的方式。
|
||||
// Average Max Min Sum
|
||||
Statistic string
|
||||
|
||||
// 触发缩放操作的度量值的阈值。
|
||||
Threshold int
|
||||
|
||||
// 时间聚合类型。 随着时间推移,收集的数据应如何组合。 默认值为 Average。
|
||||
// Average Count Last Maximum Minimum Total
|
||||
TimeAggregation string
|
||||
|
||||
//规则监视的度量值的粒度。 必须是从指标的指标定义返回的预定义值之一。 必须介于 12 小时和 1 分钟之间。
|
||||
TimeGrain string
|
||||
|
||||
//收集实例数据的时间范围。 此值必须大于指标集合中的延迟,可能会因资源而异。 必须介于 12 小时和 5 分钟之间。
|
||||
TimeWindow string
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAutoscaleSettingResources() ([]SAutoscaleSettingResource, error) {
|
||||
result := []SAutoscaleSettingResource{}
|
||||
resource := "microsoft.insights/autoscalesettings"
|
||||
err := r.client.list(resource, url.Values{"api-version": []string{"2015-04-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -508,10 +508,14 @@ func (self *SAzureClient) _list(resource string, params url.Values) (jsonutils.J
|
||||
path = fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/%s", subId, params.Get("resourceGroups"), resource)
|
||||
params.Del("resourceGroups")
|
||||
default:
|
||||
if len(subId) == 0 {
|
||||
return nil, fmt.Errorf("no avaiable subscriptions")
|
||||
if strings.HasPrefix(resource, "subscriptions/") || strings.HasPrefix(resource, "/subscriptions/") {
|
||||
path = resource
|
||||
} else {
|
||||
if len(subId) == 0 {
|
||||
return nil, fmt.Errorf("no avaiable subscriptions")
|
||||
}
|
||||
path = fmt.Sprintf("subscriptions/%s/providers/%s", subId, resource)
|
||||
}
|
||||
path = fmt.Sprintf("subscriptions/%s/providers/%s", subId, resource)
|
||||
}
|
||||
params.Set("api-version", self._apiVersion(resource, params))
|
||||
return self.jsonRequest("GET", path, nil, params, true)
|
||||
@@ -976,6 +980,7 @@ func (self *SAzureClient) GetCapabilities() []string {
|
||||
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
|
||||
cloudprovider.CLOUD_CAPABILITY_WAF,
|
||||
cloudprovider.CLOUD_CAPABILITY_CACHE,
|
||||
cloudprovider.CLOUD_CAPABILITY_APP,
|
||||
}
|
||||
return caps
|
||||
}
|
||||
|
||||
@@ -42,7 +42,8 @@ type SRegion struct {
|
||||
multicloud.SRegion
|
||||
client *SAzureClient
|
||||
|
||||
storageCache *SStoragecache
|
||||
storageCache *SStoragecache
|
||||
appServicePlans map[string]*SAppServicePlan
|
||||
|
||||
ID string
|
||||
Name string
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud/azure"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type AppServicePlanListOptions struct {
|
||||
}
|
||||
shellutils.R(&AppServicePlanListOptions{}, "app-service-plan-list", "List app service plan", func(cli *azure.SRegion, args *AppServicePlanListOptions) error {
|
||||
appServicePlans, err := cli.GetAppServicePlans()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("sku: %s\n", jsonutils.Marshal(appServicePlans[0].Sku))
|
||||
printList(appServicePlans, len(appServicePlans), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
type AppServicePlanShowOptions struct {
|
||||
ID string
|
||||
}
|
||||
shellutils.R(&AppServicePlanShowOptions{}, "app-service-plan-show", "Show app service plan", func(cli *azure.SRegion, args *AppServicePlanShowOptions) error {
|
||||
appServicePlan, err := cli.GetAppServicePlan(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(appServicePlan)
|
||||
return nil
|
||||
})
|
||||
shellutils.R(&AppServicePlanListOptions{}, "autoscale-setting-list", "List autoscale setting in app service plan", func(cli *azure.SRegion, args *AppServicePlanListOptions) error {
|
||||
appServicePlans, err := cli.GetAutoscaleSettingResources()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(appServicePlans, len(appServicePlans), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
shellutils.R(&AppServicePlanShowOptions{}, "app-service-sku-list", "List sku usable in app service plan", func(cli *azure.SRegion, args *AppServicePlanShowOptions) error {
|
||||
appServicePlan, err := cli.GetAppServicePlan(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
skus, err := appServicePlan.GetSkus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(skus, len(skus), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
shellutils.R(&AppServicePlanShowOptions{}, "app-service-network-list", "List network connected with app service plan", func(cli *azure.SRegion, args *AppServicePlanShowOptions) error {
|
||||
appServicePlan, err := cli.GetAppServicePlan(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
networks, err := appServicePlan.GetNetworks()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(networks, len(networks), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shell
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/multicloud/azure"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type AppSiteListOptions struct {
|
||||
}
|
||||
shellutils.R(&AppSiteListOptions{}, "app-site-list", "List app service plan", func(cli *azure.SRegion, args *AppSiteListOptions) error {
|
||||
ass, err := cli.GetAppSites()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(ass, len(ass), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
type AppSiteShowOptions struct {
|
||||
ID string
|
||||
}
|
||||
shellutils.R(&AppSiteShowOptions{}, "app-site-show", "Show app service plan", func(cli *azure.SRegion, args *AppSiteShowOptions) error {
|
||||
as, err := cli.GetAppSite(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(as)
|
||||
return nil
|
||||
})
|
||||
shellutils.R(&AppSiteShowOptions{}, "app-site-deployment-list", "List sku usable in app service plan", func(cli *azure.SRegion, args *AppSiteShowOptions) error {
|
||||
as, err := cli.GetAppSite(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deployments, err := as.GetDeployments()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(deployments, len(deployments), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
shellutils.R(&AppSiteShowOptions{}, "app-site-slot-list", "List slots ofr App site", func(cli *azure.SRegion, args *AppSiteShowOptions) error {
|
||||
as, err := cli.GetAppSite(args.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slots, err := as.GetSlots()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(slots, len(slots), 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
|
||||
type SAppSite struct {
|
||||
multicloud.AzureTags
|
||||
region *SRegion
|
||||
appServicePlan *SAppServicePlan
|
||||
|
||||
Properties SAppSiteProperties
|
||||
Id string
|
||||
Name string
|
||||
Kind string
|
||||
Location string
|
||||
Type string
|
||||
|
||||
stack *string
|
||||
}
|
||||
|
||||
type SAppSiteProperties struct {
|
||||
AvailabilityState string
|
||||
DefaultHostName string
|
||||
Enabled bool
|
||||
EnabledHostNames []string
|
||||
HostNameSslStates []SHostNameSslState
|
||||
HostNames []string
|
||||
HttpsOnly bool
|
||||
OutboundIpAddresses string
|
||||
ResourceGroup string
|
||||
ServerFarmId string
|
||||
SiteConfig SSiteConfig
|
||||
State string
|
||||
}
|
||||
|
||||
type SSiteConfig struct {
|
||||
// TODO
|
||||
}
|
||||
|
||||
type SHostNameSslState struct {
|
||||
HostType string
|
||||
Name string
|
||||
SslState string
|
||||
Thumbprint string
|
||||
ToUpdate bool
|
||||
VirtualIP string
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAppSites() ([]SAppSite, error) {
|
||||
result := []SAppSite{}
|
||||
resource := "Microsoft.Web/sites"
|
||||
err := r.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range result {
|
||||
result[i].region = r
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *SRegion) GetICloudApps() ([]cloudprovider.ICloudApp, error) {
|
||||
ass, err := r.GetAppSites()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apps := make([]cloudprovider.ICloudApp, 0, len(ass))
|
||||
for i := range ass {
|
||||
apps = append(apps, &SApp{
|
||||
SAppSite: ass[i],
|
||||
})
|
||||
}
|
||||
return apps, nil
|
||||
}
|
||||
|
||||
func (r *SRegion) GetICloudAppById(id string) (cloudprovider.ICloudApp, error) {
|
||||
as, err := r.GetAppSite(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SApp{
|
||||
SAppSite: *as,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetSlots() ([]SAppSite, error) {
|
||||
result := []SAppSite{}
|
||||
resource := fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/sites/%s/slots", as.region.client.subscriptionId, as.Properties.ResourceGroup, as.Name)
|
||||
err := as.region.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *SRegion) GetAppSite(siteId string) (*SAppSite, error) {
|
||||
as := &SAppSite{region: r}
|
||||
params := url.Values{"api-version": []string{"2019-08-01"}}
|
||||
return as, r.get(siteId, params, as)
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetAppServicePlan() (*SAppServicePlan, error) {
|
||||
if as.appServicePlan != nil {
|
||||
return as.appServicePlan, nil
|
||||
}
|
||||
plan, err := as.region.GetAppServicePlanWithCache(as.Properties.ServerFarmId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unable to get AppServicePlan")
|
||||
}
|
||||
as.appServicePlan = plan
|
||||
return plan, nil
|
||||
}
|
||||
|
||||
type SDeployment struct {
|
||||
ID string
|
||||
Name string
|
||||
Kind string
|
||||
Type string
|
||||
Properties SDeploymentProperties
|
||||
}
|
||||
|
||||
type SDeploymentProperties struct {
|
||||
Active bool
|
||||
Author string
|
||||
AuthorEmail string
|
||||
Deployer string
|
||||
Details string
|
||||
EndTime string
|
||||
Message string
|
||||
StartTime string
|
||||
Status string
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetDeployments() ([]SDeployment, error) {
|
||||
result := []SDeployment{}
|
||||
resource := fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/sites/%s/deployments", as.region.client._subscriptionId(), as.Properties.ResourceGroup, as.Name)
|
||||
err := as.region.client.list(resource, url.Values{"api-version": []string{"2019-08-01"}}, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type SStringDictionary struct {
|
||||
Id string
|
||||
Kind string
|
||||
Name string
|
||||
Type string
|
||||
Properties map[string]string
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetStack() (string, error) {
|
||||
if as.stack != nil {
|
||||
return *as.stack, nil
|
||||
}
|
||||
// result := SStringDictionary{}
|
||||
resource := fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/sites/%s/config/metadata", as.region.client.subscriptionId, as.Properties.ResourceGroup, as.Name)
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("api-version", "2019-08-01")
|
||||
path := resource + "/list"
|
||||
response, err := as.region.client.jsonRequest("POST", path, nil, params, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
stack, err := response.GetString("properties", "CURRENT_STACK")
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "unable to parse response correctly, response: %s", response)
|
||||
}
|
||||
as.stack = &stack
|
||||
return stack, nil
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetId() string {
|
||||
return as.Id
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetName() string {
|
||||
return as.Name
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetGlobalId() string {
|
||||
return strings.ToLower(as.Id)
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetStatus() string {
|
||||
return "ready"
|
||||
}
|
||||
|
||||
func (as *SAppSite) GetProjectId() string {
|
||||
return strings.ToLower(as.Properties.ResourceGroup)
|
||||
}
|
||||
|
||||
type SApp struct {
|
||||
multicloud.SResourceBase
|
||||
multicloud.AzureTags
|
||||
SAppSite
|
||||
}
|
||||
|
||||
type SAppEnvironment struct {
|
||||
multicloud.SResourceBase
|
||||
multicloud.AzureTags
|
||||
SAppSite
|
||||
}
|
||||
|
||||
func (ae *SAppEnvironment) GetInstanceType() (string, error) {
|
||||
asp, err := ae.SAppSite.GetAppServicePlan()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return asp.Sku.Name, nil
|
||||
}
|
||||
|
||||
func (ae *SAppEnvironment) GetInstanceNumber() (int, error) {
|
||||
asp, err := ae.SAppSite.GetAppServicePlan()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return asp.Sku.Capacity, nil
|
||||
}
|
||||
|
||||
func (a *SApp) GetEnvironments() ([]cloudprovider.ICloudAppEnvironment, error) {
|
||||
sites, err := a.SAppSite.GetSlots()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aes := make([]cloudprovider.ICloudAppEnvironment, 0, len(sites)+1)
|
||||
aes = append(aes, &SAppEnvironment{
|
||||
SAppSite: a.SAppSite,
|
||||
})
|
||||
for i := range sites {
|
||||
sites[i].region = a.region
|
||||
aes = append(aes, &SAppEnvironment{
|
||||
SAppSite: sites[i],
|
||||
})
|
||||
}
|
||||
return aes, nil
|
||||
}
|
||||
|
||||
var techStacks = map[string]string{
|
||||
"dotnet": ".NET",
|
||||
"dotnetcore": ".NET Core",
|
||||
"aspdotnet": "ASP.NET",
|
||||
"node": "Node",
|
||||
"python": "Python",
|
||||
"php": "PHP",
|
||||
"ruby": "Ruby",
|
||||
"java": "Java",
|
||||
"javacontainers": "Jave Containers",
|
||||
}
|
||||
|
||||
func (a *SApp) GetTechStack() string {
|
||||
if strings.Contains(a.SAppSite.Kind, "container") {
|
||||
return "Docker container"
|
||||
}
|
||||
stack, err := a.GetStack()
|
||||
if err != nil {
|
||||
log.Errorf("unable to GetStack: %v", err)
|
||||
}
|
||||
if s, ok := techStacks[stack]; ok {
|
||||
return s
|
||||
}
|
||||
return stack
|
||||
}
|
||||
|
||||
func (a *SApp) GetType() string {
|
||||
return "web"
|
||||
}
|
||||
|
||||
func (a *SApp) GetKind() string {
|
||||
return a.Kind
|
||||
}
|
||||
|
||||
func (a *SApp) GetOsType() string {
|
||||
if strings.Contains(a.Kind, "linux") {
|
||||
return "Linux"
|
||||
}
|
||||
return "Windows"
|
||||
}
|
||||
@@ -222,3 +222,11 @@ func (self *SRegion) GetICloudKafkas() ([]cloudprovider.ICloudKafka, error) {
|
||||
func (self *SRegion) GetICloudKafkaById(id string) (cloudprovider.ICloudKafka, error) {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudKafkaById")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetICloudApps() ([]cloudprovider.ICloudApp, error) {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudApps")
|
||||
}
|
||||
|
||||
func (self *SRegion) GetICloudAppById(id string) (cloudprovider.ICloudApp, error) {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudAppById")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user