shifted/renamed db_models, removed reliance on clerk (for now). A few more docs.
This commit is contained in:
parent
2a4714fdad
commit
18c437a1f5
@ -1,12 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
from csv import writer
|
from csv import writer
|
||||||
from artifice import invoice
|
from artifice import invoice
|
||||||
from artifice import clerk_mixins
|
# from artifice import clerk_mixins
|
||||||
import yaml
|
import yaml
|
||||||
from decimal import *
|
from decimal import *
|
||||||
|
|
||||||
|
|
||||||
class Csv(clerk_mixins.ClerkRatesMixin, invoice.Invoice):
|
class Csv(invoice.RatesFileMixin, invoice.Invoice):
|
||||||
|
|
||||||
def __init__(self, tenant, start, end, config):
|
def __init__(self, tenant, start, end, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
from .models.db_models import Tenant as tenant_model
|
from .models import billing, Base, Tenant, Resource, UsageEntry
|
||||||
from .models.db_models import UsageEntry, Resource
|
|
||||||
from .models import billing, Base
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
import json
|
import json
|
||||||
@ -61,12 +59,12 @@ class Database(object):
|
|||||||
"""Returns a list of tenants based on the usage entries
|
"""Returns a list of tenants based on the usage entries
|
||||||
in the given range.
|
in the given range.
|
||||||
start, end: define the range to query
|
start, end: define the range to query
|
||||||
teants: is a iterable of tenants,
|
tenants: is a iterable of tenants,
|
||||||
if not given will default to whole tenant list."""
|
if not given will default to whole tenant list."""
|
||||||
|
|
||||||
if tenants is None:
|
if tenants is None:
|
||||||
tenants = self.session.query(tenant_model.tenant_id).\
|
tenants = self.session.query(Tenant.tenant_id).\
|
||||||
filter(tenant_model.active)
|
filter(Tenant.active)
|
||||||
elif not isinstance(tenants, collections.Iterable):
|
elif not isinstance(tenants, collections.Iterable):
|
||||||
raise AttributeError("tenants is not an iterable")
|
raise AttributeError("tenants is not an iterable")
|
||||||
|
|
||||||
@ -103,8 +101,8 @@ class Database(object):
|
|||||||
resource.usage_strategies[entry.service] = usage_strat
|
resource.usage_strategies[entry.service] = usage_strat
|
||||||
|
|
||||||
# build tenant:
|
# build tenant:
|
||||||
name = self.session.query(tenant_model.name).\
|
name = self.session.query(Tenant.name).\
|
||||||
filter(tenant_model.tenant_id == entry.tenant_id)
|
filter(Tenant.tenant_id == entry.tenant_id)
|
||||||
tenant = billing.Tenant(name[0].name, entry.tenant_id)
|
tenant = billing.Tenant(name[0].name, entry.tenant_id)
|
||||||
# add resource to tenant:
|
# add resource to tenant:
|
||||||
tenant.resources[entry.resource_id] = resource
|
tenant.resources[entry.resource_id] = resource
|
||||||
|
@ -118,7 +118,7 @@ class RatesFileMixin(object):
|
|||||||
# Adds a rates file loader, expecting various things from the
|
# Adds a rates file loader, expecting various things from the
|
||||||
# configuration
|
# configuration
|
||||||
|
|
||||||
def rate(self, name):
|
def rate(self, name, region=None):
|
||||||
try:
|
try:
|
||||||
self.__rates
|
self.__rates
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -1,8 +1,48 @@
|
|||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy import create_engine
|
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy import Column, Text, DateTime, Boolean, DECIMAL
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
#
|
#
|
||||||
|
|
||||||
Session = sessionmaker()
|
Session = sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
|
class UsageEntry(Base):
|
||||||
|
"""Simplified data store of usage information for a given service,
|
||||||
|
in a resource, in a tenant. Similar to ceilometer datastore,
|
||||||
|
but stores local transformed data."""
|
||||||
|
__tablename__ = 'usage'
|
||||||
|
service = Column(Text, primary_key=True)
|
||||||
|
volume = Column(DECIMAL)
|
||||||
|
resource_id = Column(Text, primary_key=True)
|
||||||
|
tenant_id = Column(Text, primary_key=True)
|
||||||
|
start = Column(DateTime)
|
||||||
|
end = Column(DateTime, primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Resource(Base):
|
||||||
|
"""Database model for storing metadata associated with a resource."""
|
||||||
|
__tablename__ = 'resources'
|
||||||
|
resource_id = Column(Text, primary_key=True)
|
||||||
|
info = Column(Text)
|
||||||
|
|
||||||
|
|
||||||
|
# this might not be a needed model?
|
||||||
|
class SalesOrder(Base):
|
||||||
|
"""Historic billing periods so that tenants cannot be rebuild accidentally."""
|
||||||
|
__tablename__ = 'sales_orders'
|
||||||
|
tenant_id = Column(Text, primary_key=True)
|
||||||
|
start = Column(DateTime)
|
||||||
|
end = Column(DateTime, primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
|
class Tenant(Base):
|
||||||
|
"""Model for storage of metadata related to a tenant."""
|
||||||
|
__tablename__ = 'tenants'
|
||||||
|
# ID is a uuid
|
||||||
|
tenant_id = Column(Text, primary_key=True, nullable=False)
|
||||||
|
name = Column(Text)
|
||||||
|
info = Column(Text)
|
||||||
|
active = Column(Boolean, default=True)
|
||||||
|
# Some reference data to something else?
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
from . import Base
|
|
||||||
from sqlalchemy import Column, Text, DateTime, Boolean, DECIMAL
|
|
||||||
|
|
||||||
|
|
||||||
class UsageEntry(Base):
|
|
||||||
__tablename__ = 'usage'
|
|
||||||
service = Column(Text, primary_key=True)
|
|
||||||
volume = Column(DECIMAL)
|
|
||||||
resource_id = Column(Text, primary_key=True)
|
|
||||||
tenant_id = Column(Text, primary_key=True)
|
|
||||||
start = Column(DateTime)
|
|
||||||
end = Column(DateTime, primary_key=True)
|
|
||||||
|
|
||||||
|
|
||||||
class Resource(Base):
|
|
||||||
__tablename__ = 'resources'
|
|
||||||
resource_id = Column(Text, primary_key=True)
|
|
||||||
info = Column(Text)
|
|
||||||
|
|
||||||
|
|
||||||
class SalesOrder(Base):
|
|
||||||
__tablename__ = 'sales_orders'
|
|
||||||
tenant_id = Column(Text, primary_key=True)
|
|
||||||
start = Column(DateTime)
|
|
||||||
end = Column(DateTime, primary_key=True)
|
|
||||||
|
|
||||||
|
|
||||||
class Tenant(Base):
|
|
||||||
|
|
||||||
__tablename__ = 'tenants'
|
|
||||||
# ID is a uuid
|
|
||||||
tenant_id = Column(Text, primary_key=True, nullable=False)
|
|
||||||
name = Column(Text)
|
|
||||||
info = Column(Text)
|
|
||||||
active = Column(Boolean, default=True)
|
|
||||||
# Some reference data to something else?
|
|
@ -1,8 +1,8 @@
|
|||||||
region | m1.nano | duration | 0.32
|
region | m1_nano | duration | 0.32
|
||||||
region | m1.micro | duration | 0.42
|
region | m1_micro | duration | 0.42
|
||||||
region | m1.tiny | duration | 0.62
|
region | m1_tiny | duration | 0.62
|
||||||
region | m1.small | duration | 0.82
|
region | m1_small | duration | 0.82
|
||||||
region | m1.medium | duration | 1.02
|
region | m1_medium | duration | 1.02
|
||||||
region | incoming_megabytes | bytes | 0.004
|
region | incoming_megabytes | bytes | 0.004
|
||||||
region | outgoing_megabytes | bytes | 0.007
|
region | outgoing_megabytes | bytes | 0.007
|
||||||
region | storage_size | bytes per hour | 0.000513
|
region | storage_size | bytes per hour | 0.000513
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
from . import test_interface
|
from . import test_interface
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from artifice import database
|
from artifice import database
|
||||||
from artifice.models.db_models import Tenant
|
from artifice.models import Tenant
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from . import test_interface
|
from . import test_interface
|
||||||
from artifice import database
|
from artifice import database
|
||||||
from artifice.models.db_models import Tenant
|
from artifice.models import Tenant
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
from artifice.billing import csv_invoice
|
from artifice.billing import csv_invoice
|
||||||
@ -10,7 +10,7 @@ Base = declarative_base()
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
"output_file": '%(tenant)s-%(start)s-%(end)s.csv',
|
"output_file": '%(tenant)s-%(start)s-%(end)s.csv',
|
||||||
"output_path": "./invoices",
|
"output_path": "./tests/invoices",
|
||||||
"rates": {"file":
|
"rates": {"file":
|
||||||
"/home/adriant/Projects/openstack-artifice/examples/csv_rates.csv"}
|
"/home/adriant/Projects/openstack-artifice/examples/csv_rates.csv"}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ from artifice.interface import Artifice
|
|||||||
import mock
|
import mock
|
||||||
import random
|
import random
|
||||||
import json
|
import json
|
||||||
from artifice.models.db_models import Tenant as tenant_model
|
from artifice.models import Tenant as tenant_model
|
||||||
from artifice.models.db_models import UsageEntry, Resource
|
from artifice.models import UsageEntry, Resource
|
||||||
# import copy
|
# import copy
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
|
Loading…
x
Reference in New Issue
Block a user