[UI] support Postgres version and pod resource changes + adding IOPS and throughput config options
This commit is contained in:
		
							parent
							
								
									654d22d04a
								
							
						
					
					
						commit
						8d71953246
					
				| 
						 | 
					@ -126,6 +126,7 @@ edit
 | 
				
			||||||
        if (i.metadata.selfLink) { delete i.metadata.selfLink }
 | 
					        if (i.metadata.selfLink) { delete i.metadata.selfLink }
 | 
				
			||||||
        if (i.metadata.uid) { delete i.metadata.uid }
 | 
					        if (i.metadata.uid) { delete i.metadata.uid }
 | 
				
			||||||
        if (i.metadata.resourceVersion) { delete i.metadata.resourceVersion }
 | 
					        if (i.metadata.resourceVersion) { delete i.metadata.resourceVersion }
 | 
				
			||||||
 | 
					        if (i.metadata.managedFields) { delete i.metadata.managedFields }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.update()
 | 
					        this.update()
 | 
				
			||||||
        this.refs.yamlNice.innerHTML = yamlParser.safeDump(i.postgresql, {sortKeys: true})
 | 
					        this.refs.yamlNice.innerHTML = yamlParser.safeDump(i.postgresql, {sortKeys: true})
 | 
				
			||||||
| 
						 | 
					@ -138,7 +139,15 @@ edit
 | 
				
			||||||
        o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false
 | 
					        o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false
 | 
				
			||||||
        o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false
 | 
					        o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false
 | 
				
			||||||
        o.spec.enableConnectionPooler = i.spec.enableConnectionPooler || false
 | 
					        o.spec.enableConnectionPooler = i.spec.enableConnectionPooler || false
 | 
				
			||||||
        o.spec.volume = { size: i.spec.volume.size }
 | 
					
 | 
				
			||||||
 | 
					        o.spec.volume = {
 | 
				
			||||||
 | 
					          size: i.spec.volume.size,
 | 
				
			||||||
 | 
					          throughput: i.spec.volume.throughput || 125,
 | 
				
			||||||
 | 
					          iops: i.spec.volume.iops || 3000
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        o.spec.postgresql = {}
 | 
				
			||||||
 | 
					        o.spec.postgresql.version = i.spec.postgresql.version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ('users' in i.spec && typeof i.spec.users === 'object') {
 | 
					        if ('users' in i.spec && typeof i.spec.users === 'object') {
 | 
				
			||||||
          o.spec.users = Object.mapValues(i.spec.users, roleFlags =>
 | 
					          o.spec.users = Object.mapValues(i.spec.users, roleFlags =>
 | 
				
			||||||
| 
						 | 
					@ -166,7 +175,7 @@ edit
 | 
				
			||||||
              ].forEach(resourceType => {
 | 
					              ].forEach(resourceType => {
 | 
				
			||||||
                if (resourceType in resources) {
 | 
					                if (resourceType in resources) {
 | 
				
			||||||
                  const resourceClaim = resources[resourceType]
 | 
					                  const resourceClaim = resources[resourceType]
 | 
				
			||||||
                  if (typeof resourceClaim === '') {
 | 
					                  if (typeof resourceClaim === 'string') {
 | 
				
			||||||
                    o.spec.resources[section][resourceType] = resources[resourceType]
 | 
					                    o.spec.resources[section][resourceType] = resources[resourceType]
 | 
				
			||||||
                  }
 | 
					                  }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,6 @@ help-general
 | 
				
			||||||
    h3 Basics
 | 
					    h3 Basics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    p.
 | 
					    p.
 | 
				
			||||||
      The PostgreSQL operator will use your definition to create a new
 | 
					      The Postgres Operator will use your definition to create a new
 | 
				
			||||||
      PostgreSQL cluster for you. You can either copy the yaml definition
 | 
					      PostgreSQL cluster for you. You can either copy the yaml definition
 | 
				
			||||||
      to the repositiory or you can just hit create cluster.
 | 
					      to a repositiory or hit create cluster (not available in prod).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -266,6 +266,37 @@ new
 | 
				
			||||||
                  )
 | 
					                  )
 | 
				
			||||||
                  .input-group-addon
 | 
					                  .input-group-addon
 | 
				
			||||||
                    .input-units Gi
 | 
					                    .input-units Gi
 | 
				
			||||||
 | 
					            tr
 | 
				
			||||||
 | 
					              td 
 | 
				
			||||||
 | 
					              td Specify Iops and Throughput only if you need more than the default 3000 Iops and 125Mb/s EBS provides.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tr
 | 
				
			||||||
 | 
					              td Iops
 | 
				
			||||||
 | 
					              td
 | 
				
			||||||
 | 
					                .input-group
 | 
				
			||||||
 | 
					                  input.form-control(
 | 
				
			||||||
 | 
					                    ref='iops'
 | 
				
			||||||
 | 
					                    type='number'
 | 
				
			||||||
 | 
					                    value='{ iops }'
 | 
				
			||||||
 | 
					                    onchange='{ iopsChange }'
 | 
				
			||||||
 | 
					                    onkeyup='{ iopsChange }'
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                  .input-group-addon
 | 
				
			||||||
 | 
					                    .input-units
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tr
 | 
				
			||||||
 | 
					              td Througput
 | 
				
			||||||
 | 
					              td
 | 
				
			||||||
 | 
					                .input-group
 | 
				
			||||||
 | 
					                  input.form-control(
 | 
				
			||||||
 | 
					                    ref='throughput'
 | 
				
			||||||
 | 
					                    type='number'
 | 
				
			||||||
 | 
					                    value='{ throughput }'
 | 
				
			||||||
 | 
					                    onchange='{ throughputChange }'
 | 
				
			||||||
 | 
					                    onkeyup='{ throughputChange }'
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					                  .input-group-addon
 | 
				
			||||||
 | 
					                    .input-units MB/s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            tr(if='{ config.users_visible }')
 | 
					            tr(if='{ config.users_visible }')
 | 
				
			||||||
              td
 | 
					              td
 | 
				
			||||||
| 
						 | 
					@ -509,7 +540,9 @@ new
 | 
				
			||||||
        enableConnectionPooler: true
 | 
					        enableConnectionPooler: true
 | 
				
			||||||
        {{/if}}
 | 
					        {{/if}}
 | 
				
			||||||
        volume:
 | 
					        volume:
 | 
				
			||||||
          size: "{{ volumeSize }}Gi"
 | 
					          size: "{{ volumeSize }}Gi"{{#if iops}}
 | 
				
			||||||
 | 
					          iops: {{ iops }}{{/if}}{{#if throughput}}
 | 
				
			||||||
 | 
					          throughput: {{ throughput }}{{/if}}
 | 
				
			||||||
        {{#if users}}
 | 
					        {{#if users}}
 | 
				
			||||||
        users:{{#each users}}
 | 
					        users:{{#each users}}
 | 
				
			||||||
          {{ state }}: []{{/each}}{{/if}}
 | 
					          {{ state }}: []{{/each}}{{/if}}
 | 
				
			||||||
| 
						 | 
					@ -560,6 +593,8 @@ new
 | 
				
			||||||
        enableReplicaLoadBalancer: this.enableReplicaLoadBalancer,
 | 
					        enableReplicaLoadBalancer: this.enableReplicaLoadBalancer,
 | 
				
			||||||
        enableConnectionPooler: this.enableConnectionPooler,
 | 
					        enableConnectionPooler: this.enableConnectionPooler,
 | 
				
			||||||
        volumeSize: this.volumeSize,
 | 
					        volumeSize: this.volumeSize,
 | 
				
			||||||
 | 
					        iops: this.iops,
 | 
				
			||||||
 | 
					        throughput: this.throughput,
 | 
				
			||||||
        users: this.users.valids,
 | 
					        users: this.users.valids,
 | 
				
			||||||
        databases: this.databases.valids,
 | 
					        databases: this.databases.valids,
 | 
				
			||||||
        ranges: this.ranges,
 | 
					        ranges: this.ranges,
 | 
				
			||||||
| 
						 | 
					@ -624,6 +659,14 @@ new
 | 
				
			||||||
      this.volumeSize = +e.target.value
 | 
					      this.volumeSize = +e.target.value
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.iopsChange = e => {
 | 
				
			||||||
 | 
					      this.iops = +e.target.value
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.throughputChange = e => {
 | 
				
			||||||
 | 
					      this.throughput = +e.target.value
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.updateDNSName = () => {
 | 
					    this.updateDNSName = () => {
 | 
				
			||||||
      this.dnsName = this.config.dns_format_string.format(
 | 
					      this.dnsName = this.config.dns_format_string.format(
 | 
				
			||||||
        this.name,
 | 
					        this.name,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,7 @@ postgresqls
 | 
				
			||||||
            td { cpu } / { cpu_limit }
 | 
					            td { cpu } / { cpu_limit }
 | 
				
			||||||
            td { memory } / { memory_limit }
 | 
					            td { memory } / { memory_limit }
 | 
				
			||||||
            td { volume_size }
 | 
					            td { volume_size }
 | 
				
			||||||
            td { calcCosts(nodes, cpu, memory, volume_size) }$
 | 
					            td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            td
 | 
					            td
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,7 @@ postgresqls
 | 
				
			||||||
            td { cpu } / { cpu_limit }
 | 
					            td { cpu } / { cpu_limit }
 | 
				
			||||||
            td { memory } / { memory_limit }
 | 
					            td { memory } / { memory_limit }
 | 
				
			||||||
            td { volume_size }
 | 
					            td { volume_size }
 | 
				
			||||||
            td { calcCosts(nodes, cpu, memory, volume_size) }$
 | 
					            td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            td
 | 
					            td
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -227,8 +227,21 @@ postgresqls
 | 
				
			||||||
      + '/' + encodeURI(cluster.name)
 | 
					      + '/' + encodeURI(cluster.name)
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const calcCosts = this.calcCosts = (nodes, cpu, memory, disk) => {
 | 
					    const calcCosts = this.calcCosts = (nodes, cpu, memory, disk, iops, throughput) => {
 | 
				
			||||||
        costs = Math.max(nodes, opts.config.min_pods) * (toCores(cpu) * opts.config.cost_core + toMemory(memory) * opts.config.cost_memory + toDisk(disk) * opts.config.cost_ebs)
 | 
					      podcount = Math.max(nodes, opts.config.min_pods)
 | 
				
			||||||
 | 
					      corecost = toCores(cpu) * opts.config.cost_core
 | 
				
			||||||
 | 
					      memorycost = toMemory(memory) * opts.config.cost_memory
 | 
				
			||||||
 | 
					      diskcost = toDisk(disk) * opts.config.cost_ebs
 | 
				
			||||||
 | 
					      iopscost = 0
 | 
				
			||||||
 | 
					      if (iops !== undefined && iops > 3000) {
 | 
				
			||||||
 | 
					        iopscost = (iops - 3000) * opts.config.cost_iops
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      throughputcost = 0
 | 
				
			||||||
 | 
					      if (throughput !== undefined && throughput > 125) {
 | 
				
			||||||
 | 
					        throughputcost = (throughput - 125) * opts.config.cost_throughput
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      costs = podcount * (corecost + memorycost + diskcost + iopscost + throughputcost)
 | 
				
			||||||
       return costs.toFixed(2)
 | 
					       return costs.toFixed(2)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,6 +266,11 @@ postgresqls
 | 
				
			||||||
        value = Number(value)
 | 
					        value = Number(value)
 | 
				
			||||||
        return value
 | 
					        return value
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      else if(value.endsWith("Ti")) {
 | 
				
			||||||
 | 
					        value = value.substring(0, value.length-2)
 | 
				
			||||||
 | 
					        value = Number(value) * 1000
 | 
				
			||||||
 | 
					        return value
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return value
 | 
					      return value
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,9 @@ spec:
 | 
				
			||||||
                  "replica_load_balancer_visible": true,
 | 
					                  "replica_load_balancer_visible": true,
 | 
				
			||||||
                  "resources_visible": true,
 | 
					                  "resources_visible": true,
 | 
				
			||||||
                  "users_visible": true,
 | 
					                  "users_visible": true,
 | 
				
			||||||
                  "cost_ebs": 0.119,
 | 
					                  "cost_ebs": 0.0952,
 | 
				
			||||||
 | 
					                  "cost_iops": 0.006,
 | 
				
			||||||
 | 
					                  "cost_throughput": 0.0476,
 | 
				
			||||||
                  "cost_core": 0.0575,
 | 
					                  "cost_core": 0.0575,
 | 
				
			||||||
                  "cost_memory": 0.014375,
 | 
					                  "cost_memory": 0.014375,
 | 
				
			||||||
                  "postgresql_versions": [
 | 
					                  "postgresql_versions": [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,8 +89,10 @@ TARGET_NAMESPACE = getenv('TARGET_NAMESPACE')
 | 
				
			||||||
GOOGLE_ANALYTICS = getenv('GOOGLE_ANALYTICS', False)
 | 
					GOOGLE_ANALYTICS = getenv('GOOGLE_ANALYTICS', False)
 | 
				
			||||||
MIN_PODS= getenv('MIN_PODS', 2)
 | 
					MIN_PODS= getenv('MIN_PODS', 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# storage pricing, i.e. https://aws.amazon.com/ebs/pricing/
 | 
					# storage pricing, i.e. https://aws.amazon.com/ebs/pricing/ (e.g. Europe - Franfurt)
 | 
				
			||||||
COST_EBS = float(getenv('COST_EBS', 0.119))  # GB per month
 | 
					COST_EBS = float(getenv('COST_EBS', 0.0952))  # GB per month
 | 
				
			||||||
 | 
					COST_IOPS = float(getenv('COST_IOPS', 0.006))  # IOPS per month above 3000 baseline
 | 
				
			||||||
 | 
					COST_THROUGHPUT = float(getenv('COST_THROUGHPUT', 0.0476))  # MB/s per month above 125 MB/s baseline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge
 | 
					# compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge
 | 
				
			||||||
COST_CORE = 30.5 * 24 * float(getenv('COST_CORE', 0.0575))  # Core per hour m5.2xlarge / 8.
 | 
					COST_CORE = 30.5 * 24 * float(getenv('COST_CORE', 0.0575))  # Core per hour m5.2xlarge / 8.
 | 
				
			||||||
| 
						 | 
					@ -308,6 +310,8 @@ DEFAULT_UI_CONFIG = {
 | 
				
			||||||
    'pgui_link': '',
 | 
					    'pgui_link': '',
 | 
				
			||||||
    'static_network_whitelist': {},
 | 
					    'static_network_whitelist': {},
 | 
				
			||||||
    'cost_ebs': COST_EBS,
 | 
					    'cost_ebs': COST_EBS,
 | 
				
			||||||
 | 
					    'cost_iops': COST_IOPS,
 | 
				
			||||||
 | 
					    'cost_throughput': COST_THROUGHPUT,
 | 
				
			||||||
    'cost_core': COST_CORE,
 | 
					    'cost_core': COST_CORE,
 | 
				
			||||||
    'cost_memory': COST_MEMORY,
 | 
					    'cost_memory': COST_MEMORY,
 | 
				
			||||||
    'min_pods': MIN_PODS
 | 
					    'min_pods': MIN_PODS
 | 
				
			||||||
| 
						 | 
					@ -487,6 +491,8 @@ def get_postgresqls():
 | 
				
			||||||
            'cpu': spec.get('resources', {}).get('requests', {}).get('cpu', 0),
 | 
					            'cpu': spec.get('resources', {}).get('requests', {}).get('cpu', 0),
 | 
				
			||||||
            'cpu_limit': spec.get('resources', {}).get('limits', {}).get('cpu', 0),
 | 
					            'cpu_limit': spec.get('resources', {}).get('limits', {}).get('cpu', 0),
 | 
				
			||||||
            'volume_size': spec.get('volume', {}).get('size', 0),
 | 
					            'volume_size': spec.get('volume', {}).get('size', 0),
 | 
				
			||||||
 | 
					            'iops': spec.get('volume', {}).get('iops', 3000),
 | 
				
			||||||
 | 
					            'throughput': spec.get('volume', {}).get('throughput', 125),
 | 
				
			||||||
            'team': (
 | 
					            'team': (
 | 
				
			||||||
                spec.get('teamId') or
 | 
					                spec.get('teamId') or
 | 
				
			||||||
                metadata.get('labels', {}).get('team', '')
 | 
					                metadata.get('labels', {}).get('team', '')
 | 
				
			||||||
| 
						 | 
					@ -614,6 +620,28 @@ def update_postgresql(namespace: str, cluster: str):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        spec['volume'] = {'size': size}
 | 
					        spec['volume'] = {'size': size}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (
 | 
				
			||||||
 | 
					        'volume' in postgresql['spec']
 | 
				
			||||||
 | 
					        and 'iops' in postgresql['spec']['volume']
 | 
				
			||||||
 | 
					        and postgresql['spec']['volume']['iops'] != None
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        iops = int(postgresql['spec']['volume']['iops'])
 | 
				
			||||||
 | 
					        if not 'volume' in spec:
 | 
				
			||||||
 | 
					            spec['volume'] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        spec['volume']['iops'] = iops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (
 | 
				
			||||||
 | 
					        'volume' in postgresql['spec']
 | 
				
			||||||
 | 
					        and 'throughput' in postgresql['spec']['volume']
 | 
				
			||||||
 | 
					        and postgresql['spec']['volume']['throughput'] != None
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
 | 
					        throughput = int(postgresql['spec']['volume']['throughput'])
 | 
				
			||||||
 | 
					        if not 'volume' in spec:
 | 
				
			||||||
 | 
					            spec['volume'] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        spec['volume']['throughput'] = throughput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if 'enableConnectionPooler' in postgresql['spec']:
 | 
					    if 'enableConnectionPooler' in postgresql['spec']:
 | 
				
			||||||
        cp = postgresql['spec']['enableConnectionPooler']
 | 
					        cp = postgresql['spec']['enableConnectionPooler']
 | 
				
			||||||
        if not cp:
 | 
					        if not cp:
 | 
				
			||||||
| 
						 | 
					@ -758,6 +786,27 @@ def update_postgresql(namespace: str, cluster: str):
 | 
				
			||||||
                    owner_username=owner_username,
 | 
					                    owner_username=owner_username,
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resource_types = ["cpu","memory"]
 | 
				
			||||||
 | 
					    resource_constraints = ["requests","limits"]
 | 
				
			||||||
 | 
					    if "resources" in postgresql["spec"]:
 | 
				
			||||||
 | 
					        spec["resources"] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        res = postgresql["spec"]["resources"]
 | 
				
			||||||
 | 
					        for rt in resource_types:
 | 
				
			||||||
 | 
					            for rc in resource_constraints:
 | 
				
			||||||
 | 
					                if rc in res:
 | 
				
			||||||
 | 
					                    if rt in res[rc]:
 | 
				
			||||||
 | 
					                        if not rc in spec["resources"]:
 | 
				
			||||||
 | 
					                            spec["resources"][rc] = {}
 | 
				
			||||||
 | 
					                        spec["resources"][rc][rt] = res[rc][rt]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if "postgresql" in postgresql["spec"]:
 | 
				
			||||||
 | 
					        if "version" in postgresql["spec"]["postgresql"]:
 | 
				
			||||||
 | 
					            if "postgresql" not in spec:
 | 
				
			||||||
 | 
					                spec["postgresql"]={}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            spec["postgresql"]["version"] = postgresql["spec"]["postgresql"]["version"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    o['spec'].update(spec)
 | 
					    o['spec'].update(spec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    apply_postgresql(get_cluster(), namespace, cluster, o)
 | 
					    apply_postgresql(get_cluster(), namespace, cluster, o)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,9 @@ default_operator_ui_config='{
 | 
				
			||||||
  "nat_gateways_visible": false,
 | 
					  "nat_gateways_visible": false,
 | 
				
			||||||
  "resources_visible": true,
 | 
					  "resources_visible": true,
 | 
				
			||||||
  "users_visible": true,
 | 
					  "users_visible": true,
 | 
				
			||||||
  "cost_ebs": 0.119,
 | 
					  "cost_ebs": 0.0952,
 | 
				
			||||||
 | 
					  "cost_iops": 0.006,
 | 
				
			||||||
 | 
					  "cost_throughput": 0.0476,
 | 
				
			||||||
  "cost_core": 0.0575,
 | 
					  "cost_core": 0.0575,
 | 
				
			||||||
  "cost_memory": 0.014375,
 | 
					  "cost_memory": 0.014375,
 | 
				
			||||||
  "postgresql_versions": [
 | 
					  "postgresql_versions": [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue