How can I version control a mirrored upstream repository?
Michael Hampton referenced an answer that names Katello and Spacewalk, Satellite is the product RedHat offers to accomplish that.
Katello is to Satellite what Fedora is to RedHat (according to this)
Lifecycle environments and content views are what you are looking for in Katello:
Promoting a Content View
Initially a Content View is published to Library as version 1. If there are Content Hosts in other environments that would like to consume this Content View, a version of the content view will need to be promoted to those environments. For example, given the Content View “New Content View”, version 1 of which has been promoted to the Dev environment. Any Content Hosts in Dev attached to the Content View would remain at version 1 until a version 2 is both published and promoted to the Dev environment.
Content view sample http://www.katello.org/docs/2.3/user_guide/content_views/promote_content_view2.png
Content view promoting progress http://www.katello.org/docs/2.3/user_guide/content_views/promote_content_view3.png
To expand on fuero's answer, we use RedHat Satellite to achieve this. Satellite is a combination of the open source tools Foreman and Katello. Specifically the Katello aspect is what provides this "Lifecycle Management".
In Katello, you define upstream repositories to synchronize from: either yum repos, puppet forges, git servers, etc. You then sync the content into the Library, and "promote" it through various environments. A common example would be "Library -> Dev -> Test -> Production".
There was a good talk at one of the Puppet conferences a while ago where some of the developers gave a demo of Katello/Foreman. Link on YouTube.
One thing to note: we're currently trying to solve the problem of binary distribution and tracking, which Katello doesn't solve. What I mean by that is that we have a set of Puppet modules and associated RPMs/binaries, but Katello provides no way to "snapshot" that for export to a different system. Katello will keep a static "view" of these things, but there's no way to confirm what's in that view - I can't say to the customer that they have "version X" of the system, nor can I confirm that the view they're using is exactly the same as mine. It all depends when they synchronized and what was in the repos at the time.
We're considering tools such as Nexus/Artifactory to provide this functionality at the moment, so you may want to have a look at those too.