diff options
author | CoprDistGit <infra@openeuler.org> | 2023-05-10 05:44:19 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-05-10 05:44:19 +0000 |
commit | f1f2c4767b392d3df24c511ae90f186bcec8f43a (patch) | |
tree | a843978df87e6726089af379fd122509f3732bd5 | |
parent | 3dda19d3f55022e309d29b6d0a48bc9a076075c1 (diff) |
automatic import of python-github-terraform-importopeneuler20.03
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-github-terraform-import.spec | 697 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 699 insertions, 0 deletions
@@ -0,0 +1 @@ +/github_terraform_import-0.0.1.tar.gz diff --git a/python-github-terraform-import.spec b/python-github-terraform-import.spec new file mode 100644 index 0000000..cbc887d --- /dev/null +++ b/python-github-terraform-import.spec @@ -0,0 +1,697 @@ +%global _empty_manifest_terminate_build 0 +Name: python-github-terraform-import +Version: 0.0.1 +Release: 1 +Summary: Import or sync existing Github infrastructure into terraform +License: MIT +URL: https://github.com/BraeWebb/github-terraform-import +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/ca/e3/8a94403201cd18b248dc33a06eacaa2af4844ce0f1cb13c475e8f3b484e1/github_terraform_import-0.0.1.tar.gz +BuildArch: noarch + +Requires: python3-requests + +%description +# Github Terraform Import + +Python library to allow simple programmatic control of importing a Github organization as terraform resources. + +The library exposes four key components: +* Dataclass definitions of all terraform resources in the Github Provider (`github_terraform_import.formatter.github_types.*`) +* Formatter to easily convert dataclass types into valid terraform configuration syntax (`github_terraform_import.formatter.Formatter`) +* A metaclass required to implement a visitor pattern for all resources ([`github_terraform_import.visitor.VisitMethodInjector`](#visitmethodinjector)) +* An interface with the Github REST API that will dynamically load Github resources based on methods defined in the given visitor class `github_terraform_import.provider.GithubProvider` + + +## Usage +Create a file for each repository which contains the following repository specific resources `github_repository`, `github_repository_collaborator`, `github_team_repository`. + +```python +import os +import sys + +from github_terraform_import.visitor import VisitMethodInjector +from github_terraform_import.github_types import ( + GithubRepository, + GithubRepositoryCollaborator, + GithubTeamRepository, +) +from github_terraform_import.provider import GithubProvider +from github_terraform_import.formatter import Formatter + + +class RepositoryConfigurationGenerator(metaclass=VisitMethodInjector): + def __init__(self, path): + self._root = path + + def visit_github_repository(self, repository: GithubRepository): + file_ = os.path.join(self._root, f"{repository.name}.tf") + with open(file_, "a+") as f: + Formatter.format(repository.name, repository, out=f) + + def visit_github_repository_collaborator( + self, collaborator: GithubRepositoryCollaborator + ): + file_ = os.path.join(self._root, f"{collaborator.repository}.tf") + with open(file_, "a+") as f: + Formatter.format(collaborator.username, collaborator, out=f) + + def visit_github_team_repository(self, team: GithubTeamRepository): + file_ = os.path.join(self._root, f"{team.repository}.tf") + with open(file_, "a+") as f: + Formatter.format(team.team_id, team, out=f) + + +def main(): + if len(sys.argv) < 4: + print("Usage: example {token} {organization} {output_directory}") + exit() + + directory = sys.argv[3] + if not os.path.exists(directory): + os.makedirs(directory) + + generator = RepositoryConfigurationGenerator(directory) + provider = GithubProvider(sys.argv[1], sys.argv[2]) + provider.visit(generator) + + +if __name__ == "__main__": + main() +``` + +## Features +* Wrap around the Github API to provide terraform resources +* Typed resources for each of the terraform resources +* Dynamic resource fetching based on declared visitor methods +* Automatic caching of resources on multiple runs +* Formatting of resource classes to terraform configuration +* Detectable missing visitor methods + + +## Supported Resources +| Resource | Supported | Notes | +| - | - | - | +| github_actions_secret | :heavy_check_mark: | `plaintext_value` value cannot be imported from Github API, this must be added manually. Defaults to 'WARNING: Secrets cannot be imported via Github API' | +| github_branch | | +| github_branch_protection | :heavy_check_mark: | +| github_issue_label | :heavy_check_mark: | +| github_membership | :heavy_check_mark: | +| github_organization_block | :heavy_check_mark: | +| github_organization_project | :heavy_check_mark: | +| github_organization_webhook | :heavy_check_mark: | +| github_project_column | :heavy_check_mark: | +| github_repository | :heavy_check_mark: | `delete_branch_on_merge`, `auto_init`, `gitignore_template`, `license_template` are not provided by the API | +| github_repository_collaborator | :heavy_check_mark: | +| github_repository_deploy_key | :heavy_check_mark: | +| github_repository_file | | +| github_repository_project | :heavy_check_mark: | +| github_repository_webhook | :heavy_check_mark: | +| github_team | :heavy_check_mark: | `ldap_dn` not provided by the API | +| github_team_membership | :heavy_check_mark: | +| github_team_repository | :heavy_check_mark: | +| github_user_gpg_key | | +| github_user_invitation_accepter | | +| github_user_ssh_key | | + + +## VisitMethodInjector +Use the `VisitMethodInjector` metaclass in your customised visitor class to provide instructions for handling various fetched resources. + +### Standard Use +The standard use case for your visitor class is to define a method for each of the resources you wish to import. For example if you wish to import all the repository webhooks, a class like `FetchRepositoryWebhooks` would suffice. + +```python +class FetchRepositoryWebhooks(metaclass=VisitMethodInjector): + def visit_github_repository_webhook(self, webhook: GithubRepositoryWebhook): + pass +``` + +Visit methods must be named, as `visit_{resource_name}`. + +### Default Method +If there is some method that should be run for every resource without an implemented visitor method, you can use the default method for this purpose. + +```python +class FetchWithDefault(metaclass=VisitMethodInjector): + def visit_github_repository_webhook(self, webhook: GithubRepositoryWebhook): + pass + + def default(self, resource: Resource): + print(resource) +``` + +`FetchWithDefault` will call default for all of the resources except `github_repository_webhook`. + +### Validation +If you want to ensure that every resource has an implemented visitor method, then setting the class variable `ignore_missing` to `False` will cause a `TypeError` to be thrown if there are any missing visitor methods. + +```python +class FetchWithValidation(metaclass=VisitMethodInjector): + ignore_missing = False +``` + +`FetchWithValidation` will throw a type exception when constructed listing all of the missing visit methods. + + +## Formatter +The `Formatter` class provides a way of converting the supplied dataclasses for each resource into an appropriately formatted Terraform resource. + +This is accomplished by calling the `Formatter.format` method. The method can also be used for any custom dataclasses so long as they inherit from `github_terraform_import.github_types.Resource`. + +Any member variables starting with an underscore, conventionally private, are not generated in the resource. + +```python +@dataclass +class NestedDetails(Block): + description: str + topics: List[str] + +@dataclass +class MyTerraformResource(Resource): + name: str + id: int + valid: bool + + friends: List[str] + + details: NestedDetails +``` + +The above `MyTerraformResource` is an example dataclass definition which showcases the various supported types of the formatter. + +Executing the following will write the resource to `out.txt` +```python +details = NestedDetails( + description="Things I like", + topics=["verification", "optimisation"], +) + +resource = MyTerraformResource( + name="a special resource", + id="special", + valid=True, + friends=[], + details=details, +) + + +with open("out.txt", "w") as file: + Formatter.format("my_resource_name", resource, out=file) +``` + +The contents of out should then be: +``` +resource "my_terraform_resource" "my_resource_name" { + name = "a special resource" + id = special + valid = true + friends = [] + details { + description = "Things I like" + topics = [ + "verification" + "optimisation" + ] + } +} +``` + +If the `out` keyword argument is omitted from the `Formatter.format` method then the resource will be printed to standard out. + + + + +%package -n python3-github-terraform-import +Summary: Import or sync existing Github infrastructure into terraform +Provides: python-github-terraform-import +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-github-terraform-import +# Github Terraform Import + +Python library to allow simple programmatic control of importing a Github organization as terraform resources. + +The library exposes four key components: +* Dataclass definitions of all terraform resources in the Github Provider (`github_terraform_import.formatter.github_types.*`) +* Formatter to easily convert dataclass types into valid terraform configuration syntax (`github_terraform_import.formatter.Formatter`) +* A metaclass required to implement a visitor pattern for all resources ([`github_terraform_import.visitor.VisitMethodInjector`](#visitmethodinjector)) +* An interface with the Github REST API that will dynamically load Github resources based on methods defined in the given visitor class `github_terraform_import.provider.GithubProvider` + + +## Usage +Create a file for each repository which contains the following repository specific resources `github_repository`, `github_repository_collaborator`, `github_team_repository`. + +```python +import os +import sys + +from github_terraform_import.visitor import VisitMethodInjector +from github_terraform_import.github_types import ( + GithubRepository, + GithubRepositoryCollaborator, + GithubTeamRepository, +) +from github_terraform_import.provider import GithubProvider +from github_terraform_import.formatter import Formatter + + +class RepositoryConfigurationGenerator(metaclass=VisitMethodInjector): + def __init__(self, path): + self._root = path + + def visit_github_repository(self, repository: GithubRepository): + file_ = os.path.join(self._root, f"{repository.name}.tf") + with open(file_, "a+") as f: + Formatter.format(repository.name, repository, out=f) + + def visit_github_repository_collaborator( + self, collaborator: GithubRepositoryCollaborator + ): + file_ = os.path.join(self._root, f"{collaborator.repository}.tf") + with open(file_, "a+") as f: + Formatter.format(collaborator.username, collaborator, out=f) + + def visit_github_team_repository(self, team: GithubTeamRepository): + file_ = os.path.join(self._root, f"{team.repository}.tf") + with open(file_, "a+") as f: + Formatter.format(team.team_id, team, out=f) + + +def main(): + if len(sys.argv) < 4: + print("Usage: example {token} {organization} {output_directory}") + exit() + + directory = sys.argv[3] + if not os.path.exists(directory): + os.makedirs(directory) + + generator = RepositoryConfigurationGenerator(directory) + provider = GithubProvider(sys.argv[1], sys.argv[2]) + provider.visit(generator) + + +if __name__ == "__main__": + main() +``` + +## Features +* Wrap around the Github API to provide terraform resources +* Typed resources for each of the terraform resources +* Dynamic resource fetching based on declared visitor methods +* Automatic caching of resources on multiple runs +* Formatting of resource classes to terraform configuration +* Detectable missing visitor methods + + +## Supported Resources +| Resource | Supported | Notes | +| - | - | - | +| github_actions_secret | :heavy_check_mark: | `plaintext_value` value cannot be imported from Github API, this must be added manually. Defaults to 'WARNING: Secrets cannot be imported via Github API' | +| github_branch | | +| github_branch_protection | :heavy_check_mark: | +| github_issue_label | :heavy_check_mark: | +| github_membership | :heavy_check_mark: | +| github_organization_block | :heavy_check_mark: | +| github_organization_project | :heavy_check_mark: | +| github_organization_webhook | :heavy_check_mark: | +| github_project_column | :heavy_check_mark: | +| github_repository | :heavy_check_mark: | `delete_branch_on_merge`, `auto_init`, `gitignore_template`, `license_template` are not provided by the API | +| github_repository_collaborator | :heavy_check_mark: | +| github_repository_deploy_key | :heavy_check_mark: | +| github_repository_file | | +| github_repository_project | :heavy_check_mark: | +| github_repository_webhook | :heavy_check_mark: | +| github_team | :heavy_check_mark: | `ldap_dn` not provided by the API | +| github_team_membership | :heavy_check_mark: | +| github_team_repository | :heavy_check_mark: | +| github_user_gpg_key | | +| github_user_invitation_accepter | | +| github_user_ssh_key | | + + +## VisitMethodInjector +Use the `VisitMethodInjector` metaclass in your customised visitor class to provide instructions for handling various fetched resources. + +### Standard Use +The standard use case for your visitor class is to define a method for each of the resources you wish to import. For example if you wish to import all the repository webhooks, a class like `FetchRepositoryWebhooks` would suffice. + +```python +class FetchRepositoryWebhooks(metaclass=VisitMethodInjector): + def visit_github_repository_webhook(self, webhook: GithubRepositoryWebhook): + pass +``` + +Visit methods must be named, as `visit_{resource_name}`. + +### Default Method +If there is some method that should be run for every resource without an implemented visitor method, you can use the default method for this purpose. + +```python +class FetchWithDefault(metaclass=VisitMethodInjector): + def visit_github_repository_webhook(self, webhook: GithubRepositoryWebhook): + pass + + def default(self, resource: Resource): + print(resource) +``` + +`FetchWithDefault` will call default for all of the resources except `github_repository_webhook`. + +### Validation +If you want to ensure that every resource has an implemented visitor method, then setting the class variable `ignore_missing` to `False` will cause a `TypeError` to be thrown if there are any missing visitor methods. + +```python +class FetchWithValidation(metaclass=VisitMethodInjector): + ignore_missing = False +``` + +`FetchWithValidation` will throw a type exception when constructed listing all of the missing visit methods. + + +## Formatter +The `Formatter` class provides a way of converting the supplied dataclasses for each resource into an appropriately formatted Terraform resource. + +This is accomplished by calling the `Formatter.format` method. The method can also be used for any custom dataclasses so long as they inherit from `github_terraform_import.github_types.Resource`. + +Any member variables starting with an underscore, conventionally private, are not generated in the resource. + +```python +@dataclass +class NestedDetails(Block): + description: str + topics: List[str] + +@dataclass +class MyTerraformResource(Resource): + name: str + id: int + valid: bool + + friends: List[str] + + details: NestedDetails +``` + +The above `MyTerraformResource` is an example dataclass definition which showcases the various supported types of the formatter. + +Executing the following will write the resource to `out.txt` +```python +details = NestedDetails( + description="Things I like", + topics=["verification", "optimisation"], +) + +resource = MyTerraformResource( + name="a special resource", + id="special", + valid=True, + friends=[], + details=details, +) + + +with open("out.txt", "w") as file: + Formatter.format("my_resource_name", resource, out=file) +``` + +The contents of out should then be: +``` +resource "my_terraform_resource" "my_resource_name" { + name = "a special resource" + id = special + valid = true + friends = [] + details { + description = "Things I like" + topics = [ + "verification" + "optimisation" + ] + } +} +``` + +If the `out` keyword argument is omitted from the `Formatter.format` method then the resource will be printed to standard out. + + + + +%package help +Summary: Development documents and examples for github-terraform-import +Provides: python3-github-terraform-import-doc +%description help +# Github Terraform Import + +Python library to allow simple programmatic control of importing a Github organization as terraform resources. + +The library exposes four key components: +* Dataclass definitions of all terraform resources in the Github Provider (`github_terraform_import.formatter.github_types.*`) +* Formatter to easily convert dataclass types into valid terraform configuration syntax (`github_terraform_import.formatter.Formatter`) +* A metaclass required to implement a visitor pattern for all resources ([`github_terraform_import.visitor.VisitMethodInjector`](#visitmethodinjector)) +* An interface with the Github REST API that will dynamically load Github resources based on methods defined in the given visitor class `github_terraform_import.provider.GithubProvider` + + +## Usage +Create a file for each repository which contains the following repository specific resources `github_repository`, `github_repository_collaborator`, `github_team_repository`. + +```python +import os +import sys + +from github_terraform_import.visitor import VisitMethodInjector +from github_terraform_import.github_types import ( + GithubRepository, + GithubRepositoryCollaborator, + GithubTeamRepository, +) +from github_terraform_import.provider import GithubProvider +from github_terraform_import.formatter import Formatter + + +class RepositoryConfigurationGenerator(metaclass=VisitMethodInjector): + def __init__(self, path): + self._root = path + + def visit_github_repository(self, repository: GithubRepository): + file_ = os.path.join(self._root, f"{repository.name}.tf") + with open(file_, "a+") as f: + Formatter.format(repository.name, repository, out=f) + + def visit_github_repository_collaborator( + self, collaborator: GithubRepositoryCollaborator + ): + file_ = os.path.join(self._root, f"{collaborator.repository}.tf") + with open(file_, "a+") as f: + Formatter.format(collaborator.username, collaborator, out=f) + + def visit_github_team_repository(self, team: GithubTeamRepository): + file_ = os.path.join(self._root, f"{team.repository}.tf") + with open(file_, "a+") as f: + Formatter.format(team.team_id, team, out=f) + + +def main(): + if len(sys.argv) < 4: + print("Usage: example {token} {organization} {output_directory}") + exit() + + directory = sys.argv[3] + if not os.path.exists(directory): + os.makedirs(directory) + + generator = RepositoryConfigurationGenerator(directory) + provider = GithubProvider(sys.argv[1], sys.argv[2]) + provider.visit(generator) + + +if __name__ == "__main__": + main() +``` + +## Features +* Wrap around the Github API to provide terraform resources +* Typed resources for each of the terraform resources +* Dynamic resource fetching based on declared visitor methods +* Automatic caching of resources on multiple runs +* Formatting of resource classes to terraform configuration +* Detectable missing visitor methods + + +## Supported Resources +| Resource | Supported | Notes | +| - | - | - | +| github_actions_secret | :heavy_check_mark: | `plaintext_value` value cannot be imported from Github API, this must be added manually. Defaults to 'WARNING: Secrets cannot be imported via Github API' | +| github_branch | | +| github_branch_protection | :heavy_check_mark: | +| github_issue_label | :heavy_check_mark: | +| github_membership | :heavy_check_mark: | +| github_organization_block | :heavy_check_mark: | +| github_organization_project | :heavy_check_mark: | +| github_organization_webhook | :heavy_check_mark: | +| github_project_column | :heavy_check_mark: | +| github_repository | :heavy_check_mark: | `delete_branch_on_merge`, `auto_init`, `gitignore_template`, `license_template` are not provided by the API | +| github_repository_collaborator | :heavy_check_mark: | +| github_repository_deploy_key | :heavy_check_mark: | +| github_repository_file | | +| github_repository_project | :heavy_check_mark: | +| github_repository_webhook | :heavy_check_mark: | +| github_team | :heavy_check_mark: | `ldap_dn` not provided by the API | +| github_team_membership | :heavy_check_mark: | +| github_team_repository | :heavy_check_mark: | +| github_user_gpg_key | | +| github_user_invitation_accepter | | +| github_user_ssh_key | | + + +## VisitMethodInjector +Use the `VisitMethodInjector` metaclass in your customised visitor class to provide instructions for handling various fetched resources. + +### Standard Use +The standard use case for your visitor class is to define a method for each of the resources you wish to import. For example if you wish to import all the repository webhooks, a class like `FetchRepositoryWebhooks` would suffice. + +```python +class FetchRepositoryWebhooks(metaclass=VisitMethodInjector): + def visit_github_repository_webhook(self, webhook: GithubRepositoryWebhook): + pass +``` + +Visit methods must be named, as `visit_{resource_name}`. + +### Default Method +If there is some method that should be run for every resource without an implemented visitor method, you can use the default method for this purpose. + +```python +class FetchWithDefault(metaclass=VisitMethodInjector): + def visit_github_repository_webhook(self, webhook: GithubRepositoryWebhook): + pass + + def default(self, resource: Resource): + print(resource) +``` + +`FetchWithDefault` will call default for all of the resources except `github_repository_webhook`. + +### Validation +If you want to ensure that every resource has an implemented visitor method, then setting the class variable `ignore_missing` to `False` will cause a `TypeError` to be thrown if there are any missing visitor methods. + +```python +class FetchWithValidation(metaclass=VisitMethodInjector): + ignore_missing = False +``` + +`FetchWithValidation` will throw a type exception when constructed listing all of the missing visit methods. + + +## Formatter +The `Formatter` class provides a way of converting the supplied dataclasses for each resource into an appropriately formatted Terraform resource. + +This is accomplished by calling the `Formatter.format` method. The method can also be used for any custom dataclasses so long as they inherit from `github_terraform_import.github_types.Resource`. + +Any member variables starting with an underscore, conventionally private, are not generated in the resource. + +```python +@dataclass +class NestedDetails(Block): + description: str + topics: List[str] + +@dataclass +class MyTerraformResource(Resource): + name: str + id: int + valid: bool + + friends: List[str] + + details: NestedDetails +``` + +The above `MyTerraformResource` is an example dataclass definition which showcases the various supported types of the formatter. + +Executing the following will write the resource to `out.txt` +```python +details = NestedDetails( + description="Things I like", + topics=["verification", "optimisation"], +) + +resource = MyTerraformResource( + name="a special resource", + id="special", + valid=True, + friends=[], + details=details, +) + + +with open("out.txt", "w") as file: + Formatter.format("my_resource_name", resource, out=file) +``` + +The contents of out should then be: +``` +resource "my_terraform_resource" "my_resource_name" { + name = "a special resource" + id = special + valid = true + friends = [] + details { + description = "Things I like" + topics = [ + "verification" + "optimisation" + ] + } +} +``` + +If the `out` keyword argument is omitted from the `Formatter.format` method then the resource will be printed to standard out. + + + + +%prep +%autosetup -n github-terraform-import-0.0.1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-github-terraform-import -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Wed May 10 2023 Python_Bot <Python_Bot@openeuler.org> - 0.0.1-1 +- Package Spec generated @@ -0,0 +1 @@ +841c9e7e9b5d43e5f6437157d90b201b github_terraform_import-0.0.1.tar.gz |