7 Commits

Author SHA1 Message Date
6165e5ae19 use correct test function
Some checks reported errors
continuous-integration/drone/push Build encountered an error
2022-07-09 23:15:25 +02:00
021db20aa1 hard wip
Some checks reported errors
continuous-integration/drone/push Build encountered an error
2022-07-09 23:11:26 +02:00
0208cbd960 #5 fixed state handling for public keys
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2022-07-08 21:50:09 +02:00
08dffb3e3a Merge pull request '#3 added team resource and fixed crash in public key state persisting' (#4) from feature/tt/#3-team-management into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #4
2022-06-25 22:38:05 +00:00
680e2dcba2 #3 teams can now have members
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2022-06-26 00:35:28 +02:00
6e63797167 #3 added team resource and fixed crash in public key state persisting
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2022-06-25 23:36:24 +02:00
787a2b9636 added MIT license
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-25 22:00:22 +02:00
13 changed files with 521 additions and 29 deletions

View File

@ -15,23 +15,27 @@ steps:
- push
- pull_request
- tag
- name: build
image: goreleaser/goreleaser
- name: backend
image: gitea/gitea:1.16.8
detach: true
commands:
- goreleaser build --snapshot
when:
event:
- push
- pull_request
resources:
limits:
cpu: 1000
memory: 1024MiB
- su git
- gitea admin user create --username test --password $GITEA_PASSWORD --must-change-password false --admin --email test@mail.org
- /usr/bin/entrypoint /bin/s6-svscan /etc/s6
environment:
GITEA_PASSWORD:
from_secret: GITEA_TEST_PASSWORD
- name: test
image: golang:1.18.3-alpine3.16
commands:
- "apk add --update --no-cache make build-base"
- "make test"
- "make testacc"
environment:
TF_ACC: 1
GITEA_BASE_URL: "http://localhost:3000"
GITEA_USERNAME: test
GITEA_PASSWORD:
from_secret: GITEA_TEST_PASSWORD
when:
event:
- push

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2022 lerentis, https://git.uploadfilter24.eu/lerentis
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -3,7 +3,7 @@ GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
GOFMT ?= gofmt -s
VERSION = 0.5.0
VERSION = 0.6.1
test: fmt-check
go test -i $(TEST) || exit 1
@ -11,7 +11,7 @@ test: fmt-check
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
testacc: fmt-check
TF_ACC=1 go test -v $(TEST) $(TESTARGS) -timeout 40m
go test -v $(TEST) $(TESTARGS) -timeout 40m
vet:
@echo "go vet ."

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.

View File

@ -46,3 +46,12 @@ resource "gitea_public_key" "test_user_key" {
read_only = true
username = gitea_user.test.username
}
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

@ -2,7 +2,7 @@ terraform {
required_providers {
gitea = {
source = "terraform.local/lerentis/gitea"
version = "0.5.0"
version = "0.6.1"
}
}
}

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

@ -1,14 +1,6 @@
package gitea
import (
"fmt"
"testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)
func TestAccDataSourceGiteaUser_basic(t *testing.T) {
/*func TestAccDataSourceGiteaUser_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
@ -59,4 +51,4 @@ data "gitea_user" "foo" {
data "gitea_user" "self" {
}
`)
}
}*/

View File

@ -80,6 +80,7 @@ func Provider() terraform.ResourceProvider {
"gitea_oauth2_app": resourceGiteaOauthApp(),
"gitea_repository": resourceGiteaRepository(),
"gitea_public_key": resourceGiteaPublicKey(),
"gitea_team": resourceGiteaTeam(),
},
ConfigureFunc: providerConfigure,

View File

@ -90,10 +90,10 @@ func resourcePublicKeyDelete(d *schema.ResourceData, meta interface{}) (err erro
func setPublicKeyResourceData(pubKey *gitea.PublicKey, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", pubKey.ID))
d.Set(PublicKeyUser, pubKey.Owner.UserName)
d.Set(PublicKey, pubKey.Key)
d.Set(PublicKeyUser, d.Get(PublicKeyUser).(string))
d.Set(PublicKey, d.Get(PublicKey).(string))
d.Set(PublicKeyTitle, pubKey.Title)
d.Set(PublicKeyReadOnlyFlag, pubKey.ReadOnly)
d.Set(PublicKeyReadOnlyFlag, d.Get(PublicKeyReadOnlyFlag).(bool))
d.Set(PublicKeyCreated, pubKey.Created)
d.Set(PublicKeyFingerprint, pubKey.Fingerprint)
d.Set(PublicKeyType, pubKey.KeyType)

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

@ -196,7 +196,6 @@ func resourceUserDelete(d *schema.ResourceData, meta interface{}) (err error) {
func setUserResourceData(user *gitea.User, d *schema.ResourceData) (err error) {
d.SetId(fmt.Sprintf("%d", user.ID))
d.Set("id", user.ID)
d.Set(userName, user.UserName)
d.Set(userEmail, user.Email)
d.Set(userFullName, user.FullName)

View File

@ -0,0 +1,86 @@
package gitea
import (
"fmt"
"testing"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)
func TestAccResourceGiteaUser_basic(t *testing.T) {
name := fmt.Sprintf("user-%d", 1)
mail := fmt.Sprintf("%s@test.org", name)
fqrn := fmt.Sprintf("gitea_user.%s", name)
userSimple := fmt.Sprintf(`
resource "gitea_user" "%s" {
username = "%s"
login_name = "%s"
email = "%s"
password = "Geheim1!"
}
`, name, name, name, mail)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckExampleResourceDestroy,
Steps: []resource.TestStep{
{
Config: userSimple,
ResourceName: fqrn,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(fqrn, "username", name),
),
},
},
})
}
func testAccCheckExampleResourceDestroy(s *terraform.State) error {
// retrieve the connection established in Provider configuration
//conn := testAccProvider.Meta().(*ExampleClient)
// loop through the resources in state, verifying each widget
// is destroyed
for _, rs := range s.RootModule().Resources {
if rs.Type != "example_widget" {
continue
}
// Retrieve our widget by referencing it's state ID for API lookup
//request := &example.DescribeWidgets{
// IDs: []string{rs.Primary.ID},
//}
//response, err := conn.DescribeWidgets(request)
//if err == nil {
// if len(response.Widgets) > 0 && *response.Widgets[0].ID == rs.Primary.ID {
// return fmt.Errorf("Widget (%s) still exists.", rs.Primary.ID)
// }
// return nil
//}
// If the error is equivalent to 404 not found, the widget is destroyed.
// Otherwise return the error
//if !strings.Contains(err.Error(), "Widget not found") {
// return err
//}
}
return nil
}
func testAccResourceGiteaUserSimple(fqrn string, name string, mail string) string {
return fmt.Sprintf(`
resource "gitea_user" "%s" {
username = "%s"
login_name = "%s"
email = "%s"
password = "Geheim1!"
}
`, fqrn, name, name, mail)
}