add validation for PG resources and volume size
This commit is contained in:
parent
f9487e41c1
commit
9480b09b2c
|
|
@ -227,6 +227,10 @@ func (c *Cluster) Create() error {
|
||||||
|
|
||||||
c.setStatus(acidv1.ClusterStatusCreating)
|
c.setStatus(acidv1.ClusterStatusCreating)
|
||||||
|
|
||||||
|
if err = c.validateResources(&c.Spec); err != nil {
|
||||||
|
return fmt.Errorf("unsufficient ressources: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
for _, role := range []PostgresRole{Master, Replica} {
|
for _, role := range []PostgresRole{Master, Replica} {
|
||||||
|
|
||||||
if c.Endpoints[role] != nil {
|
if c.Endpoints[role] != nil {
|
||||||
|
|
@ -491,6 +495,53 @@ func compareResourcesAssumeFirstNotNil(a *v1.ResourceRequirements, b *v1.Resourc
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) validateResources(spec *acidv1.PostgresSpec) error {
|
||||||
|
|
||||||
|
const (
|
||||||
|
cpuMinimum = "256m"
|
||||||
|
memoryMinimum = "256Mi"
|
||||||
|
storageMinimum = "1Gi"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
isSmaller bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
cpuLimit := spec.Resources.ResourceLimits.CPU
|
||||||
|
if cpuLimit != "" {
|
||||||
|
isSmaller, err = util.IsSmallerQuantity(cpuLimit, cpuMinimum)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error validating CPU limit: %v", err)
|
||||||
|
}
|
||||||
|
if isSmaller {
|
||||||
|
return fmt.Errorf("defined CPU limit %s is below required minimum %s to properly run postgresql resource", cpuLimit, cpuMinimum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memoryLimit := spec.Resources.ResourceLimits.Memory
|
||||||
|
if memoryLimit != "" {
|
||||||
|
isSmaller, err = util.IsSmallerQuantity(memoryLimit, memoryMinimum)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error validating memory limit: %v", err)
|
||||||
|
}
|
||||||
|
if isSmaller {
|
||||||
|
return fmt.Errorf("defined memory limit %s is below required minimum %s to properly run postgresql resource", memoryLimit, memoryMinimum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storageSize := spec.Volume.Size
|
||||||
|
isSmaller, err = util.IsSmallerQuantity(storageSize, storageMinimum)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error validating volume size: %v", err)
|
||||||
|
}
|
||||||
|
if isSmaller {
|
||||||
|
return fmt.Errorf("defined volume size %s is below required minimum %s to properly run postgresql resource", storageSize, storageMinimum)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Update changes Kubernetes objects according to the new specification. Unlike the sync case, the missing object
|
// Update changes Kubernetes objects according to the new specification. Unlike the sync case, the missing object
|
||||||
// (i.e. service) is treated as an error
|
// (i.e. service) is treated as an error
|
||||||
// logical backup cron jobs are an exception: a user-initiated Update can enable a logical backup job
|
// logical backup cron jobs are an exception: a user-initiated Update can enable a logical backup job
|
||||||
|
|
|
||||||
|
|
@ -740,7 +740,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
|
||||||
limit = c.OpConfig.DefaultMemoryLimit
|
limit = c.OpConfig.DefaultMemoryLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
isSmaller, err := util.RequestIsSmallerThanLimit(request, limit)
|
isSmaller, err := util.IsSmallerQuantity(request, limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -767,7 +767,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
|
||||||
limit = c.OpConfig.DefaultMemoryLimit
|
limit = c.OpConfig.DefaultMemoryLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
isSmaller, err := util.RequestIsSmallerThanLimit(sidecarRequest, sidecarLimit)
|
isSmaller, err := util.IsSmallerQuantity(sidecarRequest, sidecarLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,17 +141,17 @@ func Coalesce(val, defaultVal string) string {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestIsSmallerThanLimit : ...
|
// IsSmallerQuantity : checks if first resource is of a smaller quantity than the second
|
||||||
func RequestIsSmallerThanLimit(requestStr, limitStr string) (bool, error) {
|
func IsSmallerQuantity(requestStr, limitStr string) (bool, error) {
|
||||||
|
|
||||||
request, err := resource.ParseQuantity(requestStr)
|
request, err := resource.ParseQuantity(requestStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("could not parse memory request %v : %v", requestStr, err)
|
return false, fmt.Errorf("could not parse request %v : %v", requestStr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
limit, err2 := resource.ParseQuantity(limitStr)
|
limit, err2 := resource.ParseQuantity(limitStr)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
return false, fmt.Errorf("could not parse memory limit %v : %v", limitStr, err2)
|
return false, fmt.Errorf("could not parse limit %v : %v", limitStr, err2)
|
||||||
}
|
}
|
||||||
|
|
||||||
return request.Cmp(limit) == -1, nil
|
return request.Cmp(limit) == -1, nil
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ var substringMatch = []struct {
|
||||||
{regexp.MustCompile(`aaaa (\d+) bbbb`), "aaaa 123 bbbb", nil},
|
{regexp.MustCompile(`aaaa (\d+) bbbb`), "aaaa 123 bbbb", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestIsSmallerThanLimitTests = []struct {
|
var requestIsSmallerQuantityTests = []struct {
|
||||||
request string
|
request string
|
||||||
limit string
|
limit string
|
||||||
out bool
|
out bool
|
||||||
|
|
@ -155,9 +155,9 @@ func TestMapContains(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestIsSmallerThanLimit(t *testing.T) {
|
func TestIsSmallerQuantity(t *testing.T) {
|
||||||
for _, tt := range requestIsSmallerThanLimitTests {
|
for _, tt := range requestIsSmallerQuantityTests {
|
||||||
res, err := RequestIsSmallerThanLimit(tt.request, tt.limit)
|
res, err := IsSmallerQuantity(tt.request, tt.limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("RequestIsSmallerThanLimit returned unexpected error: %#v", err)
|
t.Errorf("RequestIsSmallerThanLimit returned unexpected error: %#v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue