diff --git a/docs/data-sources/repository_gitlfs_hosted.md b/docs/data-sources/repository_gitlfs_hosted.md
new file mode 100644
index 00000000..b1c8d1cb
--- /dev/null
+++ b/docs/data-sources/repository_gitlfs_hosted.md
@@ -0,0 +1,53 @@
+---
+page_title: "Data Source nexus_repository_gitlfs_hosted"
+subcategory: "Repository"
+description: |-
+ Use this data source to get an existing hosted yum repository.
+---
+# Data Source nexus_repository_gitlfs_hosted
+Use this data source to get an existing hosted yum repository.
+## Example Usage
+```terraform
+data "nexus_repository_gitlfs_hosted" "internal" {
+ name = "gitlfs-internal"
+}
+```
+
+## Schema
+
+### Required
+
+- `name` (String) A unique identifier for this repository
+
+### Read-Only
+
+- `cleanup` (List of Object) Cleanup policies (see [below for nested schema](#nestedatt--cleanup))
+- `component` (List of Object) Component configuration for the hosted repository (see [below for nested schema](#nestedatt--component))
+- `id` (String) Used to identify data source at nexus
+- `online` (Boolean) Whether this repository accepts incoming requests
+- `storage` (List of Object) The storage configuration of the repository (see [below for nested schema](#nestedatt--storage))
+
+
+### Nested Schema for `cleanup`
+
+Read-Only:
+
+- `policy_names` (Set of String)
+
+
+
+### Nested Schema for `component`
+
+Read-Only:
+
+- `proprietary_components` (Boolean)
+
+
+
+### Nested Schema for `storage`
+
+Read-Only:
+
+- `blob_store_name` (String)
+- `strict_content_type_validation` (Boolean)
+- `write_policy` (String)
diff --git a/docs/resources/repository_gitlfs_hosted.md b/docs/resources/repository_gitlfs_hosted.md
new file mode 100644
index 00000000..9fd3482b
--- /dev/null
+++ b/docs/resources/repository_gitlfs_hosted.md
@@ -0,0 +1,72 @@
+---
+page_title: "Resource nexus_repository_gitlfs_hosted"
+subcategory: "Repository"
+description: |-
+ Use this resource to create a hosted gitlfs repository.
+---
+# Resource nexus_repository_gitlfs_hosted
+Use this resource to create a hosted gitlfs repository.
+## Example Usage
+```terraform
+resource "nexus_repository_gitlfs_hosted" "internal" {
+ name = "gitlfs-internal"
+ online = true
+
+ storage {
+ blob_store_name = "default"
+ strict_content_type_validation = false
+ write_policy = "ALLOW"
+ }
+}
+```
+
+## Schema
+
+### Required
+
+- `name` (String) A unique identifier for this repository
+- `storage` (Block List, Min: 1, Max: 1) The storage configuration of the repository (see [below for nested schema](#nestedblock--storage))
+
+### Optional
+
+- `cleanup` (Block List) Cleanup policies (see [below for nested schema](#nestedblock--cleanup))
+- `component` (Block List, Max: 1) Component configuration for the hosted repository (see [below for nested schema](#nestedblock--component))
+- `online` (Boolean) Whether this repository accepts incoming requests
+
+### Read-Only
+
+- `id` (String) Used to identify resource at nexus
+
+
+### Nested Schema for `storage`
+
+Required:
+
+- `blob_store_name` (String) Blob store used to store repository contents
+- `strict_content_type_validation` (Boolean) Whether to validate uploaded content's MIME type appropriate for the repository format
+
+Optional:
+
+- `write_policy` (String) Controls if deployments of and updates to assets are allowed
+
+
+
+### Nested Schema for `cleanup`
+
+Optional:
+
+- `policy_names` (Set of String) List of policy names
+
+
+
+### Nested Schema for `component`
+
+Required:
+
+- `proprietary_components` (Boolean) Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
+## Import
+Import is supported using the following syntax:
+```shell
+# import using the name of repository
+terraform import nexus_repository_gitlfs_hosted.internal gitlfs-internal
+```
diff --git a/examples/data-sources/nexus_repository_gitlfs_hosted/data-source.tf b/examples/data-sources/nexus_repository_gitlfs_hosted/data-source.tf
new file mode 100644
index 00000000..bb2fd8d3
--- /dev/null
+++ b/examples/data-sources/nexus_repository_gitlfs_hosted/data-source.tf
@@ -0,0 +1,3 @@
+data "nexus_repository_gitlfs_hosted" "internal" {
+ name = "gitlfs-internal"
+}
diff --git a/examples/resources/nexus_repository_gitlfs_hosted/import.sh b/examples/resources/nexus_repository_gitlfs_hosted/import.sh
new file mode 100644
index 00000000..7b13db5e
--- /dev/null
+++ b/examples/resources/nexus_repository_gitlfs_hosted/import.sh
@@ -0,0 +1,2 @@
+# import using the name of repository
+terraform import nexus_repository_gitlfs_hosted.internal gitlfs-internal
diff --git a/examples/resources/nexus_repository_gitlfs_hosted/resource.tf b/examples/resources/nexus_repository_gitlfs_hosted/resource.tf
new file mode 100644
index 00000000..24a5d5a1
--- /dev/null
+++ b/examples/resources/nexus_repository_gitlfs_hosted/resource.tf
@@ -0,0 +1,10 @@
+resource "nexus_repository_gitlfs_hosted" "internal" {
+ name = "gitlfs-internal"
+ online = true
+
+ storage {
+ blob_store_name = "default"
+ strict_content_type_validation = false
+ write_policy = "ALLOW"
+ }
+}
diff --git a/internal/acceptance/template-strings-repository-gitlfs.go b/internal/acceptance/template-strings-repository-gitlfs.go
new file mode 100644
index 00000000..1ea12ab7
--- /dev/null
+++ b/internal/acceptance/template-strings-repository-gitlfs.go
@@ -0,0 +1,7 @@
+package acceptance
+
+const (
+ TemplateStringRepositoryGitlfsHosted = `
+resource "nexus_repository_gitlfs_hosted" "acceptance" {
+` + TemplateStringHostedRepository
+)
diff --git a/internal/provider/main.go b/internal/provider/main.go
index 4303ae72..b017591f 100644
--- a/internal/provider/main.go
+++ b/internal/provider/main.go
@@ -34,6 +34,7 @@ func Provider() *schema.Provider {
"nexus_repository_docker_group": repository.DataSourceRepositoryDockerGroup(),
"nexus_repository_docker_hosted": repository.DataSourceRepositoryDockerHosted(),
"nexus_repository_docker_proxy": repository.DataSourceRepositoryDockerProxy(),
+ "nexus_repository_gitlfs_hosted": repository.DataSourceRepositoryGitlfsHosted(),
"nexus_repository_list": repository.DataSourceRepositoryList(),
"nexus_repository_maven_group": repository.DataSourceRepositoryMavenGroup(),
"nexus_repository_maven_hosted": repository.DataSourceRepositoryMavenHosted(),
@@ -92,6 +93,7 @@ func Provider() *schema.Provider {
"nexus_repository_docker_group": repository.ResourceRepositoryDockerGroup(),
"nexus_repository_docker_hosted": repository.ResourceRepositoryDockerHosted(),
"nexus_repository_docker_proxy": repository.ResourceRepositoryDockerProxy(),
+ "nexus_repository_gitlfs_hosted": repository.ResourceRepositoryGitlfsHosted(),
"nexus_repository_maven_group": repository.ResourceRepositoryMavenGroup(),
"nexus_repository_maven_hosted": repository.ResourceRepositoryMavenHosted(),
"nexus_repository_maven_proxy": repository.ResourceRepositoryMavenProxy(),
diff --git a/internal/services/repository/data_source_repository_gitlfs_hosted.go b/internal/services/repository/data_source_repository_gitlfs_hosted.go
new file mode 100644
index 00000000..425a767f
--- /dev/null
+++ b/internal/services/repository/data_source_repository_gitlfs_hosted.go
@@ -0,0 +1,31 @@
+package repository
+
+import (
+ "github.com/datadrivers/terraform-provider-nexus/internal/schema/common"
+ "github.com/datadrivers/terraform-provider-nexus/internal/schema/repository"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func DataSourceRepositoryGitlfsHosted() *schema.Resource {
+ return &schema.Resource{
+ Description: "Use this data source to get an existing hosted yum repository.",
+
+ Read: dataSourceRepositoryGitlfsHostedRead,
+ Schema: map[string]*schema.Schema{
+ // Common schemas
+ "id": common.DataSourceID,
+ "name": repository.DataSourceName,
+ "online": repository.DataSourceOnline,
+ // Hosted schemas
+ "cleanup": repository.DataSourceCleanup,
+ "component": repository.DataSourceComponent,
+ "storage": repository.DataSourceHostedStorage,
+ },
+ }
+}
+
+func dataSourceRepositoryGitlfsHostedRead(d *schema.ResourceData, m interface{}) error {
+ d.SetId(d.Get("name").(string))
+
+ return resourceGitlfsHostedRepositoryRead(d, m)
+}
diff --git a/internal/services/repository/data_source_repository_gitlfs_hosted_test.go b/internal/services/repository/data_source_repository_gitlfs_hosted_test.go
new file mode 100644
index 00000000..5926e13d
--- /dev/null
+++ b/internal/services/repository/data_source_repository_gitlfs_hosted_test.go
@@ -0,0 +1,50 @@
+package repository_test
+
+import (
+ "fmt"
+ "strconv"
+ "testing"
+
+ "github.com/datadrivers/go-nexus-client/nexus3/schema/repository"
+ "github.com/datadrivers/terraform-provider-nexus/internal/acceptance"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+)
+
+func testAccDataSourceRepositoryGitlfsHostedConfig() string {
+ return `
+data "nexus_repository_gitlfs_hosted" "acceptance" {
+ name = nexus_repository_gitlfs_hosted.acceptance.id
+}`
+}
+
+func TestAccDataSourceRepositoryGitlfsHosted(t *testing.T) {
+ repoUsingDefaults := repository.GitLfsHostedRepository{
+ Name: fmt.Sprintf("acceptance-%s", acctest.RandString(10)),
+ Online: true,
+ Storage: repository.HostedStorage{
+ BlobStoreName: "default",
+ StrictContentTypeValidation: false,
+ },
+ }
+ dataSourceName := "data.nexus_repository_gitlfs_hosted.acceptance"
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acceptance.AccPreCheck(t) },
+ Providers: acceptance.TestAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccResourceRepositoryGitlfsHostedConfig(repoUsingDefaults) + testAccDataSourceRepositoryGitlfsHostedConfig(),
+ Check: resource.ComposeTestCheckFunc(
+ resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr(dataSourceName, "id", repoUsingDefaults.Name),
+ resource.TestCheckResourceAttr(dataSourceName, "name", repoUsingDefaults.Name),
+ resource.TestCheckResourceAttr(dataSourceName, "online", strconv.FormatBool(repoUsingDefaults.Online)),
+ resource.TestCheckResourceAttr(dataSourceName, "storage.0.blob_store_name", repoUsingDefaults.Storage.BlobStoreName),
+ resource.TestCheckResourceAttr(dataSourceName, "storage.0.strict_content_type_validation", strconv.FormatBool(repoUsingDefaults.Storage.StrictContentTypeValidation)),
+ ),
+ ),
+ },
+ },
+ })
+}
diff --git a/internal/services/repository/resource_repository_gitlfs_hosted.go b/internal/services/repository/resource_repository_gitlfs_hosted.go
new file mode 100644
index 00000000..31f13c21
--- /dev/null
+++ b/internal/services/repository/resource_repository_gitlfs_hosted.go
@@ -0,0 +1,154 @@
+package repository
+
+import (
+ nexus "github.com/datadrivers/go-nexus-client/nexus3"
+ "github.com/datadrivers/go-nexus-client/nexus3/schema/repository"
+ "github.com/datadrivers/terraform-provider-nexus/internal/schema/common"
+ repositorySchema "github.com/datadrivers/terraform-provider-nexus/internal/schema/repository"
+ "github.com/datadrivers/terraform-provider-nexus/internal/tools"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+func ResourceRepositoryGitlfsHosted() *schema.Resource {
+ return &schema.Resource{
+ Description: "Use this resource to create a hosted gitlfs repository.",
+
+ Create: resourceGitlfsHostedRepositoryCreate,
+ Delete: resourceGitlfsHostedRepositoryDelete,
+ Exists: resourceGitlfsHostedRepositoryExists,
+ Read: resourceGitlfsHostedRepositoryRead,
+ Update: resourceGitlfsHostedRepositoryUpdate,
+ Importer: &schema.ResourceImporter{
+ StateContext: schema.ImportStatePassthroughContext,
+ },
+
+ Schema: map[string]*schema.Schema{
+ // Common schemas
+ "id": common.ResourceID,
+ "name": repositorySchema.ResourceName,
+ "online": repositorySchema.ResourceOnline,
+ // Hosted schemas
+ "cleanup": repositorySchema.ResourceCleanup,
+ "component": repositorySchema.ResourceComponent,
+ "storage": repositorySchema.ResourceHostedStorage,
+ },
+ }
+}
+
+func getGitlfsHostedRepositoryFromResourceData(resourceData *schema.ResourceData) repository.GitLfsHostedRepository {
+ storageConfig := resourceData.Get("storage").([]interface{})[0].(map[string]interface{})
+ writePolicy := repository.StorageWritePolicy(storageConfig["write_policy"].(string))
+
+ repo := repository.GitLfsHostedRepository{
+ Name: resourceData.Get("name").(string),
+ Online: resourceData.Get("online").(bool),
+ Storage: repository.HostedStorage{
+ BlobStoreName: storageConfig["blob_store_name"].(string),
+ StrictContentTypeValidation: storageConfig["strict_content_type_validation"].(bool),
+ WritePolicy: &writePolicy,
+ },
+ }
+
+ cleanupList := resourceData.Get("cleanup").([]interface{})
+ if len(cleanupList) > 0 && cleanupList[0] != nil {
+ cleanupConfig := cleanupList[0].(map[string]interface{})
+ if len(cleanupConfig) > 0 {
+ policy_names, ok := cleanupConfig["policy_names"]
+ if ok {
+ repo.Cleanup = &repository.Cleanup{
+ PolicyNames: tools.InterfaceSliceToStringSlice(policy_names.(*schema.Set).List()),
+ }
+ }
+ }
+ }
+
+ componentList := resourceData.Get("component").([]interface{})
+ if len(componentList) > 0 && componentList[0] != nil {
+ componentConfig := componentList[0].(map[string]interface{})
+ if len(componentConfig) > 0 {
+ repo.Component = &repository.Component{
+ ProprietaryComponents: componentConfig["proprietary_components"].(bool),
+ }
+ }
+ }
+
+ return repo
+}
+
+func setGitlfsHostedRepositoryToResourceData(repo *repository.GitLfsHostedRepository, resourceData *schema.ResourceData) error {
+ resourceData.SetId(repo.Name)
+ resourceData.Set("name", repo.Name)
+ resourceData.Set("online", repo.Online)
+
+ if err := resourceData.Set("storage", flattenHostedStorage(&repo.Storage)); err != nil {
+ return err
+ }
+
+ if repo.Cleanup != nil {
+ if err := resourceData.Set("cleanup", flattenCleanup(repo.Cleanup)); err != nil {
+ return err
+ }
+ }
+
+ if repo.Component != nil {
+ if err := resourceData.Set("component", flattenComponent(repo.Component)); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func resourceGitlfsHostedRepositoryCreate(resourceData *schema.ResourceData, m interface{}) error {
+ client := m.(*nexus.NexusClient)
+
+ repo := getGitlfsHostedRepositoryFromResourceData(resourceData)
+
+ if err := client.Repository.GitLfs.Hosted.Create(repo); err != nil {
+ return err
+ }
+ resourceData.SetId(repo.Name)
+
+ return resourceGitlfsHostedRepositoryRead(resourceData, m)
+}
+
+func resourceGitlfsHostedRepositoryRead(resourceData *schema.ResourceData, m interface{}) error {
+ client := m.(*nexus.NexusClient)
+
+ repo, err := client.Repository.GitLfs.Hosted.Get(resourceData.Id())
+ if err != nil {
+ return err
+ }
+
+ if repo == nil {
+ resourceData.SetId("")
+ return nil
+ }
+
+ return setGitlfsHostedRepositoryToResourceData(repo, resourceData)
+}
+
+func resourceGitlfsHostedRepositoryUpdate(resourceData *schema.ResourceData, m interface{}) error {
+ client := m.(*nexus.NexusClient)
+
+ repoName := resourceData.Id()
+ repo := getGitlfsHostedRepositoryFromResourceData(resourceData)
+
+ if err := client.Repository.GitLfs.Hosted.Update(repoName, repo); err != nil {
+ return err
+ }
+
+ return resourceGitlfsHostedRepositoryRead(resourceData, m)
+}
+
+func resourceGitlfsHostedRepositoryDelete(resourceData *schema.ResourceData, m interface{}) error {
+ client := m.(*nexus.NexusClient)
+ return client.Repository.GitLfs.Hosted.Delete(resourceData.Id())
+}
+
+func resourceGitlfsHostedRepositoryExists(resourceData *schema.ResourceData, m interface{}) (bool, error) {
+ client := m.(*nexus.NexusClient)
+
+ repo, err := client.Repository.GitLfs.Hosted.Get(resourceData.Id())
+ return repo != nil, err
+}
diff --git a/internal/services/repository/resource_repository_gitlfs_hosted_test.go b/internal/services/repository/resource_repository_gitlfs_hosted_test.go
new file mode 100644
index 00000000..f5b8fe00
--- /dev/null
+++ b/internal/services/repository/resource_repository_gitlfs_hosted_test.go
@@ -0,0 +1,82 @@
+package repository_test
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "testing"
+ "text/template"
+
+ "github.com/datadrivers/go-nexus-client/nexus3/schema/repository"
+ "github.com/datadrivers/terraform-provider-nexus/internal/acceptance"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+)
+
+func testAccResourceRepositoryGitlfsHosted() repository.GitLfsHostedRepository {
+ writePolicy := repository.StorageWritePolicyAllow
+
+ return repository.GitLfsHostedRepository{
+ Name: fmt.Sprintf("test-repo-%s", acctest.RandString(10)),
+ Online: true,
+ Storage: repository.HostedStorage{
+ BlobStoreName: "default",
+ StrictContentTypeValidation: true,
+ WritePolicy: &writePolicy,
+ },
+ Cleanup: &repository.Cleanup{
+ PolicyNames: []string{"cleanup-weekly"},
+ },
+ Component: &repository.Component{
+ ProprietaryComponents: true,
+ },
+ }
+}
+
+func testAccResourceRepositoryGitlfsHostedConfig(repo repository.GitLfsHostedRepository) string {
+ buf := &bytes.Buffer{}
+ resourceRepositoryGitlfsHostedTemplate := template.Must(template.New("GitlfsHostedRepository").Funcs(acceptance.TemplateFuncMap).Parse(acceptance.TemplateStringRepositoryGitlfsHosted))
+ if err := resourceRepositoryGitlfsHostedTemplate.Execute(buf, repo); err != nil {
+ panic(err)
+ }
+ return buf.String()
+}
+
+func TestAccResourceRepositoryGitlfsHosted(t *testing.T) {
+ repo := testAccResourceRepositoryGitlfsHosted()
+ resourceName := "nexus_repository_gitlfs_hosted.acceptance"
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { acceptance.AccPreCheck(t) },
+ Providers: acceptance.TestAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config: testAccResourceRepositoryGitlfsHostedConfig(repo),
+ Check: resource.ComposeTestCheckFunc(
+ resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "id", repo.Name),
+ resource.TestCheckResourceAttr(resourceName, "name", repo.Name),
+ resource.TestCheckResourceAttr(resourceName, "online", strconv.FormatBool(repo.Online)),
+ ),
+ resource.ComposeAggregateTestCheckFunc(
+ resource.TestCheckResourceAttr(resourceName, "storage.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "storage.0.blob_store_name", repo.Storage.BlobStoreName),
+ resource.TestCheckResourceAttr(resourceName, "storage.0.strict_content_type_validation", strconv.FormatBool(repo.Storage.StrictContentTypeValidation)),
+ resource.TestCheckResourceAttr(resourceName, "storage.0.write_policy", string(*repo.Storage.WritePolicy)),
+ resource.TestCheckResourceAttr(resourceName, "cleanup.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "cleanup.0.policy_names.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "cleanup.0.policy_names.0", repo.Cleanup.PolicyNames[0]),
+ resource.TestCheckResourceAttr(resourceName, "component.#", "1"),
+ resource.TestCheckResourceAttr(resourceName, "component.0.proprietary_components", strconv.FormatBool(repo.Component.ProprietaryComponents)),
+ ),
+ ),
+ },
+ {
+ ResourceName: resourceName,
+ ImportStateId: repo.Name,
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ },
+ })
+}