propose features upstream #2

Merged
techknowlogick merged 1 commits from lerentis/terraform-provider-gitea:feature/tt/upstream-merge into main 2022-08-22 15:54:14 +00:00
27 changed files with 2375 additions and 5 deletions

View File

@ -3,6 +3,8 @@ GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
GOFMT ?= gofmt -s
VERSION = 0.6.1
test: fmt-check
go test -i $(TEST) || exit 1
echo $(TEST) | \
@ -28,3 +30,12 @@ fmt-check:
echo "$${diff}"; \
exit 1; \
fi;
build:
go build -o terraform-provider-gitea_${VERSION}
install: build
@echo installing to
@echo ~/.terraform.d/plugins/terraform.local/local/gitea/${VERSION}/linux_amd64/terraform-provider-gitea_${VERSION}
@mkdir -p ~/.terraform.d/plugins/terraform.local/local/gitea/${VERSION}/linux_amd64
@mv terraform-provider-gitea_${VERSION} ~/.terraform.d/plugins/terraform.local/local/gitea/${VERSION}/linux_amd64/terraform-provider-gitea_${VERSION}
doc:
tfplugindocs

32
docs/data-sources/org.md Normal file
View File

@ -0,0 +1,32 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_org Data Source - terraform-provider-gitea"
subcategory: ""
description: |-
---
# gitea_org (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- `name` (String)
### Read-Only
- `avatar_url` (String)
- `description` (String)
- `full_name` (String)
- `id` (Number) The ID of this resource.
- `location` (String)
- `visibility` (String)
- `website` (String)

47
docs/data-sources/repo.md Normal file
View File

@ -0,0 +1,47 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_repo Data Source - terraform-provider-gitea"
subcategory: ""
description: |-
---
# gitea_repo (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String)
- `username` (String)
### Read-Only
- `clone_url` (String)
- `created` (String)
- `default_branch` (String)
- `description` (String)
- `fork` (Boolean)
- `forks` (Number)
- `full_name` (String)
- `html_url` (String)
- `id` (String) The ID of this resource.
- `mirror` (Boolean)
- `open_issue_count` (Number)
- `permission_admin` (Boolean)
- `permission_pull` (Boolean)
- `permission_push` (Boolean)
- `private` (Boolean)
- `size` (Number)
- `ssh_url` (String)
- `stars` (Number)
- `updated` (String)
- `watchers` (Number)
- `website` (String)

33
docs/data-sources/user.md Normal file
View File

@ -0,0 +1,33 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_user Data Source - terraform-provider-gitea"
subcategory: ""
description: |-
---
# gitea_user (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- `username` (String)
### Read-Only
- `avatar_url` (String)
- `created` (String)
- `email` (String)
- `full_name` (String)
- `id` (Number) The ID of this resource.
- `is_admin` (Boolean)
- `language` (String)
- `last_login` (String)

52
docs/index.md Normal file
View File

@ -0,0 +1,52 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea Provider"
subcategory: ""
description: |-
---
# gitea Provider
## Example Usage
```terraform
terraform {
required_providers {
gitea = {
source = "gitea/gitea"
version = "0.6.1"
}
}
}
provider "gitea" {
base_url = var.gitea_url # optionally use GITEA_BASE_URL env var
token = var.gitea_token # optionally use GITEA_TOKEN env var
# Username/Password authentication is mutally exclusive with token authentication
# username = var.username # optionally use GITEA_USERNAME env var
# password = var.password # optionally use GITEA_PASSWORD env var
# A file containing the ca certificate to use in case ssl certificate is not from a standard chain
cacert_file = var.cacert_file
# If you are running a gitea instance with self signed TLS certificates
# and you want to disable certificate validation you can deactivate it with this flag
insecure = false
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- `base_url` (String) The Gitea Base API URL
- `cacert_file` (String) A file containing the ca certificate to use in case ssl certificate is not from a standard chain
- `insecure` (Boolean) Disable SSL verification of API calls
- `password` (String) Password in case of using basic auth
- `token` (String) The application token used to connect to Gitea.
- `username` (String) Username in case of using basic auth

View File

@ -0,0 +1,29 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_oauth2_app Resource - terraform-provider-gitea"
subcategory: ""
description: |-
Handling gitea oauth application https://docs.gitea.io/en-us/oauth2-provider/ resources
---
# gitea_oauth2_app (Resource)
Handling [gitea oauth application](https://docs.gitea.io/en-us/oauth2-provider/) resources
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) OAuth Application name
- `redirect_uris` (Set of String) Accepted redirect URIs
### Read-Only
- `client_id` (String) OAuth2 Application client id
- `client_secret` (String, Sensitive) Oauth2 Application client secret
- `id` (String) The ID of this resource.

50
docs/resources/org.md Normal file
View File

@ -0,0 +1,50 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_org Resource - terraform-provider-gitea"
subcategory: ""
description: |-
gitea_org manages a gitea organisation.
Organisations are a way to group repositories and abstract permission management in a gitea instance.
---
# gitea_org (Resource)
`gitea_org` manages a gitea organisation.
Organisations are a way to group repositories and abstract permission management in a gitea instance.
## Example Usage
```terraform
resource "gitea_org" "test_org" {
name = "test-org"
}
resource "gitea_repository" "org_repo" {
username = gitea_org.test_org.name
name = "org-test-repo"
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) The name of the organisation without spaces.
### Optional
- `description` (String) A description of this organisation.
- `full_name` (String) The display name of the organisation. Defaults to the value of `name`.
- `location` (String)
- `repo_admin_change_team_access` (Boolean)
- `visibility` (String) Flag is this organisation should be publicly visible or not.
- `website` (String) A link to a website with more information about this organisation.
### Read-Only
- `avatar_url` (String)
- `id` (String) The ID of this resource.

View File

@ -0,0 +1,52 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_public_key Resource - terraform-provider-gitea"
subcategory: ""
description: |-
gitea_public_key manages ssh key that are associated with users.
---
# gitea_public_key (Resource)
`gitea_public_key` manages ssh key that are associated with users.
## Example Usage
```terraform
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
}
resource "gitea_public_key" "test_user_key" {
title = "test"
key = file("${path.module}/id_ed25519.pub")
username = gitea_user.test.username
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `key` (String, Sensitive) An armored SSH key to add
- `title` (String) Title of the key to add
- `username` (String) User to associate with the added key
### Optional
- `read_only` (Boolean) Describe if the key has only read access or read/write
### Read-Only
- `created` (String)
- `fingerprint` (String)
- `id` (String) The ID of this resource.
- `type` (String)

View File

@ -0,0 +1,109 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_repository Resource - terraform-provider-gitea"
subcategory: ""
description: |-
gitea_repository manages a gitea repository.
Per default this repository will be initializiled with the provided configuration (gitignore, License etc.).
If the username property is set to a organisation name, the provider will try to look if this organisation exists and create the repository under the organisation scope.
Repository migrations have some properties that are not available to regular repositories. These are all prefixed with migration_.
---
# gitea_repository (Resource)
`gitea_repository` manages a gitea repository.
Per default this repository will be initializiled with the provided configuration (gitignore, License etc.).
If the `username` property is set to a organisation name, the provider will try to look if this organisation exists and create the repository under the organisation scope.
Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`.
## Example Usage
```terraform
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
}
resource "gitea_repository" "test" {
username = resource.gitea_user.test.name
name = "test"
private = true
issue_labels = "Default"
license = "MIT"
gitignores = "Go"
}
resource "gitea_repository" "mirror" {
username = resource.gitea_user.test.name
name = "terraform-provider-gitea-mirror"
description = "Mirror of Terraform Provider"
mirror = true
migration_clone_addresse = "https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git"
migration_service = "gitea"
migration_service_auth_token = var.gitea_mirror_token
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) The Name of the repository
- `username` (String) The Owner of the repository
### Optional
- `allow_manual_merge` (Boolean)
- `allow_merge_commits` (Boolean)
- `allow_rebase` (Boolean)
- `allow_rebase_explicit` (Boolean)
- `allow_squash_merge` (Boolean)
- `archived` (Boolean)
- `auto_init` (Boolean) Flag if the repository should be initiated with the configured values
- `autodetect_manual_merge` (Boolean)
- `default_branch` (String) The default branch of the repository. Defaults to `main`
- `description` (String) The description of the repository.
- `gitignores` (String) A specific gitignore that should be commited to the repositoryon creation if `auto_init` is set to `true`
Need to exist in the gitea instance
- `has_issues` (Boolean) A flag if the repository should have issue management enabled or not.
- `has_projects` (Boolean) A flag if the repository should have the native project management enabled or not.
- `has_pull_requests` (Boolean) A flag if the repository should acceppt pull requests or not.
- `has_wiki` (Boolean) A flag if the repository should have the native wiki enabled or not.
- `ignore_whitespace_conflicts` (Boolean)
- `issue_labels` (String) The Issue Label configuration to be used in this repository.
Need to exist in the gitea instance
- `license` (String) The license under which the source code of this repository should be.
Need to exist in the gitea instance
- `migration_clone_addresse` (String)
- `migration_issue_labels` (Boolean)
- `migration_lfs` (Boolean)
- `migration_lfs_endpoint` (String)
- `migration_milestones` (Boolean)
- `migration_mirror_interval` (String) valid time units are 'h', 'm', 's'. 0 to disable automatic sync
- `migration_releases` (Boolean)
- `migration_service` (String) git/github/gitlab/gitea/gogs
- `migration_service_auth_password` (String, Sensitive)
- `migration_service_auth_token` (String, Sensitive)
- `migration_service_auth_username` (String)
- `mirror` (Boolean)
- `private` (Boolean) Flag if the repository should be private or not.
- `readme` (String)
- `repo_template` (Boolean)
- `website` (String) A link to a website with more information.
### Read-Only
- `created` (String)
- `id` (String) The ID of this resource.
- `permission_admin` (Boolean)
- `permission_pull` (Boolean)
- `permission_push` (Boolean)
- `updated` (String)

62
docs/resources/team.md Normal file
View File

@ -0,0 +1,62 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_team Resource - terraform-provider-gitea"
subcategory: ""
description: |-
gitea_team manages Team that are part of an organisation.
---
# gitea_team (Resource)
`gitea_team` manages Team that are part of an organisation.
## Example Usage
```terraform
resource "gitea_org" "test_org" {
name = "test-org"
}
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
admin = true
}
resource "gitea_team" "test_team" {
name = "Devs"
organisation = gitea_org.test_org.name
description = "Devs of Test Org"
permission = "write"
members = [gitea_user.test.username]
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `name` (String) Name of the Team
- `organisation` (String) The organisation which this Team is part of.
### Optional
- `can_create_repos` (Boolean) Flag if the Teams members should be able to create Rpositories in the Organisation
- `description` (String) Description of the Team
- `include_all_repositories` (Boolean) Flag if the Teams members should have access to all Repositories in the Organisation
- `members` (List of String) List of Users that should be part of this team
- `permission` (String) Permissions associated with this Team
Can be `none`, `read`, `write`, `admin` or `owner`
- `units` (String) List of types of Repositories that should be allowed to be created from Team members.
Can be `repo.code`, `repo.issues`, `repo.ext_issues`, `repo.wiki`, `repo.pulls`, `repo.releases`, `repo.projects` and/or `repo.ext_wiki`
### Read-Only
- `id` (String) The ID of this resource.

60
docs/resources/user.md Normal file
View File

@ -0,0 +1,60 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "gitea_user Resource - terraform-provider-gitea"
subcategory: ""
description: |-
gitea_user manages a native gitea user.
If you are using OIDC or other kinds of authentication mechanisms you can still try to managessh keys or other ressources this way
---
# gitea_user (Resource)
`gitea_user` manages a native gitea user.
If you are using OIDC or other kinds of authentication mechanisms you can still try to managessh keys or other ressources this way
## Example Usage
```terraform
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
}
```
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- `email` (String) E-Mail Address of the user
- `login_name` (String) The login name can differ from the username
- `password` (String, Sensitive) Password to be set for the user
- `username` (String) Username of the user to be created
### Optional
- `active` (Boolean) Flag if this user should be active or not
- `admin` (Boolean) Flag if this user should be an administrator or not
- `allow_create_organization` (Boolean)
- `allow_git_hook` (Boolean)
- `allow_import_local` (Boolean)
- `description` (String) A description of the user
- `force_password_change` (Boolean) Flag if the user defined password should be overwritten or not
- `full_name` (String) Full name of the user
- `location` (String)
- `max_repo_creation` (Number)
- `must_change_password` (Boolean) Flag if the user should change the password after first login
- `prohibit_login` (Boolean) Flag if the user should not be allowed to log in (bot user)
- `restricted` (Boolean)
- `send_notification` (Boolean) Flag to send a notification about the user creation to the defined `email`
- `visibility` (String) Visibility of the user. Can be `public`, `limited` or `private`
### Read-Only
- `id` (String) The ID of this resource.

6
examples/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.terraform
.terraform.lock.hcl
terraform.tfstate
terraform.tfstate.backup
*.tfvars
id_ed25519

View File

@ -0,0 +1,24 @@
terraform {
required_providers {
gitea = {
source = "gitea/gitea"
version = "0.6.1"
}
}
}
provider "gitea" {
base_url = var.gitea_url # optionally use GITEA_BASE_URL env var
token = var.gitea_token # optionally use GITEA_TOKEN env var
# Username/Password authentication is mutally exclusive with token authentication
# username = var.username # optionally use GITEA_USERNAME env var
# password = var.password # optionally use GITEA_PASSWORD env var
# A file containing the ca certificate to use in case ssl certificate is not from a standard chain
cacert_file = var.cacert_file
# If you are running a gitea instance with self signed TLS certificates
# and you want to disable certificate validation you can deactivate it with this flag
insecure = false
}

View File

@ -0,0 +1,8 @@
resource "gitea_org" "test_org" {
name = "test-org"
}
resource "gitea_repository" "org_repo" {
username = gitea_org.test_org.name
name = "org-test-repo"
}

View File

@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINn6hAP48oKz6MVWjYvn0fne2YeaOv/zC6zuvFXlJKf2 test@dev.local

View File

@ -0,0 +1,14 @@
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
}
resource "gitea_public_key" "test_user_key" {
title = "test"
key = file("${path.module}/id_ed25519.pub")
username = gitea_user.test.username
}

View File

@ -0,0 +1,26 @@
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
}
resource "gitea_repository" "test" {
username = resource.gitea_user.test.name
name = "test"
private = true
issue_labels = "Default"
license = "MIT"
gitignores = "Go"
}
resource "gitea_repository" "mirror" {
username = resource.gitea_user.test.name
name = "terraform-provider-gitea-mirror"
description = "Mirror of Terraform Provider"
mirror = true
migration_clone_addresse = "https://git.uploadfilter24.eu/lerentis/terraform-provider-gitea.git"
migration_service = "gitea"
migration_service_auth_token = var.gitea_mirror_token
}

View File

@ -0,0 +1,21 @@
resource "gitea_org" "test_org" {
name = "test-org"
}
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
admin = true
}
resource "gitea_team" "test_team" {
name = "Devs"
organisation = gitea_org.test_org.name
description = "Devs of Test Org"
permission = "write"
members = [gitea_user.test.username]
}

View File

@ -0,0 +1,7 @@
resource "gitea_user" "test" {
username = "test"
login_name = "test"
password = "Geheim1!"
email = "test@user.dev"
must_change_password = false
}

View File

@ -61,12 +61,11 @@ func (c *Config) Client() (interface{}, error) {
var client *gitea.Client
if c.Token != "" {
client, _ = gitea.NewClient(c.BaseURL, gitea.SetToken(c.Token))
client, _ = gitea.NewClient(c.BaseURL, gitea.SetToken(c.Token), gitea.SetHTTPClient(httpClient))
}
client.SetHTTPClient(httpClient)
if c.Username != "" {
client.SetBasicAuth(c.Username, c.Password)
client, _ = gitea.NewClient(c.BaseURL, gitea.SetBasicAuth(c.Username, c.Password), gitea.SetHTTPClient(httpClient))
}
// Test the credentials by checking we can get information about the authenticated user.

View File

@ -73,10 +73,14 @@ func Provider() terraform.ResourceProvider {
},
ResourcesMap: map[string]*schema.Resource{
// "gitea_org": resourceGiteaOrg(),
"gitea_org": resourceGiteaOrg(),
// "gitea_team": resourceGiteaTeam(),
// "gitea_repo": resourceGiteaRepo(),
// "gitea_user": resourceGiteaUser(),
"gitea_user": resourceGiteaUser(),
"gitea_oauth2_app": resourceGiteaOauthApp(),
"gitea_repository": resourceGiteaRepository(),
"gitea_public_key": resourceGiteaPublicKey(),
"gitea_team": resourceGiteaTeam(),
},
ConfigureFunc: providerConfigure,

View File

@ -0,0 +1,195 @@
package gitea
import (
"fmt"
"code.gitea.io/sdk/gitea"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
const (
oauth2KeyName string = "name"
oauth2KeyRedirectURIs string = "redirect_uris"
oauth2KeyClientId string = "client_id"
oauth2KeyClientSecret string = "client_secret"
)
func resourceGiteaOauthApp() *schema.Resource {
return &schema.Resource{
Read: resourceOauth2AppRead,
Create: resourceOauth2AppUpcreate,
Update: resourceOauth2AppUpcreate,
Delete: resourceOauth2AppDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
oauth2KeyName: {
Required: true,
Type: schema.TypeString,
Description: "OAuth Application name",
},
oauth2KeyRedirectURIs: {
Required: true,
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "Accepted redirect URIs",
},
oauth2KeyClientId: {
Type: schema.TypeString,
Computed: true,
Description: "OAuth2 Application client id",
},
oauth2KeyClientSecret: {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
Description: "Oauth2 Application client secret",
},
},
Description: "Handling [gitea oauth application](https://docs.gitea.io/en-us/oauth2-provider/) resources",
}
}
func ExpandStringList(configured []interface{}) []string {
res := make([]string, 0, len(configured))
for _, v := range configured {
val, ok := v.(string)
if ok && val != "" {
res = append(res, (v.(string)))
}
}
return res
}
func CollapseStringList(strlist []string) []interface{} {
res := make([]interface{}, 0, len(strlist))
for _, v := range strlist {
res = append(res, v)
}
return res
}
func resourceOauth2AppUpcreate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
redirectURIsSchema, redirectURIsSchemaOk := d.Get(oauth2KeyRedirectURIs).(*schema.Set)
if !redirectURIsSchemaOk {
return fmt.Errorf("attribute %s must be set to a set of strings", oauth2KeyRedirectURIs)
}
redirectURIs := ExpandStringList(redirectURIsSchema.List())
name, nameOk := d.Get(oauth2KeyName).(string)
if !nameOk {
return fmt.Errorf("attribute %s must be set and must be a string", oauth2KeyName)
}
opts := gitea.CreateOauth2Option{
Name: name,
RedirectURIs: redirectURIs,
}
var oauth2 *gitea.Oauth2
if d.IsNewResource() {
oauth2, _, err = client.CreateOauth2(opts)
} else {
oauth2, err := searchOauth2AppByClientId(client, d.Id())
if err != nil {
return err
}
oauth2, _, err = client.UpdateOauth2(oauth2.ID, opts)
}
if err != nil {
return
}
err = setOAuth2ResourceData(oauth2, d)
return
}
func searchOauth2AppByClientId(c *gitea.Client, id string) (res *gitea.Oauth2, err error) {
page := 1
for {
apps, _, err := c.ListOauth2(gitea.ListOauth2Option{
ListOptions: gitea.ListOptions{
Page: page,
PageSize: 50,
},
})
if err != nil {
return nil, err
}
if len(apps) == 0 {
return nil, fmt.Errorf("no oauth client can be found by id '%s'", id)
}
for _, app := range apps {
if app.ClientID == id {
return app, nil
}
}
page += 1
}
}
func resourceOauth2AppRead(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
app, err := searchOauth2AppByClientId(client, d.Id())
if err != nil {
return err
}
err = setOAuth2ResourceData(app, d)
return
}
func resourceOauth2AppDelete(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
app, err := searchOauth2AppByClientId(client, d.Id())
if err != nil {
return err
}
_, err = client.DeleteOauth2(app.ID)
return
}
func setOAuth2ResourceData(app *gitea.Oauth2, d *schema.ResourceData) (err error) {
d.SetId(app.ClientID)
for k, v := range map[string]interface{}{
oauth2KeyName: app.Name,
oauth2KeyRedirectURIs: schema.NewSet(schema.HashString, CollapseStringList(app.RedirectURIs)),
oauth2KeyClientId: app.ClientID,
} {
err = d.Set(k, v)
if err != nil {
return
}
}
if app.ClientSecret != "" {
// Gitea API only reports client secrets if the resource is newly created
d.Set(oauth2KeyClientSecret, app.ClientSecret)
}
return
}

View File

@ -0,0 +1,190 @@
package gitea
import (
"fmt"
"code.gitea.io/sdk/gitea"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
const (
orgName string = "name"
orgFullName string = "full_name"
orgDescription string = "description"
orgWebsite string = "website"
orgLocation string = "location"
orgVisibility string = "visibility"
RepoAdminChangeTeamAccess string = "repo_admin_change_team_access"
)
func resourceOrgRead(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var org *gitea.Organization
var resp *gitea.Response
org, resp, err = client.GetOrg(d.Get(orgName).(string))
if err != nil {
if resp.StatusCode == 404 {
d.SetId("")
return nil
} else {
return err
}
}
err = setOrgResourceData(org, d)
return
}
func resourceOrgCreate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
opts := gitea.CreateOrgOption{
Name: d.Get(orgName).(string),
FullName: d.Get(orgFullName).(string),
Description: d.Get(orgDescription).(string),
Website: d.Get(orgWebsite).(string),
Location: d.Get(orgLocation).(string),
Visibility: gitea.VisibleType(d.Get(orgVisibility).(string)),
RepoAdminChangeTeamAccess: d.Get(RepoAdminChangeTeamAccess).(bool),
}
org, _, err := client.CreateOrg(opts)
if err != nil {
return
}
err = setOrgResourceData(org, d)
return
}
func resourceOrgUpdate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var org *gitea.Organization
var resp *gitea.Response
org, resp, err = client.GetOrg(d.Get(orgName).(string))
if err != nil {
if resp.StatusCode == 404 {
resourceOrgCreate(d, meta)
} else {
return err
}
}
opts := gitea.EditOrgOption{
FullName: d.Get(orgFullName).(string),
Description: d.Get(orgDescription).(string),
Website: d.Get(orgWebsite).(string),
Location: d.Get(orgLocation).(string),
Visibility: gitea.VisibleType(d.Get(orgVisibility).(string)),
}
client.EditOrg(d.Get(orgName).(string), opts)
org, resp, err = client.GetOrg(d.Get(orgName).(string))
err = setOrgResourceData(org, d)
return
}
func resourceOrgDelete(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var resp *gitea.Response
resp, err = client.DeleteOrg(d.Get(orgName).(string))
if err != nil {
if resp.StatusCode == 404 {
return
} else {
return err
}
}
return
}
func setOrgResourceData(org *gitea.Organization, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", org.ID))
d.Set("name", org.UserName)
d.Set("full_name", org.FullName)
d.Set("avatar_url", org.AvatarURL)
d.Set("description", org.Description)
d.Set("website", org.Website)
d.Set("location", org.Location)
d.Set("visibility", org.Visibility)
return
}
func resourceGiteaOrg() *schema.Resource {
return &schema.Resource{
Read: resourceOrgRead,
Create: resourceOrgCreate,
Update: resourceOrgUpdate,
Delete: resourceOrgDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The name of the organisation without spaces.",
},
"full_name": {
Type: schema.TypeString,
Required: false,
Optional: true,
Description: "The display name of the organisation. Defaults to the value of `name`.",
},
"description": {
Type: schema.TypeString,
Required: false,
Optional: true,
Description: "A description of this organisation.",
},
"website": {
Type: schema.TypeString,
Required: false,
Optional: true,
Description: "A link to a website with more information about this organisation.",
},
"location": {
Type: schema.TypeString,
Required: false,
Optional: true,
},
"repo_admin_change_team_access": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"avatar_url": {
Type: schema.TypeString,
Required: false,
Computed: true,
},
"visibility": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "public",
Description: "Flag is this organisation should be publicly visible or not.",
},
},
Description: "`gitea_org` manages a gitea organisation.\n\n" +
"Organisations are a way to group repositories and abstract permission management in a gitea instance.",
}
}

View File

@ -0,0 +1,155 @@
package gitea
import (
"fmt"
"strconv"
"code.gitea.io/sdk/gitea"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
const (
PublicKeyUser string = "username"
PublicKey string = "key"
PublicKeyReadOnlyFlag string = "read_only"
PublicKeyTitle string = "title"
PublicKeyId string = "id"
PublicKeyFingerprint string = "fingerprint"
PublicKeyCreated string = "created"
PublicKeyType string = "type"
)
func resourcePublicKeyRead(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
var pubKey *gitea.PublicKey
pubKey, resp, err = client.GetPublicKey(id)
if err != nil {
if resp.StatusCode == 404 {
d.SetId("")
return nil
} else {
return err
}
}
err = setPublicKeyResourceData(pubKey, d)
return
}
func resourcePublicKeyCreate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var pubKey *gitea.PublicKey
opts := gitea.CreateKeyOption{
Title: d.Get(PublicKeyTitle).(string),
Key: d.Get(PublicKey).(string),
ReadOnly: d.Get(PublicKeyReadOnlyFlag).(bool),
}
pubKey, _, err = client.AdminCreateUserPublicKey(d.Get(PublicKeyUser).(string), opts)
err = setPublicKeyResourceData(pubKey, d)
return
}
func resourcePublicKeyUpdate(d *schema.ResourceData, meta interface{}) (err error) {
// update = recreate
resourcePublicKeyDelete(d, meta)
resourcePublicKeyCreate(d, meta)
return
}
func resourcePublicKeyDelete(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
resp, err = client.AdminDeleteUserPublicKey(d.Get(PublicKeyUser).(string), int(id))
if err != nil {
if resp.StatusCode == 404 {
return
} else {
return err
}
}
return
}
func setPublicKeyResourceData(pubKey *gitea.PublicKey, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", pubKey.ID))
d.Set(PublicKeyUser, d.Get(PublicKeyUser).(string))
d.Set(PublicKey, d.Get(PublicKey).(string))
d.Set(PublicKeyTitle, pubKey.Title)
d.Set(PublicKeyReadOnlyFlag, d.Get(PublicKeyReadOnlyFlag).(bool))
d.Set(PublicKeyCreated, pubKey.Created)
d.Set(PublicKeyFingerprint, pubKey.Fingerprint)
d.Set(PublicKeyType, pubKey.KeyType)
return
}
func resourceGiteaPublicKey() *schema.Resource {
return &schema.Resource{
Read: resourcePublicKeyRead,
Create: resourcePublicKeyCreate,
Update: resourcePublicKeyUpdate,
Delete: resourcePublicKeyDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"title": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Title of the key to add",
},
"key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Sensitive: true,
Description: "An armored SSH key to add",
},
"read_only": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: false,
Description: "Describe if the key has only read access or read/write",
},
"username": {
Type: schema.TypeString,
Required: true,
Optional: false,
ForceNew: true,
Description: "User to associate with the added key",
},
"fingerprint": {
Type: schema.TypeString,
Computed: true,
},
"created": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
},
Description: "`gitea_public_key` manages ssh key that are associated with users.",
}
}

View File

@ -0,0 +1,523 @@
package gitea
import (
"fmt"
"strconv"
"code.gitea.io/sdk/gitea"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
const (
repoOwner string = "username"
repoName string = "name"
repoDescription string = "description"
repoPrivateFlag string = "private"
repoIssueLabels string = "issue_labels"
repoAutoInit string = "auto_init"
repoTemplate string = "repo_template"
repoGitignores string = "gitignores"
repoLicense string = "license"
repoReadme string = "readme"
repoDefaultBranch string = "default_branch"
repoWebsite string = "website"
repoIssues string = "has_issues"
repoWiki string = "has_wiki"
repoPrs string = "has_pull_requests"
repoProjects string = "has_projects"
repoIgnoreWhitespace string = "ignore_whitespace_conflicts"
repoAllowMerge string = "allow_merge_commits"
repoAllowRebase string = "allow_rebase"
repoAllowRebaseMerge string = "allow_rebase_explicit"
repoAllowSquash string = "allow_squash_merge"
repoAchived string = "archived"
repoAllowManualMerge string = "allow_manual_merge"
repoAutodetectManualMerge string = "autodetect_manual_merge"
repoMirror string = "mirror"
migrationCloneAddress string = "migration_clone_addresse"
migrationService string = "migration_service"
migrationServiceAuthName string = "migration_service_auth_username"
migrationServiceAuthPassword string = "migration_service_auth_password"
migrationServiceAuthToken string = "migration_service_auth_token"
migrationMilestones string = "migration_milestones"
migrationReleases string = "migration_releases"
migrationIssueLabels string = "migration_issue_labels"
migrationMirrorInterval string = "migration_mirror_interval"
migrationLFS string = "migration_lfs"
migrationLFSEndpoint string = "migration_lfs_endpoint"
)
func resourceRepoRead(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
if err != nil {
return err
}
repo, resp, err := client.GetRepoByID(id)
if err != nil {
if resp.StatusCode == 404 {
d.SetId("")
return nil
} else {
return err
}
}
err = setRepoResourceData(repo, d)
return
}
func resourceRepoCreate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var repo *gitea.Repository
var resp *gitea.Response
var orgRepo bool
_, resp, err = client.GetOrg(d.Get(repoOwner).(string))
if resp.StatusCode == 404 {
orgRepo = false
} else {
orgRepo = true
}
if (d.Get(repoMirror)).(bool) {
opts := gitea.MigrateRepoOption{
RepoName: d.Get(repoName).(string),
RepoOwner: d.Get(repoOwner).(string),
CloneAddr: d.Get(migrationCloneAddress).(string),
Service: gitea.GitServiceType(d.Get(migrationService).(string)),
Mirror: d.Get(repoMirror).(bool),
Private: d.Get(repoPrivateFlag).(bool),
Description: d.Get(repoDescription).(string),
Wiki: d.Get(repoWiki).(bool),
Milestones: d.Get(migrationMilestones).(bool),
Labels: d.Get(migrationIssueLabels).(bool),
Issues: d.Get(repoIssues).(bool),
PullRequests: d.Get(repoPrs).(bool),
Releases: d.Get(migrationReleases).(bool),
MirrorInterval: d.Get(migrationMirrorInterval).(string),
LFS: d.Get(migrationLFS).(bool),
LFSEndpoint: d.Get(migrationLFSEndpoint).(string),
}
if d.Get(migrationServiceAuthName).(string) != "" {
opts.AuthUsername = d.Get(migrationServiceAuthName).(string)
}
if d.Get(migrationServiceAuthPassword).(string) != "" {
opts.AuthPassword = d.Get(migrationServiceAuthPassword).(string)
}
if d.Get(migrationServiceAuthToken).(string) != "" {
opts.AuthToken = d.Get(migrationServiceAuthToken).(string)
}
repo, _, err = client.MigrateRepo(opts)
} else {
opts := gitea.CreateRepoOption{
Name: d.Get(repoName).(string),
Description: d.Get(repoDescription).(string),
Private: d.Get(repoPrivateFlag).(bool),
IssueLabels: d.Get(repoIssueLabels).(string),
AutoInit: d.Get(repoAutoInit).(bool),
Template: d.Get(repoTemplate).(bool),
Gitignores: d.Get(repoGitignores).(string),
License: d.Get(repoLicense).(string),
Readme: d.Get(repoReadme).(string),
DefaultBranch: d.Get(repoDefaultBranch).(string),
TrustModel: "default",
}
if orgRepo {
repo, _, err = client.CreateOrgRepo(d.Get(repoOwner).(string), opts)
} else {
repo, _, err = client.CreateRepo(opts)
}
}
if err != nil {
return
}
err = setRepoResourceData(repo, d)
return
}
func resourceRepoUpdate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var repo *gitea.Repository
var name string = d.Get(repoName).(string)
var description string = d.Get(repoDescription).(string)
var website string = d.Get(repoWebsite).(string)
var private bool = d.Get(repoPrivateFlag).(bool)
var template bool = d.Get(repoTemplate).(bool)
var hasIssues bool = d.Get(repoIssues).(bool)
var hasWiki bool = d.Get(repoWiki).(bool)
var defaultBranch string = d.Get(repoDefaultBranch).(string)
var hasPRs bool = d.Get(repoPrs).(bool)
var hasProjects bool = d.Get(repoProjects).(bool)
var ignoreWhitespaceConflicts bool = d.Get(repoIgnoreWhitespace).(bool)
var allowMerge bool = d.Get(repoAllowMerge).(bool)
var allowRebase bool = d.Get(repoAllowRebase).(bool)
var allowRebaseMerge bool = d.Get(repoAllowRebaseMerge).(bool)
var allowSquash bool = d.Get(repoAllowSquash).(bool)
var allowManualMerge bool = d.Get(repoAllowManualMerge).(bool)
var autodetectManualMerge bool = d.Get(repoAutodetectManualMerge).(bool)
opts := gitea.EditRepoOption{
Name: &name,
Description: &description,
Website: &website,
Private: &private,
Template: &template,
HasIssues: &hasIssues,
HasWiki: &hasWiki,
DefaultBranch: &defaultBranch,
HasPullRequests: &hasPRs,
HasProjects: &hasProjects,
IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts,
AllowMerge: &allowMerge,
AllowRebase: &allowRebase,
AllowRebaseMerge: &allowRebaseMerge,
AllowSquash: &allowSquash,
AllowManualMerge: &allowManualMerge,
AutodetectManualMerge: &autodetectManualMerge,
}
if d.Get(repoMirror).(bool) {
var mirrorInterval string = d.Get(migrationMirrorInterval).(string)
opts.MirrorInterval = &mirrorInterval
} else {
var archived bool = d.Get(repoAchived).(bool)
opts.Archived = &archived
}
repo, _, err = client.EditRepo(d.Get(repoOwner).(string), d.Get(repoName).(string), opts)
if err != nil {
return err
}
err = setRepoResourceData(repo, d)
return
}
func respurceRepoDelete(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
client.DeleteRepo(d.Get(repoOwner).(string), d.Get(repoName).(string))
return
}
func setRepoResourceData(repo *gitea.Repository, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", repo.ID))
d.Set("name", repo.Name)
d.Set("description", repo.Description)
d.Set("full_name", repo.FullName)
d.Set("private", repo.Private)
d.Set("fork", repo.Fork)
d.Set("mirror", repo.Mirror)
d.Set("size", repo.Size)
d.Set("html_url", repo.HTMLURL)
d.Set("ssh_url", repo.SSHURL)
d.Set("clone_url", repo.CloneURL)
d.Set("website", repo.Website)
d.Set("stars", repo.Stars)
d.Set("forks", repo.Forks)
d.Set("watchers", repo.Watchers)
d.Set("open_issue_count", repo.OpenIssues)
d.Set("default_branch", repo.DefaultBranch)
d.Set("created", repo.Created)
d.Set("updated", repo.Updated)
d.Set("permission_admin", repo.Permissions.Admin)
d.Set("permission_push", repo.Permissions.Push)
d.Set("permission_pull", repo.Permissions.Pull)
return
}
func resourceGiteaRepository() *schema.Resource {
return &schema.Resource{
Read: resourceRepoRead,
Create: resourceRepoCreate,
Update: resourceRepoUpdate,
Delete: respurceRepoDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"username": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The Owner of the repository",
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The Name of the repository",
},
"auto_init": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "Flag if the repository should be initiated with the configured values",
},
"repo_template": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: false,
},
"issue_labels": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "Default",
Description: "The Issue Label configuration to be used in this repository.\n" +
"Need to exist in the gitea instance",
},
"gitignores": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
Description: "A specific gitignore that should be commited to the repository" +
"on creation if `auto_init` is set to `true`\n" +
"Need to exist in the gitea instance",
},
"license": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
Description: "The license under which the source code of this repository should be.\n" +
"Need to exist in the gitea instance",
},
"readme": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
},
"description": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
Description: "The description of the repository.",
},
"private": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "Flag if the repository should be private or not.",
},
"default_branch": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "main",
Description: "The default branch of the repository. Defaults to `main`",
},
"created": {
Type: schema.TypeString,
Computed: true,
},
"updated": {
Type: schema.TypeString,
Computed: true,
},
"permission_admin": {
Type: schema.TypeBool,
Computed: true,
},
"permission_push": {
Type: schema.TypeBool,
Computed: true,
},
"permission_pull": {
Type: schema.TypeBool,
Computed: true,
},
"website": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
Description: "A link to a website with more information.",
},
"has_issues": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "A flag if the repository should have issue management enabled or not.",
},
"has_wiki": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "A flag if the repository should have the native wiki enabled or not.",
},
"has_pull_requests": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "A flag if the repository should acceppt pull requests or not.",
},
"has_projects": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "A flag if the repository should have the native project management enabled or not.",
},
"ignore_whitespace_conflicts": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"allow_merge_commits": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"allow_rebase": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"allow_rebase_explicit": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"allow_squash_merge": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"archived": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: false,
},
"allow_manual_merge": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"autodetect_manual_merge": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"mirror": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: false,
},
"migration_clone_addresse": {
Type: schema.TypeString,
Required: false,
Optional: true,
ForceNew: true,
},
"migration_service": {
Type: schema.TypeString,
Required: false,
ForceNew: true,
Optional: true,
Description: "git/github/gitlab/gitea/gogs",
},
"migration_service_auth_username": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
},
"migration_service_auth_password": {
Type: schema.TypeString,
Required: false,
Optional: true,
Sensitive: true,
Default: "",
},
"migration_service_auth_token": {
Type: schema.TypeString,
Required: false,
Optional: true,
Sensitive: true,
Default: "",
},
"migration_milestones": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"migration_releases": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"migration_issue_labels": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
},
"migration_mirror_interval": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "8h0m0s",
Description: "valid time units are 'h', 'm', 's'. 0 to disable automatic sync",
},
"migration_lfs": {
Type: schema.TypeBool,
Required: false,
Optional: true,
},
"migration_lfs_endpoint": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
},
},
Description: "`gitea_repository` manages a gitea repository.\n\n" +
"Per default this repository will be initializiled with the provided configuration (gitignore, License etc.).\n" +
"If the `username` property is set to a organisation name, the provider will try to look if this organisation exists " +
"and create the repository under the organisation scope.\n\n" +
"Repository migrations have some properties that are not available to regular repositories. These are all prefixed with `migration_`.",
}
}

View File

@ -0,0 +1,296 @@
package gitea
import (
"fmt"
"strconv"
"strings"
"code.gitea.io/sdk/gitea"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
const (
TeamName string = "name"
TeamOrg string = "organisation"
TeamDescription string = "description"
TeamPermissions string = "permission"
TeamCreateRepoFlag string = "can_create_repos"
TeamIncludeAllReposFlag string = "include_all_repositories"
TeamUnits string = "units"
TeamMembers string = "members"
)
func resourceTeamRead(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
var team *gitea.Team
team, resp, err = client.GetTeam(id)
if err != nil {
if resp.StatusCode == 404 {
d.SetId("")
return nil
} else {
return err
}
}
err = setTeamResourceData(team, d)
return
}
func resourceTeamCreate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var team *gitea.Team
var units []gitea.RepoUnitType
if strings.Contains(d.Get(TeamUnits).(string), "repo.code") {
units = append(units, gitea.RepoUnitCode)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.issues") {
units = append(units, gitea.RepoUnitIssues)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.ext_issues") {
units = append(units, gitea.RepoUnitExtIssues)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.wiki") {
units = append(units, gitea.RepoUnitWiki)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.pulls") {
units = append(units, gitea.RepoUnitPulls)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.releases") {
units = append(units, gitea.RepoUnitReleases)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.ext_wiki") {
units = append(units, gitea.RepoUnitExtWiki)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.projects") {
units = append(units, gitea.RepoUnitProjects)
}
opts := gitea.CreateTeamOption{
Name: d.Get(TeamName).(string),
Description: d.Get(TeamDescription).(string),
Permission: gitea.AccessMode(d.Get(TeamPermissions).(string)),
CanCreateOrgRepo: d.Get(TeamCreateRepoFlag).(bool),
IncludesAllRepositories: d.Get(TeamIncludeAllReposFlag).(bool),
Units: units,
}
team, _, err = client.CreateTeam(d.Get(TeamOrg).(string), opts)
if err != nil {
return
}
users := d.Get(TeamMembers).([]interface{})
for _, user := range users {
if user != "" {
_, err = client.AddTeamMember(team.ID, user.(string))
if err != nil {
return err
}
}
}
err = setTeamResourceData(team, d)
return
}
func resourceTeamUpdate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
var team *gitea.Team
team, resp, err = client.GetTeam(id)
if err != nil {
if resp.StatusCode == 404 {
resourceTeamCreate(d, meta)
} else {
return err
}
}
description := d.Get(TeamDescription).(string)
canCreateRepo := d.Get(TeamCreateRepoFlag).(bool)
includeAllRepos := d.Get(TeamIncludeAllReposFlag).(bool)
var units []gitea.RepoUnitType
if strings.Contains(d.Get(TeamUnits).(string), "repo.code") {
units = append(units, gitea.RepoUnitCode)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.issues") {
units = append(units, gitea.RepoUnitIssues)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.ext_issues") {
units = append(units, gitea.RepoUnitExtIssues)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.wiki") {
units = append(units, gitea.RepoUnitWiki)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.pulls") {
units = append(units, gitea.RepoUnitPulls)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.releases") {
units = append(units, gitea.RepoUnitReleases)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.ext_wiki") {
units = append(units, gitea.RepoUnitExtWiki)
}
if strings.Contains(d.Get(TeamUnits).(string), "repo.projects") {
units = append(units, gitea.RepoUnitProjects)
}
opts := gitea.EditTeamOption{
Name: d.Get(TeamName).(string),
Description: &description,
Permission: gitea.AccessMode(d.Get(TeamPermissions).(string)),
CanCreateOrgRepo: &canCreateRepo,
IncludesAllRepositories: &includeAllRepos,
Units: units,
}
resp, err = client.EditTeam(id, opts)
if err != nil {
return err
}
users := d.Get(TeamMembers).([]interface{})
for _, user := range users {
if user != "" {
_, err = client.AddTeamMember(team.ID, user.(string))
if err != nil {
return err
}
}
}
team, _, _ = client.GetTeam(id)
err = setTeamResourceData(team, d)
return
}
func resourceTeamDelete(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
resp, err = client.DeleteTeam(id)
if err != nil {
if resp.StatusCode == 404 {
return
} else {
return err
}
}
return
}
func setTeamResourceData(team *gitea.Team, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", team.ID))
d.Set(TeamCreateRepoFlag, team.CanCreateOrgRepo)
d.Set(TeamDescription, team.Description)
d.Set(TeamName, team.Name)
d.Set(TeamPermissions, string(team.Permission))
d.Set(TeamIncludeAllReposFlag, team.IncludesAllRepositories)
d.Set(TeamUnits, d.Get(TeamUnits).(string))
d.Set(TeamOrg, d.Get(TeamOrg).(string))
d.Set(TeamMembers, d.Get(TeamMembers))
return
}
func resourceGiteaTeam() *schema.Resource {
return &schema.Resource{
Read: resourceTeamRead,
Create: resourceTeamCreate,
Update: resourceTeamUpdate,
Delete: resourceTeamDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Name of the Team",
},
"organisation": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The organisation which this Team is part of.",
},
"description": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
Description: "Description of the Team",
},
"permission": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "",
Description: "Permissions associated with this Team\n" +
"Can be `none`, `read`, `write`, `admin` or `owner`",
},
"can_create_repos": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "Flag if the Teams members should be able to create Rpositories in the Organisation",
},
"include_all_repositories": {
Type: schema.TypeBool,
Required: false,
Optional: true,
Default: true,
Description: "Flag if the Teams members should have access to all Repositories in the Organisation",
},
"units": {
Type: schema.TypeString,
Required: false,
Optional: true,
Default: "[repo.code, repo.issues, repo.ext_issues, repo.wiki, repo.pulls, repo.releases, repo.projects, repo.ext_wiki]",
Description: "List of types of Repositories that should be allowed to be created from Team members.\n" +
"Can be `repo.code`, `repo.issues`, `repo.ext_issues`, `repo.wiki`, `repo.pulls`, `repo.releases`, `repo.projects` and/or `repo.ext_wiki`",
},
"members": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
Required: false,
Computed: true,
Description: "List of Users that should be part of this team",
},
},
Description: "`gitea_team` manages Team that are part of an organisation.",
}
}

View File

@ -0,0 +1,364 @@
package gitea
import (
"fmt"
"strconv"
"code.gitea.io/sdk/gitea"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
const (
userName string = "username"
userLoginName string = "login_name"
userEmail string = "email"
userFullName string = "full_name"
userPassword string = "password"
userMustChangePassword string = "must_change_password"
userSendNotification string = "send_notification"
userVisibility string = "visibility"
userDescription string = "description"
userLocation string = "location"
userActive string = "active"
userAdmin string = "admin"
userAllowGitHook string = "allow_git_hook"
userAllowLocalImport string = "allow_import_local"
userMaxRepoCreation string = "max_repo_creation"
userPhorbitLogin string = "prohibit_login"
userAllowCreateOrgs string = "allow_create_organization"
userRestricted string = "restricted"
userForcePasswordChange string = "force_password_change"
)
func resourceUserRead(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
var user *gitea.User
user, resp, err = client.GetUserByID(id)
if err != nil {
if resp.StatusCode == 404 {
d.SetId("")
return nil
} else {
return err
}
}
err = setUserResourceData(user, d)
return
}
func resourceUserCreate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var user *gitea.User
visibility := gitea.VisibleType(d.Get(userVisibility).(string))
changePassword := d.Get(userMustChangePassword).(bool)
opts := gitea.CreateUserOption{
SourceID: 0,
LoginName: d.Get(userLoginName).(string),
Username: d.Get(userName).(string),
FullName: d.Get(userFullName).(string),
Email: d.Get(userEmail).(string),
Password: d.Get(userPassword).(string),
MustChangePassword: &changePassword,
SendNotify: d.Get(userSendNotification).(bool),
Visibility: &visibility,
}
user, _, err = client.AdminCreateUser(opts)
if err != nil {
return
}
d.SetId(fmt.Sprintf("%d", user.ID))
err = resourceUserUpdate(d, meta)
return
}
func resourceUserUpdate(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
id, err := strconv.ParseInt(d.Id(), 10, 64)
var resp *gitea.Response
var user *gitea.User
user, resp, err = client.GetUserByID(id)
if err != nil {
if resp.StatusCode == 404 {
resourceUserCreate(d, meta)
} else {
return err
}
}
mail := d.Get(userEmail).(string)
fullName := d.Get(userFullName).(string)
description := d.Get(userDescription).(string)
changePassword := d.Get(userMustChangePassword).(bool)
location := d.Get(userLocation).(string)
active := d.Get(userActive).(bool)
admin := d.Get(userAdmin).(bool)
allowHook := d.Get(userAllowGitHook).(bool)
allowImport := d.Get(userAllowLocalImport).(bool)
maxRepoCreation := d.Get(userMaxRepoCreation).(int)
accessDenied := d.Get(userPhorbitLogin).(bool)
allowOrgs := d.Get(userAllowCreateOrgs).(bool)
restricted := d.Get(userRestricted).(bool)
visibility := gitea.VisibleType(d.Get(userVisibility).(string))
if d.Get(userForcePasswordChange).(bool) {
opts := gitea.EditUserOption{
SourceID: 0,
LoginName: d.Get(userLoginName).(string),
Email: &mail,
FullName: &fullName,
Password: d.Get(userPassword).(string),
Description: &description,
MustChangePassword: &changePassword,
Location: &location,
Active: &active,
Admin: &admin,
AllowGitHook: &allowHook,
AllowImportLocal: &allowImport,
MaxRepoCreation: &maxRepoCreation,
ProhibitLogin: &accessDenied,
AllowCreateOrganization: &allowOrgs,
Restricted: &restricted,
Visibility: &visibility,
}
_, err = client.AdminEditUser(d.Get(userName).(string), opts)
if err != nil {
return err
}
} else {
opts := gitea.EditUserOption{
SourceID: 0,
LoginName: d.Get(userLoginName).(string),
Email: &mail,
FullName: &fullName,
Description: &description,
MustChangePassword: &changePassword,
Location: &location,
Active: &active,
Admin: &admin,
AllowGitHook: &allowHook,
AllowImportLocal: &allowImport,
MaxRepoCreation: &maxRepoCreation,
ProhibitLogin: &accessDenied,
AllowCreateOrganization: &allowOrgs,
Restricted: &restricted,
Visibility: &visibility,
}
_, err = client.AdminEditUser(d.Get(userName).(string), opts)
if err != nil {
return err
}
}
user, _, err = client.GetUserByID(id)
err = setUserResourceData(user, d)
return
}
func resourceUserDelete(d *schema.ResourceData, meta interface{}) (err error) {
client := meta.(*gitea.Client)
var resp *gitea.Response
resp, err = client.AdminDeleteUser(d.Get(userName).(string))
if err != nil {
if resp.StatusCode == 404 {
return
} else {
return err
}
}
return
}
func setUserResourceData(user *gitea.User, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", user.ID))
d.Set(userName, user.UserName)
d.Set(userEmail, user.Email)
d.Set(userFullName, user.FullName)
d.Set(userAdmin, user.IsAdmin)
d.Set("created", user.Created)
d.Set("avatar_url", user.AvatarURL)
d.Set("last_login", user.LastLogin)
d.Set("language", user.Language)
d.Set(userLoginName, d.Get(userLoginName).(string))
d.Set(userMustChangePassword, d.Get(userMustChangePassword).(bool))
d.Set(userSendNotification, d.Get(userSendNotification).(bool))
d.Set(userVisibility, d.Get(userVisibility).(string))
d.Set(userDescription, d.Get(userDescription).(string))
d.Set(userLocation, d.Get(userLocation).(string))
d.Set(userActive, d.Get(userActive).(bool))
d.Set(userAllowGitHook, d.Get(userAllowGitHook).(bool))
d.Set(userAllowLocalImport, d.Get(userAllowLocalImport).(bool))
d.Set(userMaxRepoCreation, d.Get(userMaxRepoCreation).(int))
d.Set(userPhorbitLogin, d.Get(userPhorbitLogin).(bool))
d.Set(userAllowCreateOrgs, d.Get(userAllowCreateOrgs).(bool))
d.Set(userRestricted, d.Get(userRestricted).(bool))
d.Set(userForcePasswordChange, d.Get(userForcePasswordChange).(bool))
return
}
func resourceGiteaUser() *schema.Resource {
return &schema.Resource{
Read: resourceUserRead,
Create: resourceUserCreate,
Update: resourceUserUpdate,
Delete: resourceUserDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"username": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Username of the user to be created",
},
"login_name": {
Type: schema.TypeString,
Optional: false,
Required: true,
Description: "The login name can differ from the username",
},
"email": {
Type: schema.TypeString,
Optional: false,
Required: true,
Description: "E-Mail Address of the user",
},
"full_name": {
Type: schema.TypeString,
Computed: true,
Optional: true,
Required: false,
Description: "Full name of the user",
},
"password": {
Type: schema.TypeString,
Optional: false,
Required: true,
Sensitive: true,
Description: "Password to be set for the user",
},
"must_change_password": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: true,
Description: "Flag if the user should change the password after first login",
},
"send_notification": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: true,
Description: "Flag to send a notification about the user creation to the defined `email`",
},
"visibility": {
Type: schema.TypeString,
Optional: true,
Required: false,
Default: "public",
Description: "Visibility of the user. Can be `public`, `limited` or `private`",
},
"description": {
Type: schema.TypeString,
Optional: true,
Required: false,
Default: "",
Description: "A description of the user",
},
"location": {
Type: schema.TypeString,
Optional: true,
Required: false,
Default: "",
},
"active": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: true,
Description: "Flag if this user should be active or not",
},
"admin": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: false,
Description: "Flag if this user should be an administrator or not",
},
"allow_git_hook": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: true,
},
"allow_import_local": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: true,
},
"max_repo_creation": {
Type: schema.TypeInt,
Optional: true,
Required: false,
Default: -1,
},
"prohibit_login": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: false,
Description: "Flag if the user should not be allowed to log in (bot user)",
},
"allow_create_organization": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: true,
},
"restricted": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: false,
},
"force_password_change": {
Type: schema.TypeBool,
Optional: true,
Required: false,
Default: false,
Description: "Flag if the user defined password should be overwritten or not",
},
},
Description: "`gitea_user` manages a native gitea user.\n\n" +
"If you are using OIDC or other kinds of authentication mechanisms you can still try to manage" +
"ssh keys or other ressources this way",
}
}