etcdserver/api/v2auth/auth.go
func (rw RWPermission) Revoke(lg *zap.Logger, n RWPermission) (RWPermission, error) {
	var out RWPermission
	currentRead := types.NewUnsafeSet(rw.Read...)
	for _, r := range n.Read {
		if !currentRead.Contains(r) {
			if lg != nil {
				lg.Info(
					"revoking ungranted read permission",
					zap.String("read-permission", r),
				)
			} else {
				plog.Noticef("revoking ungranted read permission %s", r)
			}
			continue
		}
		currentRead.Remove(r)
	}
	currentWrite := types.NewUnsafeSet(rw.Write...)
	for _, w := range n.Write {
		if !currentWrite.Contains(w) {
			if lg != nil {
				lg.Info(
					"revoking ungranted write permission",
					zap.String("write-permission", w),
				)
			} else {
				plog.Noticef("revoking ungranted write permission %s", w)
			}
			continue
		}
		currentWrite.Remove(w)
	}
	out.Read = currentRead.Values()
	out.Write = currentWrite.Values()
	sort.Strings(out.Read)
	sort.Strings(out.Write)
	return out, nil
}
func (rw RWPermission) Revoke(lg *zap.Logger, n RWPermission) (RWPermission, error) {
	var out RWPermission
	currentRead := types.NewUnsafeSet(rw.Read...)
	for _, r := range n.Read {
		if !currentRead.Contains(r) {
			if lg != nil {
				lg.Info(
					"revoking ungranted read permission",
					zap.String("read-permission", r),
				)
			} else {
				plog.Noticef("revoking ungranted read permission %s", r)
			}
			continue
		}
		currentRead.Remove(r)
	}
	currentWrite := types.NewUnsafeSet(rw.Write...)
	for _, w := range n.Write {
		if !currentWrite.Contains(w) {
			if lg != nil {
				lg.Info(
					"revoking ungranted write permission",
					zap.String("write-permission", w),
				)
			} else {
				plog.Noticef("revoking ungranted write permission %s", w)
			}
			continue
		}
		currentWrite.Remove(w)
	}
	out.Read = currentRead.Values()
	out.Write = currentWrite.Values()
	sort.Strings(out.Read)
	sort.Strings(out.Write)
	return out, nil
}
// Revoke removes a set of permissions to the permission object on which it is called,
// returning a new permission object.