Add SubordinateOverrides & Fix Log_services privileges

SubordinateOverrides:
  This commit automates the creation of SubordinateOverrides privileges
  structures from the redfish privilege registry. In addition, it
  enhances the function of parse_registries.py.

  It reads SubordinateOverrides privilege registry from DMTF and
  generates const defines SubordinateOverrides for all the privilege
  registry entries in the same format that the Privileges struct
  accepts.

  Moreover, it generates unique const defines for all
  SubordinateOverrides target levels.
  Ex: EthernetInterface SubordinateOverrides has two "Targets":
      ["Manager", "EthernetInterfaceCollection"]. So
      parse_registries.py generates two unique const

      1) Subordinate override for Manager -> EthernetInterface
      2) Subordinate override for Manager ->
         EthernetInterfaceCollection ->  EthernetInterface

  Note: if SubordinateOverrides privilege gets changed, then it
  automatically updates that route privilege, but if
  SubordinateOverrides target gets changed, then the user needs to
  update that manually.

Fix Log_services privileges:
  In Log_services, some of the privileges not following the
  Redfish_1.1.0_PrivilegeRegistry registry.

  This commit contains the following LogServices privileges.

  1) POST method
```
     ComputerSystem -> LogServiceCollection -> LogService
      - POST /redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/
      - POST /redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/
      - POST /redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/
      - POST /LogServices/PostCodes/Actions/LogService.ClearLog/
```

   2) DELETE method
```
     ComputerSystem -> LogServiceCollection -> LogService -> LogEntryCollection -> LogEntry
       - DELETE /redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/
```

This commit also changes the current privilege

   1) ConfigureManager to ConfigureComponents.

```
    DELETE /redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>
```

   2) ConfigureCompnents -> ConfigureManager

```
   POST /redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/
   POST /redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/
   POST /redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/
```

Tested: manually tested on Witherspoon system, there is no change in
        output. Run Redfish validator, with all different Privileges;
        Error Get: UUID: String '' does not match pattern ''
        this commit doesn't affect UUID

Email sent to openbmc list:
https://lists.ozlabs.org/pipermail/openbmc/2021-August/027232.html

Change-Id: I37d8a2882f1cfaa59a482083f180fdd0805e2e7d
Signed-off-by: Abhishek Patel <Abhishek.Patel@ibm.com>
Signed-off-by: Myung Bae <myungbae@us.ibm.com>
diff --git a/redfish-core/include/registries/privilege_registry.hpp b/redfish-core/include/registries/privilege_registry.hpp
index 5367aaf..07685c7 100644
--- a/redfish-core/include/registries/privilege_registry.hpp
+++ b/redfish-core/include/registries/privilege_registry.hpp
@@ -256,6 +256,14 @@
 const static auto& deleteCertificate = privilegeSetConfigureManager;
 const static auto& postCertificate = privilegeSetConfigureManager;
 
+// Subordinate override for ComputerSystem -> Certificate
+const static auto& getCertificateSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& headCertificateSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& patchCertificateSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& putCertificateSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& deleteCertificateSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& postCertificateSubOverComputerSystem = privilegeSetConfigureComponents;
+
 // CertificateCollection
 const static auto& getCertificateCollection = privilegeSetConfigureManager;
 const static auto& headCertificateCollection = privilegeSetConfigureManager;
@@ -264,6 +272,14 @@
 const static auto& deleteCertificateCollection = privilegeSetConfigureManager;
 const static auto& postCertificateCollection = privilegeSetConfigureManager;
 
+// Subordinate override for ComputerSystem -> CertificateCollection
+const static auto& getCertificateCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& headCertificateCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& patchCertificateCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& putCertificateCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& deleteCertificateCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& postCertificateCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+
 // CertificateLocations
 const static auto& getCertificateLocations = privilegeSetConfigureManager;
 const static auto& headCertificateLocations = privilegeSetConfigureManager;
@@ -576,6 +592,42 @@
 const static auto& deleteEnvironmentMetrics = privilegeSetConfigureManager;
 const static auto& postEnvironmentMetrics = privilegeSetConfigureManager;
 
+// Subordinate override for Processor -> EnvironmentMetrics
+const static auto& patchEnvironmentMetricsSubOverProcessor = privilegeSetConfigureComponents;
+const static auto& putEnvironmentMetricsSubOverProcessor = privilegeSetConfigureComponents;
+const static auto& deleteEnvironmentMetricsSubOverProcessor = privilegeSetConfigureComponents;
+const static auto& postEnvironmentMetricsSubOverProcessor = privilegeSetConfigureComponents;
+
+// Subordinate override for Memory -> EnvironmentMetrics
+const static auto& patchEnvironmentMetricsSubOverMemory = privilegeSetConfigureComponents;
+const static auto& putEnvironmentMetricsSubOverMemory = privilegeSetConfigureComponents;
+const static auto& deleteEnvironmentMetricsSubOverMemory = privilegeSetConfigureComponents;
+const static auto& postEnvironmentMetricsSubOverMemory = privilegeSetConfigureComponents;
+
+// Subordinate override for Drive -> EnvironmentMetrics
+const static auto& patchEnvironmentMetricsSubOverDrive = privilegeSetConfigureComponents;
+const static auto& putEnvironmentMetricsSubOverDrive = privilegeSetConfigureComponents;
+const static auto& deleteEnvironmentMetricsSubOverDrive = privilegeSetConfigureComponents;
+const static auto& postEnvironmentMetricsSubOverDrive = privilegeSetConfigureComponents;
+
+// Subordinate override for PCIeDevice -> EnvironmentMetrics
+const static auto& patchEnvironmentMetricsSubOverPCIeDevice = privilegeSetConfigureComponents;
+const static auto& putEnvironmentMetricsSubOverPCIeDevice = privilegeSetConfigureComponents;
+const static auto& deleteEnvironmentMetricsSubOverPCIeDevice = privilegeSetConfigureComponents;
+const static auto& postEnvironmentMetricsSubOverPCIeDevice = privilegeSetConfigureComponents;
+
+// Subordinate override for StorageController -> EnvironmentMetrics
+const static auto& patchEnvironmentMetricsSubOverStorageController = privilegeSetConfigureComponents;
+const static auto& putEnvironmentMetricsSubOverStorageController = privilegeSetConfigureComponents;
+const static auto& deleteEnvironmentMetricsSubOverStorageController = privilegeSetConfigureComponents;
+const static auto& postEnvironmentMetricsSubOverStorageController = privilegeSetConfigureComponents;
+
+// Subordinate override for Port -> EnvironmentMetrics
+const static auto& patchEnvironmentMetricsSubOverPort = privilegeSetConfigureComponents;
+const static auto& putEnvironmentMetricsSubOverPort = privilegeSetConfigureComponents;
+const static auto& deleteEnvironmentMetricsSubOverPort = privilegeSetConfigureComponents;
+const static auto& postEnvironmentMetricsSubOverPort = privilegeSetConfigureComponents;
+
 // EthernetInterface
 const static auto& getEthernetInterface = privilegeSetLogin;
 const static auto& headEthernetInterface = privilegeSetLogin;
@@ -584,6 +636,12 @@
 const static auto& putEthernetInterface = privilegeSetConfigureComponents;
 const static auto& deleteEthernetInterface = privilegeSetConfigureComponents;
 
+// Subordinate override for Manager -> EthernetInterfaceCollection -> EthernetInterface
+const static auto& patchEthernetInterfaceSubOverManagerEthernetInterfaceCollection = privilegeSetConfigureManager;
+const static auto& postEthernetInterfaceSubOverManagerEthernetInterfaceCollection = privilegeSetConfigureManager;
+const static auto& putEthernetInterfaceSubOverManagerEthernetInterfaceCollection = privilegeSetConfigureManager;
+const static auto& deleteEthernetInterfaceSubOverManagerEthernetInterfaceCollection = privilegeSetConfigureManager;
+
 // EthernetInterfaceCollection
 const static auto& getEthernetInterfaceCollection = privilegeSetLogin;
 const static auto& headEthernetInterfaceCollection = privilegeSetLogin;
@@ -904,6 +962,20 @@
 const static auto& deleteLogEntry = privilegeSetConfigureManager;
 const static auto& postLogEntry = privilegeSetConfigureManager;
 
+// Subordinate override for ComputerSystem -> LogServiceCollection -> LogService -> LogEntryCollection -> LogEntry
+const static auto& patchLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+const static auto& putLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+const static auto& deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+const static auto& postLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+
+// Subordinate override for Chassis -> LogServiceCollection -> LogService -> LogEntryCollection -> LogEntry
+const static auto& getLogEntrySubOverChassisLogServiceCollectionLogServiceLogEntryCollection = privilegeSetLogin;
+const static auto& headLogEntrySubOverChassisLogServiceCollectionLogServiceLogEntryCollection = privilegeSetLogin;
+const static auto& patchLogEntrySubOverChassisLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+const static auto& putLogEntrySubOverChassisLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+const static auto& deleteLogEntrySubOverChassisLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+const static auto& postLogEntrySubOverChassisLogServiceCollectionLogServiceLogEntryCollection = privilegeSetConfigureComponents;
+
 // LogEntryCollection
 const static auto& getLogEntryCollection = privilegeSetLogin;
 const static auto& headLogEntryCollection = privilegeSetLogin;
@@ -912,6 +984,20 @@
 const static auto& deleteLogEntryCollection = privilegeSetConfigureManager;
 const static auto& postLogEntryCollection = privilegeSetConfigureManager;
 
+// Subordinate override for ComputerSystem -> LogServiceCollection -> LogService -> LogEntryCollection
+const static auto& patchLogEntryCollectionSubOverComputerSystemLogServiceCollectionLogService = privilegeSetConfigureComponents;
+const static auto& putLogEntryCollectionSubOverComputerSystemLogServiceCollectionLogService = privilegeSetConfigureComponents;
+const static auto& deleteLogEntryCollectionSubOverComputerSystemLogServiceCollectionLogService = privilegeSetConfigureComponents;
+const static auto& postLogEntryCollectionSubOverComputerSystemLogServiceCollectionLogService = privilegeSetConfigureComponents;
+
+// Subordinate override for Chassis -> LogServiceCollection -> LogService -> LogEntryCollection
+const static auto& getLogEntryCollectionSubOverChassisLogServiceCollectionLogService = privilegeSetLogin;
+const static auto& headLogEntryCollectionSubOverChassisLogServiceCollectionLogService = privilegeSetLogin;
+const static auto& patchLogEntryCollectionSubOverChassisLogServiceCollectionLogService = privilegeSetConfigureComponents;
+const static auto& putLogEntryCollectionSubOverChassisLogServiceCollectionLogService = privilegeSetConfigureComponents;
+const static auto& deleteLogEntryCollectionSubOverChassisLogServiceCollectionLogService = privilegeSetConfigureComponents;
+const static auto& postLogEntryCollectionSubOverChassisLogServiceCollectionLogService = privilegeSetConfigureComponents;
+
 // LogService
 const static auto& getLogService = privilegeSetLogin;
 const static auto& headLogService = privilegeSetLogin;
@@ -920,6 +1006,20 @@
 const static auto& deleteLogService = privilegeSetConfigureManager;
 const static auto& postLogService = privilegeSetConfigureManager;
 
+// Subordinate override for ComputerSystem -> LogServiceCollection -> LogService
+const static auto& patchLogServiceSubOverComputerSystemLogServiceCollection = privilegeSetConfigureComponents;
+const static auto& postLogServiceSubOverComputerSystemLogServiceCollection = privilegeSetConfigureComponents;
+const static auto& putLogServiceSubOverComputerSystemLogServiceCollection = privilegeSetConfigureComponents;
+const static auto& deleteLogServiceSubOverComputerSystemLogServiceCollection = privilegeSetConfigureComponents;
+
+// Subordinate override for Chassis -> LogServiceCollection -> LogService
+const static auto& getLogServiceSubOverChassisLogServiceCollection = privilegeSetLogin;
+const static auto& headLogServiceSubOverChassisLogServiceCollection = privilegeSetLogin;
+const static auto& patchLogServiceSubOverChassisLogServiceCollection = privilegeSetConfigureComponents;
+const static auto& putLogServiceSubOverChassisLogServiceCollection = privilegeSetConfigureComponents;
+const static auto& deleteLogServiceSubOverChassisLogServiceCollection = privilegeSetConfigureComponents;
+const static auto& postLogServiceSubOverChassisLogServiceCollection = privilegeSetConfigureComponents;
+
 // LogServiceCollection
 const static auto& getLogServiceCollection = privilegeSetLogin;
 const static auto& headLogServiceCollection = privilegeSetLogin;
@@ -928,6 +1028,20 @@
 const static auto& deleteLogServiceCollection = privilegeSetConfigureManager;
 const static auto& postLogServiceCollection = privilegeSetConfigureManager;
 
+// Subordinate override for ComputerSystem -> LogServiceCollection
+const static auto& patchLogServiceCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& putLogServiceCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& deleteLogServiceCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+const static auto& postLogServiceCollectionSubOverComputerSystem = privilegeSetConfigureComponents;
+
+// Subordinate override for Chassis -> LogServiceCollection
+const static auto& getLogServiceCollectionSubOverChassis = privilegeSetLogin;
+const static auto& headLogServiceCollectionSubOverChassis = privilegeSetLogin;
+const static auto& patchLogServiceCollectionSubOverChassis = privilegeSetConfigureComponents;
+const static auto& putLogServiceCollectionSubOverChassis = privilegeSetConfigureComponents;
+const static auto& deleteLogServiceCollectionSubOverChassis = privilegeSetConfigureComponents;
+const static auto& postLogServiceCollectionSubOverChassis = privilegeSetConfigureComponents;
+
 // Manager
 const static auto& getManager = privilegeSetLogin;
 const static auto& headManager = privilegeSetLogin;
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index e951263..d960aad 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -1344,7 +1344,8 @@
     BMCWEB_ROUTE(
         app,
         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
-        .privileges({{"ConfigureComponents"}})
+        .privileges(redfish::privileges::
+                        postLogServiceSubOverComputerSystemLogServiceCollection)
         .methods(boost::beast::http::verb::post)(std::bind_front(
             handleSystemsLogServicesEventLogActionsClearPost, std::ref(app)));
 }
@@ -1927,8 +1928,9 @@
 
     BMCWEB_ROUTE(
         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
-        .privileges(redfish::privileges::deleteLogEntry)
-
+        .privileges(
+            redfish::privileges::
+                deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection)
         .methods(boost::beast::http::verb::delete_)(
             [&app](const crow::Request& req,
                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -2554,7 +2556,8 @@
     BMCWEB_ROUTE(
         app,
         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
-        .privileges(redfish::privileges::postLogService)
+        .privileges(redfish::privileges::
+                        postLogServiceSubOverComputerSystemLogServiceCollection)
         .methods(boost::beast::http::verb::post)(std::bind_front(
             handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
             std::ref(app)));
@@ -2565,7 +2568,8 @@
     BMCWEB_ROUTE(
         app,
         "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
-        .privileges(redfish::privileges::postLogService)
+        .privileges(redfish::privileges::
+                        postLogServiceSubOverComputerSystemLogServiceCollection)
         .methods(boost::beast::http::verb::post)(std::bind_front(
             handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
 }
@@ -3167,7 +3171,8 @@
     BMCWEB_ROUTE(
         app,
         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
-        .privileges(redfish::privileges::postLogService)
+        .privileges(redfish::privileges::
+                        postLogServiceSubOverComputerSystemLogServiceCollection)
         .methods(boost::beast::http::verb::post)(
             [&app](const crow::Request& req,
                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
diff --git a/redfish-core/lib/systems_logservices_postcodes.hpp b/redfish-core/lib/systems_logservices_postcodes.hpp
index cd2cb8c..12f31d9 100644
--- a/redfish-core/lib/systems_logservices_postcodes.hpp
+++ b/redfish-core/lib/systems_logservices_postcodes.hpp
@@ -623,9 +623,8 @@
     BMCWEB_ROUTE(
         app,
         "/redfish/v1/Systems/<str>/LogServices/PostCodes/Actions/LogService.ClearLog/")
-        // The following privilege is correct; we need "SubordinateOverrides"
-        // before we can automate it.
-        .privileges({{"ConfigureComponents"}})
+        .privileges(redfish::privileges::
+                        postLogServiceSubOverComputerSystemLogServiceCollection)
         .methods(boost::beast::http::verb::post)(std::bind_front(
             handleSystemsLogServicesPostCodesPost, std::ref(app)));
 
diff --git a/scripts/parse_registries.py b/scripts/parse_registries.py
index 041b86e..747aac1 100755
--- a/scripts/parse_registries.py
+++ b/scripts/parse_registries.py
@@ -615,6 +615,17 @@
                     privilege_list,
                     None,
                 )
+            if "SubordinateOverrides" in mapping:
+                for subordinateOverride in mapping["SubordinateOverrides"]:
+                    for operation, privilege_list in subordinateOverride[
+                        "OperationMap"
+                    ].items():
+                        privilege_dict[
+                            get_privilege_string_from_list(privilege_list)
+                        ] = (
+                            privilege_list,
+                            None,
+                        )
         for index, key in enumerate(privilege_dict):
             (privilege_list, _) = privilege_dict[key]
             name = get_variable_name_for_privilege_set(privilege_list)
@@ -641,6 +652,32 @@
                     )
                 )
             registry.write("\n")
+            if "SubordinateOverrides" in mapping:
+                for subordinateOverrides in mapping["SubordinateOverrides"]:
+                    target_list_list = subordinateOverrides["Targets"]
+                    registry.write("// Subordinate override for ")
+                    concateVarName = ""
+                    for target in target_list_list:
+                        registry.write(target + " -> ")
+                        concateVarName += target
+                    registry.write(entity)
+                    registry.write("\n")
+                    for operation, privilege_list in subordinateOverrides[
+                        "OperationMap"
+                    ].items():
+                        privilege_string = get_privilege_string_from_list(
+                            privilege_list
+                        )
+                        operation = operation.lower()
+                        registry.write(
+                            "const static auto& {}{}SubOver{} = privilegeSet{};\n".format(
+                                operation,
+                                entity,
+                                concateVarName,
+                                privilege_dict[privilege_string][1],
+                            )
+                        )
+                    registry.write("\n")
         registry.write(
             "} // namespace redfish::privileges\n// clang-format on\n"
         )