Skip to content

Commit

Permalink
feat: read-only api (#108)
Browse files Browse the repository at this point in the history
Co-authored-by: zhuyang <[email protected]>
Co-authored-by: André Möller <[email protected]>
  • Loading branch information
3 people authored Aug 14, 2023
1 parent 02aebbe commit 1f4d54a
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 0 deletions.
3 changes: 3 additions & 0 deletions nexus3/nexus.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nexus3
import (
"github.com/datadrivers/go-nexus-client/nexus3/pkg/blobstore"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/client"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/readonly"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/deprecated"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/repository"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/security"
Expand All @@ -25,6 +26,7 @@ type NexusClient struct {
RoutingRule *RoutingRuleService
Security *security.SecurityService
Script *ScriptService
ReadOnly *readonly.ReadOnlyService
MailConfig *MailConfigService
Deprecated *deprecated.DeprecatedService
}
Expand All @@ -39,6 +41,7 @@ func NewClient(config client.Config) *NexusClient {
RoutingRule: NewRoutingRuleService(client),
Security: security.NewSecurityService(client),
Script: NewScriptService(client),
ReadOnly: readonly.NewReadOnlyService(client),
MailConfig: NewMailConfigService(client),
Deprecated: deprecated.NewDeprecatedService(client),
}
Expand Down
80 changes: 80 additions & 0 deletions nexus3/pkg/readonly/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package readonly

import (
"encoding/json"
"errors"
"fmt"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/client"
"github.com/datadrivers/go-nexus-client/nexus3/schema/readonly"
"net/http"
)

const (
readOnlyAPIEndpoint = client.BasePath + "v1/read-only"
)

var (
ErrAuthenticationRequired = errors.New("authentication is required to change readonly state")
ErrNoChangeToReadOnlyState = errors.New("no change to readonly state")
)

type ReadOnlyService client.Service

func NewReadOnlyService(c *client.Client) *ReadOnlyService {
return &ReadOnlyService{Client: c}
}

func (s *ReadOnlyService) GetState() (*readonly.State, error) {
body, resp, err := s.Client.Get(readOnlyAPIEndpoint, nil)
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("could not read readonly state: HTTP: %d, %s", resp.StatusCode, string(body))
}

var state readonly.State
if err := json.Unmarshal(body, &state); err != nil {
return nil, fmt.Errorf("could not unmarshal readonly state : %v", err)
}

return &state, nil
}

func (s *ReadOnlyService) Freeze() error {
_, resp, err := s.Client.Post(fmt.Sprintf("%s/freeze", readOnlyAPIEndpoint), nil)
if err != nil {
return err
}
return toErr(resp)
}

func (s *ReadOnlyService) Release() error {
_, resp, err := s.Client.Post(fmt.Sprintf("%s/release", readOnlyAPIEndpoint), nil)
if err != nil {
return err
}
return toErr(resp)
}

func (s *ReadOnlyService) ForceRelease() error {
_, resp, err := s.Client.Post(fmt.Sprintf("%s/force-release", readOnlyAPIEndpoint), nil)
if err != nil {
return err
}
return toErr(resp)
}

func toErr(resp *http.Response) error {
switch resp.StatusCode {
case http.StatusNoContent:
return nil
case http.StatusForbidden:
return ErrAuthenticationRequired
case http.StatusNotFound:
return ErrNoChangeToReadOnlyState
default:
return errors.New(fmt.Sprintf("unexpected status code %d", resp.StatusCode))
}
}
69 changes: 69 additions & 0 deletions nexus3/pkg/readonly/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package readonly

import (
"github.com/datadrivers/go-nexus-client/nexus3/pkg/client"
"github.com/datadrivers/go-nexus-client/nexus3/pkg/tools"
"github.com/stretchr/testify/assert"
"testing"
)

var (
testClient *client.Client = nil
)

func getTestClient() *client.Client {
if testClient != nil {
return testClient
}
return client.NewClient(getDefaultConfig())
}

func getTestService() *ReadOnlyService {
return NewReadOnlyService(getTestClient())
}

func getDefaultConfig() client.Config {
return client.Config{
Insecure: tools.GetEnv("NEXUS_INSECURE_SKIP_VERIFY", true).(bool),
Password: tools.GetEnv("NEXUS_PASSWORD", "admin123").(string),
URL: tools.GetEnv("NEXUS_URL", "http://127.0.0.1:8081").(string),
Username: tools.GetEnv("NEXUS_USRNAME", "admin").(string),
}
}

func TestFreezeAndReleaseReadOnlyState(t *testing.T) {
s := getTestService()

state, err := s.GetState()
if err != nil {
assert.Failf(t, "fail to retreive readonly state", err.Error())
return
}

if state.Frozen {
// try release first
if err = s.Release(); err != nil && err != ErrNoChangeToReadOnlyState {
assert.Failf(t, "unexpected error when try to release", err.Error())
}
}

// freeze
if err = s.Freeze(); err != nil && err != ErrNoChangeToReadOnlyState {
assert.Failf(t, "unexpected error when try to freeze", err.Error())
}

// release
if err = s.Release(); err != nil && err != ErrNoChangeToReadOnlyState {
assert.Failf(t, "unexpected error when try to release", err.Error())
}

// freeze again
if err = s.Freeze(); err != nil && err != ErrNoChangeToReadOnlyState {
assert.Failf(t, "unexpected error when try to freeze again", err.Error())
}

// force release
if err = s.ForceRelease(); err != nil && err != ErrNoChangeToReadOnlyState {
assert.Failf(t, "unexpected error when try to force release", err.Error())
}
}
7 changes: 7 additions & 0 deletions nexus3/schema/readonly/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package readonly

type State struct {
SummaryReason string `json:"summaryReason"`
SystemInitiated bool `json:"systemInitiated"`
Frozen bool `json:"frozen"`
}

0 comments on commit 1f4d54a

Please sign in to comment.