backend/satellite_tools/satCerts.py | 209 +++++++++++++++++++++++++++++++++++-
1 file changed, 208 insertions(+), 1 deletion(-)
New commits:
commit 04fe23a6d3525c7de1651bde6e7ab69ebff5479a
Author: Jan Pazdziora <jpazdziora(a)redhat.com>
Date: Tue Dec 20 13:42:09 2011 +0100
Check for channel family entitlement counts.
This should provide nicer messages for errors
common.rhnException.rhnFault: (23, 'ORA-20294: (not_enough_flex_entitlements_in_base_org) - You do not have enough entitlements in the base org.: org_id [1] family [rhel-server-6] max [10]', 'Could not update database entry.')
common.rhnException.rhnFault: (23, 'ORA-20290: (not_enough_entitlements_in_base_org) - You do not have enough entitlements in the base org.: org_id [1] family [rhel-server-6] max [-3]', 'Could not update database entry.')
diff --git a/backend/satellite_tools/satCerts.py b/backend/satellite_tools/satCerts.py
index 5eb954e..f3a4890 100644
--- a/backend/satellite_tools/satCerts.py
+++ b/backend/satellite_tools/satCerts.py
@@ -134,6 +134,40 @@ select case when rhnServerGroup.org_id = :base_org_id then 'base' else 'other' e
group by org, slot_name
""")
+_query_get_family_counts = rhnSQL.Statement("""
+select org, label,
+ sum(current_members) as current_members,
+ sum(max_members) as max_members,
+ sum(fve_current_members) as fve_current_members,
+ sum(fve_max_members) as fve_max_members,
+ sum(physical_count) as physical_count,
+ sum(virtual_count) as virtual_count
+from (
+ select case when CFO.org_id = :base_org_id then 'base' else 'other' end as org,
+ CFO.label,
+ CFO.current_members, coalesce(CFO.max_members, 0) as max_members,
+ CFO.fve_current_members, coalesce(CFO.fve_max_members, 0) as fve_max_members,
+ (select count(CFS.server_id)
+ from rhnChannelFamilyServers CFS
+ where CFS.customer_id = CFO.org_id
+ and CFS.channel_family_id = CFO.id
+ and CFS.server_id not in
+ (select virtual_system_id from rhnVirtualInstance)) as physical_count,
+ (select count(CFS.server_id)
+ from rhnChannelFamilyServers CFS
+ where CFS.customer_id = CFO.org_id
+ and CFS.channel_family_id = CFO.id
+ and CFS.server_id in
+ (select virtual_system_id from rhnVirtualInstance)
+ and CFS.server_id not in
+ (select SV.server_id from rhnChannelFamilyServerVirtual SV
+ where SV.CHANNEL_FAMILY_ID = CFO.id)) as virtual_count
+ from rhnChannelFamilyOverview CFO
+) X
+group by org, label
+""")
+
+
def set_slots_from_cert(cert):
""" populates database with entitlements from an RHN certificate
"cert" is a satellite_cert.SatelliteCert() object
@@ -198,6 +232,105 @@ def set_slots_from_cert(cert):
entitlement_name = entitlement_name.replace('RHN ', '')
sys.stderr.write(" In the WebUI, the entitlement is named %s.\n" % entitlement_name)
+ h = rhnSQL.prepare(_query_get_family_counts)
+ h.execute(base_org_id = org_id)
+ rows = h.fetchall_dict()
+
+ families = {}
+ for entry in rows:
+ if not families.has_key(entry['label']):
+ families[entry['label']] = { 'base' : ( 0, 0, 0, 0, 0, 0 ), 'other' : ( 0, 0, 0, 0, 0, 0 ) }
+
+ families[entry['label']][entry['org']] = [ entry[i] for i in ( 'current_members',
+ 'max_members',
+ 'fve_current_members',
+ 'fve_max_members',
+ 'physical_count',
+ 'virtual_count'
+ )]
+
+ print families['rhel-server-6']
+ print families['private-channel-family-1']
+
+ for cf in cert.channel_families:
+ if not families.has_key(cf.name):
+ continue
+ flex = cf.flex
+ if not flex:
+ flex = 0
+ flex = int(flex)
+
+ quantity = cf.quantity
+ if not quantity:
+ quantity = 0
+ quantity = int(quantity)
+
+ # print cf.name, quantity, flex
+ if cf.name == 'rhel-server-6':
+ print cf.name, quantity, flex
+
+ existing_base = families[cf.name]['base'][4] + families[cf.name]['base'][5]
+ allocated_other = families[cf.name]['other'][1] + families[cf.name]['other'][3]
+
+ if quantity < existing_base + allocated_other:
+ has_error = True
+ sys.stderr.write("Certificate specifies %s of %s channel family entitlements" % ( quantity, cf.name ))
+ if flex:
+ sys.stderr.write(",\n of which %s are flex entitlements.\n" % flex)
+ else:
+ sys.stderr.write(".\n")
+ sys.stderr.write(" There are")
+ if existing_base:
+ sys.stderr.write(" %s systems in the base organization" % existing_base)
+ if not families[cf.name]['base'][4]:
+ sys.stderr.write(", all virtual (flex-capable)")
+ elif families[cf.name]['base'][5]:
+ sys.stderr.write("\n of which %s are virtual (flex-capable)" % families[cf.name]['base'][5])
+
+ if allocated_other:
+ sys.stderr.write(",\n plus")
+ else:
+ sys.stderr.write(".\n")
+
+ if allocated_other:
+ sys.stderr.write(" %s entitlements allocated to non-base org(s) (%s used).\n" % (allocated_other, families[cf.name]['other'][0] + families[cf.name]['other'][2]))
+
+ sys.stderr.write(" You might need to ")
+ if existing_base:
+ sys.stderr.write("unentitle some systems in the base organization")
+ if existing_base and allocated_other:
+ sys.stderr.write(",\n or ")
+ if allocated_other:
+ sys.stderr.write("deallocate some entitlements from non-base organization(s)")
+ sys.stderr.write(".\n")
+ sys.stderr.write(" You need to free %s entitlements to match the new certificate.\n" % (existing_base + allocated_other - quantity))
+
+ elif quantity - flex < families[cf.name]['base'][4] + families[cf.name]['other'][1]:
+ has_error = True
+ sys.stderr.write("Certificate specifies %s of %s non-flex entitlements.\n" % ( quantity - flex, cf.name ))
+
+ sys.stderr.write(" There are")
+ if families[cf.name]['base'][4]:
+ sys.stderr.write(" %s non-flex systems in the base organization" % families[cf.name]['base'][4])
+
+ if families[cf.name]['other'][1]:
+ sys.stderr.write(",\n plus")
+ else:
+ sys.stderr.write(".\n")
+
+ if families[cf.name]['other'][1]:
+ sys.stderr.write(" %s non-flex entitlements allocated to non-base org(s) (%s used).\n" % (families[cf.name]['other'][1], families[cf.name]['other'][0]))
+
+ sys.stderr.write(" You might need to ")
+ if families[cf.name]['base'][4]:
+ sys.stderr.write("unentitle some systems in the base organization")
+ if families[cf.name]['base'][4] and families[cf.name]['other'][1]:
+ sys.stderr.write(",\n or ")
+ if families[cf.name]['other'][1]:
+ sys.stderr.write("deallocate some entitlements from non-base organization(s)")
+ sys.stderr.write(".\n")
+ sys.stderr.write(" You need to free %s entitlements to match the new certificate.\n" % (families[cf.name]['base'][4] + families[cf.name]['other'][1] - (quantity - flex)))
+
if has_error:
sys.stderr.write("Activation failed, will now exit with no changes.\n")
sys.exit(1)
commit 570df4c30b5a57c0372038ec3df1e26069f31720
Author: Jan Pazdziora <jpazdziora(a)redhat.com>
Date: Thu Dec 8 14:47:33 2011 +0100
Also show what the certificate slot is called in the WebUI.
diff --git a/backend/satellite_tools/satCerts.py b/backend/satellite_tools/satCerts.py
index e878d0e..5eb954e 100644
--- a/backend/satellite_tools/satCerts.py
+++ b/backend/satellite_tools/satCerts.py
@@ -142,6 +142,8 @@ def set_slots_from_cert(cert):
org_id = get_org_id()
counts = {}
+ slot_table = rhnSQL.Table("rhnServerGroupType", "label")
+
h = rhnSQL.prepare(_query_get_slots)
h.execute(base_org_id = org_id)
rows = h.fetchall_dict()
@@ -189,6 +191,12 @@ def set_slots_from_cert(cert):
sys.stderr.write("deallocate some entitlements from non-base organization(s)")
sys.stderr.write(".\n")
sys.stderr.write(" You need to free %s entitlements to match the new certificate.\n" % (allocated - quantity))
+ if slot_table.has_key(db_label):
+ entitlement_name = slot_table[db_label]['name']
+ entitlement_name = entitlement_name.replace(' Entitled Servers', '')
+ entitlement_name = entitlement_name.replace('Spacewalk ', '')
+ entitlement_name = entitlement_name.replace('RHN ', '')
+ sys.stderr.write(" In the WebUI, the entitlement is named %s.\n" % entitlement_name)
if has_error:
sys.stderr.write("Activation failed, will now exit with no changes.\n")
@@ -199,7 +207,6 @@ def set_slots_from_cert(cert):
activate_system_entitlement = rhnSQL.Procedure(
"rhn_entitlements.activate_system_entitlement")
org_service_proc = rhnSQL.Procedure("rhn_entitlements.modify_org_service")
- slot_table = rhnSQL.Table("rhnServerGroupType", "label")
# Fetch all available entitlements; the ones that are not present in the
# cert will have to be set to zero
h = rhnSQL.prepare(_query_get_allorg_slot_types)
commit db09035c9f6c9e13554a89395f76040d40577f5a
Author: Jan Pazdziora <jpazdziora(a)redhat.com>
Date: Wed Dec 7 17:12:01 2011 +0100
Better explanation of slot changes.
diff --git a/backend/satellite_tools/satCerts.py b/backend/satellite_tools/satCerts.py
index 2203f16..e878d0e 100644
--- a/backend/satellite_tools/satCerts.py
+++ b/backend/satellite_tools/satCerts.py
@@ -121,6 +121,18 @@ _query_get_allorg_slot_types = rhnSQL.Statement("""
where sg.group_type = sgt.id
""")
+_query_get_slots = rhnSQL.Statement("""
+select org, slot_name, sum(max_members) as max_members, sum(current_members) as current_members
+from (
+select case when rhnServerGroup.org_id = :base_org_id then 'base' else 'other' end as org,
+ rhnServerGroupType.label as slot_name,
+ rhnServerGroup.max_members,
+ rhnServerGroup.current_members
+ from rhnServerGroup, rhnServerGroupType
+ where rhnServerGroup.group_type = rhnServerGroupType.id
+) X
+group by org, slot_name
+""")
def set_slots_from_cert(cert):
""" populates database with entitlements from an RHN certificate
@@ -129,6 +141,61 @@ def set_slots_from_cert(cert):
"""
org_id = get_org_id()
+ counts = {}
+ h = rhnSQL.prepare(_query_get_slots)
+ h.execute(base_org_id = org_id)
+ rows = h.fetchall_dict()
+
+ for entry in rows:
+ if not counts.has_key(entry['slot_name']):
+ counts[entry['slot_name']] = { 'base' : ( 0, 0 ), 'other' : ( 0, 0 ) }
+
+ counts[entry['slot_name']][entry['org']] = ( entry['max_members'], entry['current_members'] )
+
+ has_error = False
+ for slot_type in cert.get_slot_types():
+ slots = cert.get_slots(slot_type)
+ db_label = slots.get_db_label()
+ quantity = slots.get_quantity()
+ # Do not pass along a NULL quantity - NULL for
+ # rhnServerGroup.max_members means 'no maximum' BZ #160046
+ if not quantity:
+ quantity = 0
+ else:
+ quantity = int(quantity)
+
+ if not counts.has_key(db_label):
+ continue
+
+ allocated = counts[db_label]['base'][1] + counts[db_label]['other'][0]
+ if allocated > quantity:
+ has_error = True
+ sys.stderr.write("Certificate specifies %s of %s entitlements.\n" % ( quantity, db_label ))
+ sys.stderr.write(" There are ")
+ if counts[db_label]['base'][1]:
+ sys.stderr.write("%s entitlements used by systems in the base (id %s) organization" % ( counts[db_label]['base'][1], org_id ))
+ if counts[db_label]['base'][1] and counts[db_label]['other'][0]:
+ sys.stderr.write(",\n plus ")
+ if counts[db_label]['other'][0]:
+ sys.stderr.write("%s entitlements allocated to non-base org(s) (%s used)" % ( counts[db_label]['other'][0], counts[db_label]['other'][1] ))
+ sys.stderr.write(".\n")
+
+ sys.stderr.write(" You might need to ")
+ if counts[db_label]['base'][1]:
+ sys.stderr.write("unentitle some systems in the base organization")
+ if counts[db_label]['base'][1] and counts[db_label]['other'][0]:
+ sys.stderr.write(",\n or ")
+ if counts[db_label]['other'][0]:
+ sys.stderr.write("deallocate some entitlements from non-base organization(s)")
+ sys.stderr.write(".\n")
+ sys.stderr.write(" You need to free %s entitlements to match the new certificate.\n" % (allocated - quantity))
+
+ if has_error:
+ sys.stderr.write("Activation failed, will now exit with no changes.\n")
+ sys.exit(1)
+
+
+
activate_system_entitlement = rhnSQL.Procedure(
"rhn_entitlements.activate_system_entitlement")
org_service_proc = rhnSQL.Procedure("rhn_entitlements.modify_org_service")