本文整理汇总了Golang中k8s/io/kubernetes/pkg/api/rest.BeforeUpdate函数的典型用法代码示例。如果您正苦于以下问题:Golang BeforeUpdate函数的具体用法?Golang BeforeUpdate怎么用?Golang BeforeUpdate使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了BeforeUpdate函数的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: updateRoleBinding
func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.RoleBinding, bool, error) {
old, err := m.Get(ctx, name)
if err != nil {
return nil, false, err
}
obj, err := objInfo.UpdatedObject(ctx, old)
if err != nil {
return nil, false, err
}
roleBinding, ok := obj.(*authorizationapi.RoleBinding)
if !ok {
return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj))
}
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil {
return nil, false, err
}
if err := m.validateReferentialIntegrity(ctx, roleBinding); err != nil {
return nil, false, err
}
if !allowEscalation {
if err := m.confirmNoEscalation(ctx, roleBinding); err != nil {
return nil, false, err
}
}
policyBinding, err := m.getPolicyBindingForPolicy(ctx, roleBinding.RoleRef.Namespace, allowEscalation)
if err != nil {
return nil, false, err
}
previousRoleBinding, exists := policyBinding.RoleBindings[roleBinding.Name]
if !exists {
return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), roleBinding.Name)
}
if previousRoleBinding.RoleRef != roleBinding.RoleRef {
return nil, false, errors.New("roleBinding.RoleRef may not be modified")
}
if kapi.Semantic.DeepEqual(previousRoleBinding, roleBinding) {
return roleBinding, false, nil
}
roleBinding.ResourceVersion = policyBinding.ResourceVersion
policyBinding.RoleBindings[roleBinding.Name] = roleBinding
policyBinding.LastModified = unversioned.Now()
if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil {
return nil, false, err
}
return roleBinding, false, nil
}
示例2: updateRole
func (m *VirtualStorage) updateRole(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.Role, bool, error) {
old, err := m.Get(ctx, name)
if err != nil {
return nil, false, err
}
obj, err := objInfo.UpdatedObject(ctx, old)
if err != nil {
return nil, false, err
}
role, ok := obj.(*authorizationapi.Role)
if !ok {
return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj))
}
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil {
return nil, false, err
}
if !allowEscalation {
if err := rulevalidation.ConfirmNoEscalation(ctx, authorizationapi.Resource("role"), role.Name, m.RuleResolver, authorizationinterfaces.NewLocalRoleAdapter(role)); err != nil {
return nil, false, err
}
}
policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
if err != nil && kapierrors.IsNotFound(err) {
return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("role"), role.Name)
}
if err != nil {
return nil, false, err
}
oldRole, exists := policy.Roles[role.Name]
if !exists {
return nil, false, kapierrors.NewNotFound(authorizationapi.Resource("role"), role.Name)
}
// non-mutating change
if kapi.Semantic.DeepEqual(oldRole, role) {
return role, false, nil
}
role.ResourceVersion = policy.ResourceVersion
policy.Roles[role.Name] = role
policy.LastModified = unversioned.Now()
if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil {
return nil, false, err
}
return role, false, nil
}
示例3: Update
func (r *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
istag, ok := obj.(*api.ImageStreamTag)
if !ok {
return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not an ImageStreamTag: %#v", obj))
}
old, err := r.Get(ctx, istag.Name)
if err != nil {
return nil, false, err
}
if err := rest.BeforeUpdate(Strategy, ctx, obj, old); err != nil {
return nil, false, err
}
// we only allow updates of annotations, so lets find the correct image stream and update it.
name, tag, err := nameAndTag(istag.Name)
if err != nil {
return nil, false, err
}
imageStream, err := r.imageStreamRegistry.GetImageStream(ctx, name)
if imageStream.Spec.Tags == nil {
imageStream.Spec.Tags = map[string]api.TagReference{}
}
tagRef := imageStream.Spec.Tags[tag]
tagRef.Annotations = istag.Annotations
imageStream.Spec.Tags[tag] = tagRef
newImageStream, err := r.imageStreamRegistry.UpdateImageStream(ctx, imageStream)
if err != nil {
return nil, false, err
}
image, err := r.imageFor(ctx, tag, newImageStream)
if err != nil {
return nil, false, err
}
newISTag, err := newISTag(tag, newImageStream, image)
return newISTag, false, err
}
示例4: Update
func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
role, ok := obj.(*authorizationapi.Role)
if !ok {
return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj))
}
old, err := m.Get(ctx, role.Name)
if err != nil {
return nil, false, err
}
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil {
return nil, false, err
}
policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
if err != nil && kapierrors.IsNotFound(err) {
return nil, false, kapierrors.NewNotFound("Role", role.Name)
}
if err != nil {
return nil, false, err
}
if _, exists := policy.Roles[role.Name]; !exists {
return nil, false, kapierrors.NewNotFound("Role", role.Name)
}
role.ResourceVersion = policy.ResourceVersion
policy.Roles[role.Name] = role
policy.LastModified = util.Now()
if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil {
return nil, false, err
}
return role, false, nil
}
示例5: Update
// Update performs an atomic update and set of the object. Returns the result of the update
// or an error. If the registry allows create-on-update, the create flow will be executed.
// A bool is returned along with the object and any errors, to indicate object creation.
func (e *Store) Update(ctx api.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
key, err := e.KeyFunc(ctx, name)
if err != nil {
return nil, false, err
}
var (
creatingObj runtime.Object
creating = false
)
storagePreconditions := &storage.Preconditions{}
if preconditions := objInfo.Preconditions(); preconditions != nil {
storagePreconditions.UID = preconditions.UID
}
out := e.NewFunc()
// deleteObj is only used in case a deletion is carried out
var deleteObj runtime.Object
err = e.Storage.GuaranteedUpdate(ctx, key, out, true, storagePreconditions, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
// Given the existing object, get the new object
obj, err := objInfo.UpdatedObject(ctx, existing)
if err != nil {
return nil, nil, err
}
// If AllowUnconditionalUpdate() is true and the object specified by the user does not have a resource version,
// then we populate it with the latest version.
// Else, we check that the version specified by the user matches the version of latest storage object.
resourceVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil {
return nil, nil, err
}
doUnconditionalUpdate := resourceVersion == 0 && e.UpdateStrategy.AllowUnconditionalUpdate()
version, err := e.Storage.Versioner().ObjectResourceVersion(existing)
if err != nil {
return nil, nil, err
}
if version == 0 {
if !e.UpdateStrategy.AllowCreateOnUpdate() {
return nil, nil, kubeerr.NewNotFound(e.QualifiedResource, name)
}
creating = true
creatingObj = obj
if err := rest.BeforeCreate(e.CreateStrategy, ctx, obj); err != nil {
return nil, nil, err
}
ttl, err := e.calculateTTL(obj, 0, false)
if err != nil {
return nil, nil, err
}
return obj, &ttl, nil
}
creating = false
creatingObj = nil
if doUnconditionalUpdate {
// Update the object's resource version to match the latest storage object's resource version.
err = e.Storage.Versioner().UpdateObject(obj, res.ResourceVersion)
if err != nil {
return nil, nil, err
}
} else {
// Check if the object's resource version matches the latest resource version.
newVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil {
return nil, nil, err
}
if newVersion == 0 {
// TODO: The Invalid error should has a field for Resource.
// After that field is added, we should fill the Resource and
// leave the Kind field empty. See the discussion in #18526.
qualifiedKind := unversioned.GroupKind{Group: e.QualifiedResource.Group, Kind: e.QualifiedResource.Resource}
fieldErrList := field.ErrorList{field.Invalid(field.NewPath("metadata").Child("resourceVersion"), newVersion, "must be specified for an update")}
return nil, nil, kubeerr.NewInvalid(qualifiedKind, name, fieldErrList)
}
if newVersion != version {
return nil, nil, kubeerr.NewConflict(e.QualifiedResource, name, fmt.Errorf(OptimisticLockErrorMsg))
}
}
if err := rest.BeforeUpdate(e.UpdateStrategy, ctx, obj, existing); err != nil {
return nil, nil, err
}
delete := e.shouldDelete(ctx, key, obj, existing)
if delete {
deleteObj = obj
return nil, nil, errEmptiedFinalizers
}
ttl, err := e.calculateTTL(obj, res.TTL, true)
if err != nil {
return nil, nil, err
}
if int64(ttl) != res.TTL {
return obj, &ttl, nil
}
return obj, nil, nil
//.........这里部分代码省略.........
示例6: Update
// Update performs an atomic update and set of the object. Returns the result of the update
// or an error. If the registry allows create-on-update, the create flow will be executed.
// A bool is returned along with the object and any errors, to indicate object creation.
func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) {
trace := util.NewTrace("Update " + reflect.TypeOf(obj).String())
defer trace.LogIfLong(time.Second)
name, err := e.ObjectNameFunc(obj)
if err != nil {
return nil, false, err
}
key, err := e.KeyFunc(ctx, name)
if err != nil {
return nil, false, err
}
// If AllowUnconditionalUpdate() is true and the object specified by the user does not have a resource version,
// then we populate it with the latest version.
// Else, we check that the version specified by the user matches the version of latest etcd object.
resourceVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil {
return nil, false, err
}
doUnconditionalUpdate := resourceVersion == 0 && e.UpdateStrategy.AllowUnconditionalUpdate()
// TODO: expose TTL
creating := false
out := e.NewFunc()
err = e.Storage.GuaranteedUpdate(ctx, key, out, true, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
version, err := e.Storage.Versioner().ObjectResourceVersion(existing)
if err != nil {
return nil, nil, err
}
if version == 0 {
if !e.UpdateStrategy.AllowCreateOnUpdate() {
return nil, nil, kubeerr.NewNotFound(e.EndpointName, name)
}
creating = true
if err := rest.BeforeCreate(e.CreateStrategy, ctx, obj); err != nil {
return nil, nil, err
}
ttl, err := e.calculateTTL(obj, 0, false)
if err != nil {
return nil, nil, err
}
return obj, &ttl, nil
}
creating = false
if doUnconditionalUpdate {
// Update the object's resource version to match the latest etcd object's resource version.
err = e.Storage.Versioner().UpdateObject(obj, res.Expiration, res.ResourceVersion)
if err != nil {
return nil, nil, err
}
} else {
// Check if the object's resource version matches the latest resource version.
newVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil {
return nil, nil, err
}
if newVersion != version {
return nil, nil, kubeerr.NewConflict(e.EndpointName, name, fmt.Errorf("the object has been modified; please apply your changes to the latest version and try again"))
}
}
if err := rest.BeforeUpdate(e.UpdateStrategy, ctx, obj, existing); err != nil {
return nil, nil, err
}
ttl, err := e.calculateTTL(obj, res.TTL, true)
if err != nil {
return nil, nil, err
}
if int64(ttl) != res.TTL {
return obj, &ttl, nil
}
return obj, nil, nil
})
if err != nil {
if creating {
err = etcderr.InterpretCreateError(err, e.EndpointName, name)
err = rest.CheckGeneratedNameError(e.CreateStrategy, err, obj)
} else {
err = etcderr.InterpretUpdateError(err, e.EndpointName, name)
}
return nil, false, err
}
if creating {
if e.AfterCreate != nil {
if err := e.AfterCreate(out); err != nil {
return nil, false, err
}
}
} else {
if e.AfterUpdate != nil {
if err := e.AfterUpdate(out); err != nil {
return nil, false, err
}
}
}
if e.Decorator != nil {
if err := e.Decorator(obj); err != nil {
return nil, false, err
//.........这里部分代码省略.........
示例7: createOrUpdate
func (s *REST) createOrUpdate(ctx kapi.Context, obj runtime.Object, forceCreate bool) (runtime.Object, bool, error) {
mapping := obj.(*api.UserIdentityMapping)
identity, identityErr, oldUser, oldUserErr, oldMapping, oldMappingErr := s.getRelatedObjects(ctx, mapping.Name)
// Ensure we didn't get any errors other than NotFound errors
if !(oldMappingErr == nil || kerrs.IsNotFound(oldMappingErr)) {
return nil, false, oldMappingErr
}
if !(identityErr == nil || kerrs.IsNotFound(identityErr)) {
return nil, false, identityErr
}
if !(oldUserErr == nil || kerrs.IsNotFound(oldUserErr)) {
return nil, false, oldUserErr
}
// If we expect to be creating, fail if the mapping already existed
if forceCreate && oldMappingErr == nil {
return nil, false, kerrs.NewAlreadyExists(api.Resource("useridentitymapping"), oldMapping.Name)
}
// Allow update to create if missing
creating := forceCreate || kerrs.IsNotFound(oldMappingErr)
if creating {
// Pre-create checks with no access to oldMapping
if err := rest.BeforeCreate(Strategy, ctx, mapping); err != nil {
return nil, false, err
}
// Ensure resource version is not specified
if len(mapping.ResourceVersion) > 0 {
return nil, false, kerrs.NewNotFound(api.Resource("useridentitymapping"), mapping.Name)
}
} else {
// Pre-update checks with access to oldMapping
if err := rest.BeforeUpdate(Strategy, ctx, mapping, oldMapping); err != nil {
return nil, false, err
}
// Ensure resource versions match
if len(mapping.ResourceVersion) > 0 && mapping.ResourceVersion != oldMapping.ResourceVersion {
return nil, false, kerrs.NewConflict(api.Resource("useridentitymapping"), mapping.Name, fmt.Errorf("the resource was updated to %s", oldMapping.ResourceVersion))
}
// If we're "updating" to the user we're already pointing to, we're already done
if mapping.User.Name == oldMapping.User.Name {
return oldMapping, false, nil
}
}
// Validate identity
if kerrs.IsNotFound(identityErr) {
errs := field.ErrorList{field.Invalid(field.NewPath("identity", "name"), mapping.Identity.Name, "referenced identity does not exist")}
return nil, false, kerrs.NewInvalid(api.Kind("UserIdentityMapping"), mapping.Name, errs)
}
// Get new user
newUser, err := s.userRegistry.GetUser(ctx, mapping.User.Name)
if kerrs.IsNotFound(err) {
errs := field.ErrorList{field.Invalid(field.NewPath("user", "name"), mapping.User.Name, "referenced user does not exist")}
return nil, false, kerrs.NewInvalid(api.Kind("UserIdentityMapping"), mapping.Name, errs)
}
if err != nil {
return nil, false, err
}
// Update the new user to point at the identity. If this fails, Update is re-entrant
if addIdentityToUser(identity, newUser) {
if _, err := s.userRegistry.UpdateUser(ctx, newUser); err != nil {
return nil, false, err
}
}
// Update the identity to point at the new user. If this fails. Update is re-entrant
if setIdentityUser(identity, newUser) {
if updatedIdentity, err := s.identityRegistry.UpdateIdentity(ctx, identity); err != nil {
return nil, false, err
} else {
identity = updatedIdentity
}
}
// At this point, the mapping for the identity has been updated to the new user
// Everything past this point is cleanup
// Update the old user to no longer point at the identity.
// If this fails, log the error, but continue, because Update is no longer re-entrant
if oldUser != nil && removeIdentityFromUser(identity, oldUser) {
if _, err := s.userRegistry.UpdateUser(ctx, oldUser); err != nil {
utilruntime.HandleError(fmt.Errorf("error removing identity reference %s from user %s: %v", identity.Name, oldUser.Name, err))
}
}
updatedMapping, err := mappingFor(newUser, identity)
return updatedMapping, creating, err
}
示例8: TestBeforeUpdate
// TODO: This should be done on types that are not part of our API
func TestBeforeUpdate(t *testing.T) {
testCases := []struct {
name string
tweakSvc func(oldSvc, newSvc *api.Service) // given basic valid services, each test case can customize them
expectErr bool
}{
{
name: "no change",
tweakSvc: func(oldSvc, newSvc *api.Service) {
// nothing
},
expectErr: false,
},
{
name: "change port",
tweakSvc: func(oldSvc, newSvc *api.Service) {
newSvc.Spec.Ports[0].Port++
},
expectErr: false,
},
{
name: "bad namespace",
tweakSvc: func(oldSvc, newSvc *api.Service) {
newSvc.Namespace = "#$%%invalid"
},
expectErr: true,
},
{
name: "change name",
tweakSvc: func(oldSvc, newSvc *api.Service) {
newSvc.Name += "2"
},
expectErr: true,
},
{
name: "change ClusterIP",
tweakSvc: func(oldSvc, newSvc *api.Service) {
oldSvc.Spec.ClusterIP = "1.2.3.4"
newSvc.Spec.ClusterIP = "4.3.2.1"
},
expectErr: true,
},
{
name: "change selectpor",
tweakSvc: func(oldSvc, newSvc *api.Service) {
newSvc.Spec.Selector = map[string]string{"newkey": "newvalue"}
},
expectErr: false,
},
}
for _, tc := range testCases {
oldSvc := makeValidService()
newSvc := makeValidService()
tc.tweakSvc(&oldSvc, &newSvc)
ctx := api.NewDefaultContext()
err := rest.BeforeUpdate(Strategy, ctx, runtime.Object(&oldSvc), runtime.Object(&newSvc))
if tc.expectErr && err == nil {
t.Errorf("unexpected non-error for %q", tc.name)
}
if !tc.expectErr && err != nil {
t.Errorf("unexpected error for %q: %v", tc.name, err)
}
}
}
示例9: Update
func (r *REST) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
istag, ok := obj.(*api.ImageStreamTag)
if !ok {
return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not an ImageStreamTag: %#v", obj))
}
name, tag, err := nameAndTag(istag.Name)
if err != nil {
return nil, false, err
}
imageStream, err := r.imageStreamRegistry.GetImageStream(ctx, name)
if err != nil {
if !kapierrors.IsNotFound(err) || len(istag.ResourceVersion) != 0 {
return nil, false, err
}
namespace, ok := kapi.NamespaceFrom(ctx)
if !ok {
return nil, false, kapierrors.NewBadRequest("namespace is required on ImageStreamTags")
}
imageStream = &api.ImageStream{
ObjectMeta: kapi.ObjectMeta{Namespace: namespace, Name: name},
}
}
// check for conflict
if len(istag.ResourceVersion) == 0 {
istag.ResourceVersion = imageStream.ResourceVersion
}
if imageStream.ResourceVersion != istag.ResourceVersion {
return nil, false, kapierrors.NewConflict(api.Resource("imagestreamtags"), istag.Name, fmt.Errorf("another caller has updated the resource version to %s", imageStream.ResourceVersion))
}
// create the synthetic old istag
old, err := newISTag(tag, imageStream, nil, true)
if err != nil {
return nil, false, err
}
if len(istag.ResourceVersion) == 0 {
if err := rest.BeforeCreate(Strategy, ctx, obj); err != nil {
return nil, false, err
}
} else {
if err := rest.BeforeUpdate(Strategy, ctx, obj, old); err != nil {
return nil, false, err
}
}
// update the spec tag
if imageStream.Spec.Tags == nil {
imageStream.Spec.Tags = map[string]api.TagReference{}
}
tagRef, exists := imageStream.Spec.Tags[tag]
// if the caller set tag, override the spec tag
if istag.Tag != nil {
tagRef = *istag.Tag
tagRef.Name = tag
}
tagRef.Annotations = istag.Annotations
imageStream.Spec.Tags[tag] = tagRef
// mutate the image stream
var newImageStream *api.ImageStream
if imageStream.CreationTimestamp.IsZero() {
newImageStream, err = r.imageStreamRegistry.CreateImageStream(ctx, imageStream)
} else {
newImageStream, err = r.imageStreamRegistry.UpdateImageStream(ctx, imageStream)
}
if err != nil {
return nil, false, err
}
image, err := r.imageFor(ctx, tag, newImageStream)
if err != nil {
if !kapierrors.IsNotFound(err) {
return nil, false, err
}
}
newISTag, err := newISTag(tag, newImageStream, image, true)
return newISTag, !exists, err
}
示例10: updateRole
func (m *VirtualStorage) updateRole(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.Role, bool, error) {
var updatedRole *authorizationapi.Role
var roleConflicted = false
// Retry if the policy update hits a conflict
if err := kclient.RetryOnConflict(kclient.DefaultRetry, func() error {
policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
if kapierrors.IsNotFound(err) {
return kapierrors.NewNotFound(m.Resource, name)
}
if err != nil {
return err
}
oldRole, exists := policy.Roles[name]
if !exists {
return kapierrors.NewNotFound(m.Resource, name)
}
obj, err := objInfo.UpdatedObject(ctx, oldRole)
if err != nil {
return err
}
role, ok := obj.(*authorizationapi.Role)
if !ok {
return kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role: %#v", obj))
}
if len(role.ResourceVersion) == 0 && m.UpdateStrategy.AllowUnconditionalUpdate() {
role.ResourceVersion = oldRole.ResourceVersion
}
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, oldRole); err != nil {
return err
}
if !allowEscalation {
if err := rulevalidation.ConfirmNoEscalation(ctx, m.Resource, role.Name, m.RuleResolver, m.CachedRuleResolver, authorizationinterfaces.NewLocalRoleAdapter(role)); err != nil {
return err
}
}
// conflict detection
if role.ResourceVersion != oldRole.ResourceVersion {
// mark as a conflict err, but return an untyped error to escape the retry
roleConflicted = true
return errors.New(registry.OptimisticLockErrorMsg)
}
// non-mutating change
if kapi.Semantic.DeepEqual(oldRole, role) {
updatedRole = role
return nil
}
role.ResourceVersion = policy.ResourceVersion
policy.Roles[role.Name] = role
policy.LastModified = unversioned.Now()
if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil {
return err
}
updatedRole = role
return nil
}); err != nil {
if roleConflicted {
// construct the typed conflict error
return nil, false, kapierrors.NewConflict(authorizationapi.Resource("name"), name, err)
}
return nil, false, err
}
return updatedRole, false, nil
}
示例11: updateRoleBinding
func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, name string, objInfo rest.UpdatedObjectInfo, allowEscalation bool) (*authorizationapi.RoleBinding, bool, error) {
var updatedRoleBinding *authorizationapi.RoleBinding
var roleBindingConflicted = false
if err := kclient.RetryOnConflict(kclient.DefaultRetry, func() error {
// Do an initial fetch
old, err := m.Get(ctx, name)
if err != nil {
return err
}
oldRoleBinding, exists := old.(*authorizationapi.RoleBinding)
if !exists {
return kapierrors.NewBadRequest(fmt.Sprintf("old obj is not a role binding: %#v", old))
}
// get the updated object, so we know what namespace we're binding against
obj, err := objInfo.UpdatedObject(ctx, old)
if err != nil {
return err
}
roleBinding, ok := obj.(*authorizationapi.RoleBinding)
if !ok {
return kapierrors.NewBadRequest(fmt.Sprintf("obj is not a role binding: %#v", obj))
}
// now that we know which roleRef we want to go to, fetch the policyBinding we'll actually be updating, and re-get the oldRoleBinding
policyBinding, err := m.getPolicyBindingForPolicy(ctx, roleBinding.RoleRef.Namespace, allowEscalation)
if err != nil {
return err
}
oldRoleBinding, exists = policyBinding.RoleBindings[roleBinding.Name]
if !exists {
return kapierrors.NewNotFound(authorizationapi.Resource("rolebinding"), roleBinding.Name)
}
if len(roleBinding.ResourceVersion) == 0 && m.UpdateStrategy.AllowUnconditionalUpdate() {
roleBinding.ResourceVersion = oldRoleBinding.ResourceVersion
}
if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, oldRoleBinding); err != nil {
return err
}
if !allowEscalation {
if err := m.confirmNoEscalation(ctx, roleBinding); err != nil {
return err
}
}
// conflict detection
if roleBinding.ResourceVersion != oldRoleBinding.ResourceVersion {
// mark as a conflict err, but return an untyped error to escape the retry
roleBindingConflicted = true
return errors.New(registry.OptimisticLockErrorMsg)
}
// non-mutating change
if kapi.Semantic.DeepEqual(oldRoleBinding, roleBinding) {
updatedRoleBinding = roleBinding
return nil
}
roleBinding.ResourceVersion = policyBinding.ResourceVersion
policyBinding.RoleBindings[roleBinding.Name] = roleBinding
policyBinding.LastModified = unversioned.Now()
if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil {
return err
}
updatedRoleBinding = roleBinding
return nil
}); err != nil {
if roleBindingConflicted {
// construct the typed conflict error
return nil, false, kapierrors.NewConflict(authorizationapi.Resource("rolebinding"), name, err)
}
return nil, false, err
}
return updatedRoleBinding, false, nil
}
示例12: Update
// Update performs an atomic update and set of the object. Returns the result of the update
// or an error. If the registry allows create-on-update, the create flow will be executed.
// A bool is returned along with the object and any errors, to indicate object creation.
func (e *Etcd) Update(ctx api.Context, obj runtime.Object) (runtime.Object, bool, error) {
name, err := e.ObjectNameFunc(obj)
if err != nil {
return nil, false, err
}
key, err := e.KeyFunc(ctx, name)
if err != nil {
return nil, false, err
}
// If AllowUnconditionalUpdate() is true and the object specified by the user does not have a resource version,
// then we populate it with the latest version.
// Else, we check that the version specified by the user matches the version of latest etcd object.
resourceVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil {
return nil, false, err
}
doUnconditionalUpdate := resourceVersion == 0 && e.UpdateStrategy.AllowUnconditionalUpdate()
// TODO: expose TTL
creating := false
out := e.NewFunc()
err = e.Storage.GuaranteedUpdate(ctx, key, out, true, func(existing runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) {
// Since we return 'obj' from this function and it can be modified outside this
// function, we are resetting resourceVersion to the initial value here.
//
// TODO: In fact, we should probably return a DeepCopy of obj in all places.
err := e.Storage.Versioner().UpdateObject(obj, nil, resourceVersion)
if err != nil {
return nil, nil, err
}
version, err := e.Storage.Versioner().ObjectResourceVersion(existing)
if err != nil {
return nil, nil, err
}
if version == 0 {
if !e.UpdateStrategy.AllowCreateOnUpdate() {
return nil, nil, kubeerr.NewNotFound(e.QualifiedResource, name)
}
creating = true
if err := rest.BeforeCreate(e.CreateStrategy, ctx, obj); err != nil {
return nil, nil, err
}
ttl, err := e.calculateTTL(obj, 0, false)
if err != nil {
return nil, nil, err
}
return obj, &ttl, nil
}
creating = false
if doUnconditionalUpdate {
// Update the object's resource version to match the latest etcd object's resource version.
err = e.Storage.Versioner().UpdateObject(obj, res.Expiration, res.ResourceVersion)
if err != nil {
return nil, nil, err
}
} else {
// Check if the object's resource version matches the latest resource version.
newVersion, err := e.Storage.Versioner().ObjectResourceVersion(obj)
if err != nil {
return nil, nil, err
}
if newVersion == 0 {
// TODO: The Invalid error should has a field for Resource.
// After that field is added, we should fill the Resource and
// leave the Kind field empty. See the discussion in #18526.
qualifiedKind := unversioned.GroupKind{e.QualifiedResource.Group, e.QualifiedResource.Resource}
fieldErrList := field.ErrorList{field.Invalid(field.NewPath("metadata").Child("resourceVersion"), newVersion, "must be specified for an update")}
return nil, nil, kubeerr.NewInvalid(qualifiedKind, name, fieldErrList)
}
if newVersion != version {
return nil, nil, kubeerr.NewConflict(e.QualifiedResource, name, fmt.Errorf("the object has been modified; please apply your changes to the latest version and try again"))
}
}
if err := rest.BeforeUpdate(e.UpdateStrategy, ctx, obj, existing); err != nil {
return nil, nil, err
}
ttl, err := e.calculateTTL(obj, res.TTL, true)
if err != nil {
return nil, nil, err
}
if int64(ttl) != res.TTL {
return obj, &ttl, nil
}
return obj, nil, nil
})
if err != nil {
if creating {
err = etcderr.InterpretCreateError(err, e.QualifiedResource, name)
err = rest.CheckGeneratedNameError(e.CreateStrategy, err, obj)
} else {
err = etcderr.InterpretUpdateError(err, e.QualifiedResource, name)
}
return nil, false, err
}
if creating {
//.........这里部分代码省略.........
示例13: Update
func (r *REST) Update(ctx kapi.Context, tagName string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
name, tag, err := nameAndTag(tagName)
if err != nil {
return nil, false, err
}
create := false
imageStream, err := r.imageStreamRegistry.GetImageStream(ctx, name)
if err != nil {
if !kapierrors.IsNotFound(err) {
return nil, false, err
}
namespace, ok := kapi.NamespaceFrom(ctx)
if !ok {
return nil, false, kapierrors.NewBadRequest("namespace is required on ImageStreamTags")
}
imageStream = &api.ImageStream{
ObjectMeta: kapi.ObjectMeta{
Namespace: namespace,
Name: name,
},
}
kapi.FillObjectMetaSystemFields(ctx, &imageStream.ObjectMeta)
create = true
}
// create the synthetic old istag
old, err := newISTag(tag, imageStream, nil, true)
if err != nil {
return nil, false, err
}
obj, err := objInfo.UpdatedObject(ctx, old)
if err != nil {
return nil, false, err
}
istag, ok := obj.(*api.ImageStreamTag)
if !ok {
return nil, false, kapierrors.NewBadRequest(fmt.Sprintf("obj is not an ImageStreamTag: %#v", obj))
}
// check for conflict
switch {
case len(istag.ResourceVersion) == 0:
// should disallow blind PUT, but this was previously supported
istag.ResourceVersion = imageStream.ResourceVersion
case len(imageStream.ResourceVersion) == 0:
// image stream did not exist, cannot update
return nil, false, kapierrors.NewNotFound(api.Resource("imagestreamtags"), tagName)
case imageStream.ResourceVersion != istag.ResourceVersion:
// conflicting input and output
return nil, false, kapierrors.NewConflict(api.Resource("imagestreamtags"), istag.Name, fmt.Errorf("another caller has updated the resource version to %s", imageStream.ResourceVersion))
}
if create {
if err := rest.BeforeCreate(Strategy, ctx, obj); err != nil {
return nil, false, err
}
} else {
if err := rest.BeforeUpdate(Strategy, ctx, obj, old); err != nil {
return nil, false, err
}
}
// update the spec tag
if imageStream.Spec.Tags == nil {
imageStream.Spec.Tags = map[string]api.TagReference{}
}
tagRef, exists := imageStream.Spec.Tags[tag]
// if the caller set tag, override the spec tag
if istag.Tag != nil {
tagRef = *istag.Tag
tagRef.Name = tag
}
tagRef.Annotations = istag.Annotations
imageStream.Spec.Tags[tag] = tagRef
// mutate the image stream
var newImageStream *api.ImageStream
if create {
newImageStream, err = r.imageStreamRegistry.CreateImageStream(ctx, imageStream)
} else {
newImageStream, err = r.imageStreamRegistry.UpdateImageStream(ctx, imageStream)
}
if err != nil {
return nil, false, err
}
image, err := r.imageFor(ctx, tag, newImageStream)
if err != nil {
if !kapierrors.IsNotFound(err) {
return nil, false, err
}
}
newISTag, err := newISTag(tag, newImageStream, image, true)
return newISTag, !exists, err
}