github.com/aiven/aiven-go-client@v1.36.0/service_user.go (about) 1 package aiven 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "reflect" 8 ) 9 10 const ( 11 UpdateOperationResetCredentials = "reset-credentials" 12 UpdateOperationSetAccessControl = "set-access-control" 13 ) 14 15 type ( 16 // ServiceUser is the representation of a Service User in the Aiven API. 17 ServiceUser struct { 18 Username string `json:"username"` 19 Password string `json:"password"` 20 Type string `json:"type"` 21 AccessCert string `json:"access_cert"` 22 AccessKey string `json:"access_key"` 23 AccessCertNotValidAfterTime string `json:"access_cert_not_valid_after_time"` 24 AccessControl AccessControl `json:"access_control,omitempty"` 25 } 26 27 AccessControl struct { 28 M3Group *string `json:"m3_group"` 29 RedisACLCategories []string `json:"redis_acl_categories"` 30 RedisACLCommands []string `json:"redis_acl_commands"` 31 RedisACLKeys []string `json:"redis_acl_keys"` 32 RedisACLChannels []string `json:"redis_acl_channels"` 33 PostgresAllowReplication *bool `json:"pg_allow_replication"` 34 } 35 36 // ServiceUsersHandler is the client that interacts with the ServiceUsers 37 // endpoints. 38 ServiceUsersHandler struct { 39 client *Client 40 } 41 42 // CreateServiceUserRequest are the parameters required to create a 43 // ServiceUser. 44 CreateServiceUserRequest struct { 45 Username string `json:"username"` 46 Authentication *string `json:"authentication,omitempty"` 47 AccessControl *AccessControl `json:"access_control,omitempty"` 48 } 49 50 // ModifyServiceUserRequest params required to modify a ServiceUser 51 ModifyServiceUserRequest struct { 52 Operation *string `json:"operation"` 53 Authentication *string `json:"authentication,omitempty"` 54 NewPassword *string `json:"new_password,omitempty"` 55 AccessControl *AccessControl `json:"access_control,omitempty"` 56 } 57 58 // ServiceUserResponse represents the response after creating a ServiceUser. 59 ServiceUserResponse struct { 60 APIResponse 61 User *ServiceUser `json:"user"` 62 } 63 ) 64 65 // MarshalJSON implements a custom marshalling process for AccessControl where only null fields are omitted 66 func (ac AccessControl) MarshalJSON() ([]byte, error) { 67 out := make(map[string]interface{}) 68 69 fields := reflect.TypeOf(ac) 70 values := reflect.ValueOf(ac) 71 72 for i := 0; i < fields.NumField(); i++ { 73 field := fields.Field(i) 74 value := values.Field(i) 75 76 switch value.Kind() { 77 case reflect.Pointer, reflect.Slice: // *string, *bool, []string 78 if !value.IsNil() { 79 jsonName := field.Tag.Get("json") 80 out[jsonName] = value.Interface() 81 } 82 } 83 } 84 return json.Marshal(out) 85 } 86 87 // Create creates the given User on Aiven. 88 func (h *ServiceUsersHandler) Create(project, service string, req CreateServiceUserRequest) (*ServiceUser, error) { 89 path := buildPath("project", project, "service", service, "user") 90 bts, err := h.client.doPostRequest(path, req) 91 if err != nil { 92 return nil, err 93 } 94 95 var r ServiceUserResponse 96 errR := checkAPIResponse(bts, &r) 97 98 return r.User, errR 99 } 100 101 // List Service Users for given service in Aiven. 102 func (h *ServiceUsersHandler) List(project, serviceName string) ([]*ServiceUser, error) { 103 // Aiven API does not provide list operation for service users, need to get them via service info instead 104 service, err := h.client.Services.Get(project, serviceName) 105 if err != nil { 106 return nil, err 107 } 108 109 return service.Users, nil 110 } 111 112 // Get specific Service User in Aiven. 113 func (h *ServiceUsersHandler) Get(project, serviceName, username string) (*ServiceUser, error) { 114 // Aiven API does not provide get operation for service users, need to get them via list instead 115 users, err := h.List(project, serviceName) 116 if err != nil { 117 return nil, err 118 } 119 for _, user := range users { 120 if user.Username == username { 121 return user, nil 122 } 123 } 124 125 err = Error{Message: fmt.Sprintf("Service user with username %v not found", username), Status: 404} 126 return nil, err 127 } 128 129 // Update modifies the given Service User in Aiven. 130 func (h *ServiceUsersHandler) Update(project, service, username string, update ModifyServiceUserRequest) (*ServiceUser, error) { 131 var DefaultOperation = UpdateOperationResetCredentials 132 if update.Operation == nil { 133 update.Operation = &DefaultOperation 134 } 135 136 if update.AccessControl != nil && *update.Operation != UpdateOperationSetAccessControl { 137 return nil, errors.New("wrong operation for updating access control") 138 } 139 140 if (update.NewPassword != nil || update.Authentication != nil) && *update.Operation != UpdateOperationResetCredentials { 141 return nil, errors.New("wrong operation for updating credentials") 142 } 143 path := buildPath("project", project, "service", service, "user", username) 144 svc, err := h.client.doPutRequest(path, update) 145 if err != nil { 146 return nil, err 147 } 148 149 var r ServiceResponse 150 errR := checkAPIResponse(svc, &r) 151 if errR == nil { 152 for _, user := range r.Service.Users { 153 if user.Username == username { 154 return user, nil 155 } 156 } 157 return nil, errors.New("user not found") 158 } 159 160 return nil, errR 161 } 162 163 // Delete deletes the given Service User in Aiven. 164 func (h *ServiceUsersHandler) Delete(project, service, user string) error { 165 path := buildPath("project", project, "service", service, "user", user) 166 bts, err := h.client.doDeleteRequest(path, nil) 167 if err != nil { 168 return err 169 } 170 171 return checkAPIResponse(bts, nil) 172 }