Merge pull request #5657 from yousong/automated-cherry-pick-of-#5652-upstream-release-3.1

Automated cherry pick of #5652: proxysetting: forbid deletion of DIRECT setting
This commit is contained in:
Zexi Li
2020-04-02 12:44:05 +08:00
committed by GitHub
5 changed files with 153 additions and 7 deletions
+3 -7
View File
@@ -13,20 +13,16 @@ const (
type ProxySettingCreateInput struct {
apis.StandaloneResourceCreateInput
HttpProxy string
HttpsProxy string
NoProxy string
ProxySetting
}
type ProxySettingUpdateInput struct {
HttpProxy string
HttpsProxy string
NoProxy string
// 资源名称
Name string `json:"name"`
// 资源描述
Description string `json:"description"`
ProxySetting
}
// String implements ISerializable interface
+111
View File
@@ -0,0 +1,111 @@
package proxy
import (
"fmt"
"net"
"net/url"
"strings"
"yunion.io/x/pkg/errors"
)
type ProxySetting struct {
HttpProxy string
HttpsProxy string
NoProxy string
}
func (v *ProxySetting) Sanitize() error {
v.HttpProxy = strings.TrimSpace(v.HttpProxy)
if u, err := parseProxy(v.HttpProxy); err != nil {
return errors.Wrap(err, "invalid https_proxy url")
} else {
v.HttpProxy = u.String()
}
v.HttpsProxy = strings.TrimSpace(v.HttpsProxy)
if u, err := parseProxy(v.HttpsProxy); err != nil {
return errors.Wrap(err, "invalid http_proxy url")
} else {
v.HttpsProxy = u.String()
}
if noProxy, err := parseNoProxy(v.NoProxy); err == nil {
v.NoProxy = strings.Join(noProxy, ",")
} else {
return errors.Wrap(err, "invalid no_proxy")
}
return nil
}
func parseProxy(proxy string) (*url.URL, error) {
if proxy == "" {
return nil, nil
}
proxyURL, err := url.Parse(proxy)
if err != nil ||
(proxyURL.Scheme != "http" &&
proxyURL.Scheme != "https" &&
proxyURL.Scheme != "socks5") {
// proxy was bogus. Try prepending "http://" to it and
// see if that parses correctly. If not, we fall
// through and complain about the original one.
if proxyURL, err := url.Parse("http://" + proxy); err == nil {
return proxyURL, nil
}
}
if err != nil {
return nil, errors.Wrapf(err, "invalid proxy address %q", proxy)
}
return proxyURL, nil
}
func parseNoProxy(noProxy string) ([]string, error) {
var r []string
for _, p := range strings.Split(noProxy, ",") {
p = strings.ToLower(strings.TrimSpace(p))
if len(p) == 0 {
continue
}
if p == "*" {
r = append(r, p)
// let it go
//return r, nil
}
// IPv4/CIDR, IPv6/CIDR
if _, _, err := net.ParseCIDR(p); err == nil {
r = append(r, p)
continue
}
// IPv4:port, [IPv6]:port
phost, _, err := net.SplitHostPort(p)
if err == nil {
if len(phost) == 0 {
// There is no host part, likely the entry is malformed; ignore.
return nil, fmt.Errorf("host part must not be empty: %s", p)
}
if phost[0] == '[' && phost[len(phost)-1] == ']' {
phost = phost[1 : len(phost)-1]
}
} else {
phost = p
}
// IPv4, IPv6
if pip := net.ParseIP(phost); pip != nil {
r = append(r, p)
continue
}
if len(phost) == 0 {
// There is no host part, likely the entry is malformed; ignore.
continue
}
r = append(r, p)
}
return r, nil
}
+3
View File
@@ -19,6 +19,7 @@ import (
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/apis"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
)
@@ -180,4 +181,6 @@ type CloudaccountDetail struct {
// 存储缓存数量
// example: 10
StoragecacheCount int `json:"storagecache_count,allowempty"`
ProxySetting proxyapi.SProxySetting `json:"proxy_setting"`
}
+9
View File
@@ -46,6 +46,9 @@ type SProxySetting struct {
}
func (man *SProxySettingManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data proxyapi.ProxySettingCreateInput) (proxyapi.ProxySettingCreateInput, error) {
if err := data.ProxySetting.Sanitize(); err != nil {
return data, httperrors.NewInputParameterError("%s", err)
}
return data, nil
}
@@ -58,6 +61,9 @@ func (ps *SProxySetting) ValidateUpdateData(ctx context.Context, userCred mcclie
if ps.Id == proxyapi.ProxySettingId_DIRECT {
return data, httperrors.NewConflictError("DIRECT setting cannot be changed")
}
if err := data.ProxySetting.Sanitize(); err != nil {
return data, httperrors.NewInputParameterError("%s", err)
}
return data, nil
}
@@ -74,6 +80,9 @@ func (ps *SProxySetting) HttpTransportProxyFunc() httputils.TransportProxyFunc {
}
func (ps *SProxySetting) ValidateDeleteCondition(ctx context.Context) error {
if ps.Id == proxyapi.ProxySettingId_DIRECT {
return httperrors.NewConflictError("DIRECT setting cannot be deleted")
}
for _, man := range referrersMen {
t := man.TableSpec().Instance()
n, err := t.Query().
+27
View File
@@ -1714,6 +1714,33 @@ func (manager *SCloudaccountManager) FetchCustomizeColumns(ctx context.Context,
}
}
}
proxySettings := make(map[string]proxy.SProxySetting)
{
proxySettingIds := make([]string, len(objs))
for i := range objs {
proxySettingId := objs[i].(*SCloudaccount).ProxySettingId
if !utils.IsInStringArray(proxySettingId, proxySettingIds) {
proxySettingIds = append(proxySettingIds, proxySettingId)
}
}
q := proxy.ProxySettingManager.Query().In("id", proxySettingIds)
r := []proxy.SProxySetting{}
if err := db.FetchModelObjects(proxy.ProxySettingManager, q, &r); err != nil {
log.Errorf("FetchModelObjects (%s) fail %s",
proxy.ProxySettingManager.KeywordPlural(), err)
return rows
}
for i := range r {
proxySetting := r[i]
proxySettings[proxySetting.Id] = proxySetting
}
}
for i := range rows {
account := objs[i].(*SCloudaccount)
if proxySetting, ok := proxySettings[account.ProxySettingId]; ok {
rows[i].Set("proxy_setting", jsonutils.Marshal(proxySetting))
}
}
return rows
}